Go vendor目录未生效主因是版本差异:Go 1.5默认不启用,1.6起默认开启GO15VENDOREXPERIMENT,1.11+需显式设GO111MODULE=off才启用;且必须位于$GOPATH/src下,构建时需见"vendor/"输出才确认生效。

Go vendor 目录为什么没生效?
Go 1.5 引入 vendor 目录,但默认不启用——这是离线环境失效的最常见原因。Go 1.6 起才默认开启 GO15VENDOREXPERIMENT=1,而你若用的是 Go 1.11+,vendor 实际上已被模块系统弱化,除非显式启用。
实操建议:
- 确认 Go 版本:
go version;若 ≥1.11,需额外设置GO111MODULE=off才会真正走vendor/ - 检查当前目录是否在
$GOPATH/src下(旧式 vendor 模式依赖此路径结构) - 运行
go build -v观察输出:如果看到"vendor/"被打印出来,说明正在读取;若直接打出"$GOROOT/src/..."或"$GOPATH/pkg/mod/...",那 vendor 就被绕过了
go mod vendor 和传统 vendor 目录的区别
Go 1.11+ 的 go mod vendor 是模块时代的“兼容性补丁”,不是回归旧模式,它把 go.mod 解析出的所有依赖(含 transitive 依赖)复制进 vendor/,但不会删掉 go.sum,也不会自动修改 import 路径。
关键差异点:
立即学习“go语言免费学习笔记(深入)”;
-
go mod vendor生成的vendor/只对当前模块有效,不能被其他模块当本地依赖引用 - 执行后仍需设
GO111MODULE=off,否则go build优先走go.mod+pkg/mod,完全无视vendor/ -
vendor/modules.txt是它的元数据文件,记录了每个包来源和版本,别手动改它
离线构建失败:找不到包或 checksum 不匹配
典型错误信息:cannot find module providing package xxx 或 checksum mismatch for xxx。根本原因不是网络断了,而是 vendor 内容不完整或状态不一致。
排查步骤:
- 运行
go list -m all(需先GO111MODULE=on)看完整依赖树,再比对vendor/是否覆盖全部 - 检查
vendor/modules.txt里有没有缺失的间接依赖(// indirect标记的那些) -
go mod vendor前先go mod download确保缓存齐全;若已离线,得提前在有网机器上跑完并打包整个vendor/目录 - 别用
cp -r手动拷贝 vendor——可能漏隐藏文件或破坏时间戳,导致go mod vendor后校验失败
交叉编译 + vendor 环境下 CGO_ENABLED=0 的坑
离线环境常搭配交叉编译(比如 Linux 上编译 Windows 二进制),此时若项目含 C 依赖(如 net 包调用系统 DNS),关掉 CGO 很容易触发 import "C" 报错或 DNS 解析异常。
真实影响:
-
CGO_ENABLED=0会让net包用纯 Go 实现,但某些 vendor 包(如旧版github.com/mattn/go-sqlite3)强制依赖 C,关掉就编译不过 - 若必须关 CGO,得确认所有 vendor 包都支持纯 Go 模式;查法:
grep -r "import.*C" vendor/ - 离线时没法动态下载 cgo 工具链,所以
CGO_ENABLED=1需提前在目标平台装好对应 GCC/Clang,否则 vendor 白搭
vendor 不是魔法盒,它只管 Go 源码层面的依赖快照。C 头文件、静态库、工具链这些,还得自己配齐,而且得跟目标平台严丝合缝。










