go mod vendor离线构建失败的根本原因不是vendor目录为空,而是本地$gocache中缺失模块zip和info文件、go.mod与vendor/modules.txt不一致、或vendor目录结构被篡改;它只复制不下载,且忽略测试依赖、embed文件及replace路径。

go mod vendor 不是“有 vendor 目录就能离线构建”,它只复制、不下载,失败根源几乎总是本地缺失模块缓存。
go mod vendor 为什么在离线时总报 no required module 提示
根本不是 vendor 目录空,而是 go.mod 里声明的模块,在 $GOCACHE/pkg/mod/cache/download/ 下压根没 zip 和 info 文件。比如你从别人机器拷来项目,go mod download 没跑过,go mod vendor 就会静默跳过所有依赖——它不报错,但 vendor/ 是残缺的。
- 执行
go list -m all,逐行检查输出的每个模块路径,手动去$GOCACHE/pkg/mod/cache/download/找对应目录,确认存在.zip和.info - CI 构建机生成 vendor 后,别只 rsync 项目目录;要么打包整个
$GOCACHE,要么用go mod download -json输出校验清单,和本地比对 - 如果用了
replace,vendor/ 里不会出现被 replace 的原始路径(如replace github.com/a => ./a,则vendor/github.com/a/是空的),实际代码来自本地./a—— 这个路径必须存在且可读
go build -mod=vendor 失败的三个硬性条件
go build -mod=vendor 会严格比对三样东西:当前 module 的 go.mod、vendor/modules.txt、以及 vendor/ 目录结构。任意一项不一致,就 fallback 到 module mode 并报错,比如:
在 Go 中使用 google/wire 实现编译时依赖注入——wire.NewSet、wire.Build、wire.Bind(接口→实现)、wire.Struct、wire.Value、wire.Interface
-
vendor/modules.txt缺失或内容被手动修改 —— 它是 vendor 的快照,删了就废了 -
go.mod被改过(哪怕只是加了个注释),但没重新 rungo mod vendor,导致modules.txt和go.mod不同步 - vendor/ 下多了不该有的文件(比如 IDE 自动生成的 .DS_Store),
go build会拒绝加载
测试依赖、embed 文件、replace 路径怎么进 vendor
go mod vendor 默认只处理构建依赖,以下三类东西它不管:
- 测试代码里 import 的包(如
_test.go中用到的github.com/stretchr/testify)—— 先跑go test -mod=mod -c ./...触发解析,再 vendor -
//go:embed引用的非 Go 文件(如模板、配置、图片)—— vendor 不复制这些,得靠构建脚本额外处理 -
replace后的目标路径(如replace example.com/a => ../a)—— vendor/ 里example.com/a/是空目录,实际代码来自../a,这个路径必须在 vendor 外可用
离线环境验证 vendor 是否真正可用
别信目录存在,要真跑一次:
- 清掉
$GOPATH/pkg和$GOCACHE(模拟纯离线环境),再go build -mod=vendor - 加
-v参数看详细日志:go mod vendor -v会标出哪些包被跳过(含(not in vendor)) - 用
go list -m -f '{{.Dir}}' all查所有模块实际路径,确认它们都落在 vendor/ 内部,而不是指向$GOCACHE
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










