Go Modules 默认不隔离,依赖统一缓存在 $GOPATH/pkg/mod;物理上共享,逻辑上靠 go.mod 版本锁定、go.sum 校验和 MVS 算法保证一致性;需隔离时应使用 replace、GOPRIVATE 或 go mod vendor,而非 GOPATH 或 gvm。

go mod 默认不隔离,依赖全缓存在 $GOPATH/pkg/mod
Go Modules 本身不为每个项目创建独立的依赖副本,所有 go get 下载的模块都统一存到全局缓存目录 $GOPATH/pkg/mod(实际路径由 GOPATH 和 GOMODCACHE 决定)。这意味着:不同项目引用同一依赖的相同版本时,共享缓存;但若版本冲突,MVS 算法会按需解析,不会互相污染——**物理上不隔离,逻辑上靠版本锁定和 MVS 保证一致性**。
真正需要隔离的场景:私有模块、调试替换、离线构建
多数情况下无需手动隔离,但以下情况必须干预:
- 想临时用本地修改版替代远程依赖 → 用
replace指令,写在go.mod里:replace github.com/old/pkg => ./local-fix
- 企业内网项目依赖私有 Git 仓库,又不想走代理 → 设置
GOPRIVATE=git.example.com/*,跳过GOPROXY和GOSUMDB校验 - 需要打包可离线部署的二进制 → 运行
go mod vendor,把当前项目所有依赖复制到vendor/目录,后续构建加-mod=vendor参数
别误用 gvm pkgset 或 GOPATH 来“隔离模块”
gvm 的 pkgset 是为隔离 GOPATH 下的旧式包管理设计的,与 Go Modules 不兼容。启用 GO111MODULE=on 后,GOPATH 和 pkgset 对模块依赖下载完全无效。强行混用会导致:
-
go mod download仍写入全局pkg/mod,pkgset目录空空如也 -
go build找不到依赖,报错cannot find module providing package - CI 流水线因环境不一致而失败
可靠隔离只靠三件事:go.mod + go.sum + GOPROXY 配置
项目级依赖可重现性的唯一正解是这三者协同:
-
go.mod锁定模块路径和语义化版本(含// indirect标注) -
go.sum记录每个模块的校验和,go mod verify可随时校验 -
GOPROXY设为国内镜像(如https://goproxy.cn)加速下载,避免因网络抖动导致go mod tidy失败重试拉取不同 commit
提交 go.mod 和 go.sum 到 Git,比任何环境变量或工具链隔离都管用。真正容易被忽略的是:很多人删掉 go.sum 或忽略其变更,结果在另一台机器上 go build 时 silently 拉了被篡改的依赖。

















