go mod download 默认将包下载到 $gomodcache(即 $gopath/pkg/mod 或 $home/go/pkg/mod),全局共享、非项目目录非 vendor;只下直接依赖,需加 all 才下载全部模块,含 indirect;路径以 go env gomodcache 输出为准。

go mod download 到底把包下到哪儿了
它默认写入 $GOMODCACHE,也就是 $GOPATH/pkg/mod 或 $HOME/go/pkg/mod(Go 1.16+ 未设 GOPATH 时)。这不是项目目录里的 vendor/,也不是临时构建目录,而是全局共享的缓存位置。
验证方式很简单:go env GOMODCACHE 输出的就是真实路径。别信“应该在哪儿”,只信这个命令的输出结果。
- 如果改过
GOPATH,GOMODCACHE会跟着变;没改就 fallback 到$HOME/go/pkg/mod - 多个项目共用同一份缓存——下载一次,所有项目都能复用
- 手动删
pkg/mod下的子目录极危险:校验和可能失效,导致后续go build报checksum mismatch - 真要清空,只用
go clean -modcache,它会安全擦除并重置校验状态
为什么 go mod download 不等于“全量下载”
不加参数跑 go mod download,只拉 go.mod 里 require 块中显式声明的模块,跳过所有 // indirect 依赖。这意味着:你代码里 import 了某个包,但它没被直接 require 过,go mod download 就不会碰它。
结果就是:本地缓存看似完整,go build 时却突然联网拉一个 indirect 包——尤其在 CI 或离线环境里特别致命。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 想真正覆盖全部依赖(含 indirect),必须用
go mod download all -
all是关键字,不是通配符;它等价于go list -m all | xargs go mod download - 注意:
all会忽略replace指向远程 URL 的模块(比如replace example.com/a => https://github.com/x/a v1.2.0),这类模块得等go build时才真正 fetch - 执行前先
go mod tidy,确保go.mod和go.sum一致,否则all可能漏掉或误拉
怎么改模块下载位置(GOMODCACHE)
改 GOMODCACHE 环境变量就行,但路径必须干净:不能含中文、空格、符号链接,且目标目录要有读写权限。Windows 上尤其注意反斜杠和盘符格式。
临时改法(当前终端有效):
Linux/macOS:export GOMODCACHE=/data/go/mod
Windows PowerShell:$env:GOMODCACHE = "D:\gomod"
- 永久生效就写进 shell 配置(如
~/.zshrc),然后source一下 - 改完立刻验证:
go env GOMODCACHE必须返回新路径 - 改完不影响已有缓存——旧路径下的内容不会自动迁移,得手动复制或重新下载
- CI/CD 中常设为 SSD 路径或内存盘(如
/dev/shm/gomod),加速重复构建
离线构建前最容易被忽略的三件事
光靠 go mod download all 并不能保证离线成功。Go 构建阶段仍可能触发网络请求,尤其当代码里有 //go:embed、cgo、或不同 build tag 分支引用了未被 go list -m all 覆盖的模块时。
- 离线机必须设
GOPROXY=off和GOSUMDB=off,否则即使文件全在本地,校验阶段也会连sum.golang.org - 运行
go build -v -a .观察输出,只要看到任何Fetching日志,说明还有漏网之鱼 - 检查
go.mod里有没有exclude或replace到非本地路径的条目——它们不会被go mod download处理,但go build会尝试去拉
缓存路径本身不复杂,麻烦的是它和构建流程、校验机制、代理配置深度耦合。哪怕只漏掉一个间接依赖或一个校验开关,离线构建就会卡在第一行日志上。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










