go mod download 下载的包存于 $GOMODCACHE,默认为 $GOPATH/pkg/mod 或 $HOME/go/pkg/mod,全局共享、按模块哈希分层存储源码与校验文件,不放入项目目录或 vendor/。

go mod download 下载的包到底存在哪?
它不存项目里,也不进 vendor/,更不会塞进 $GOROOT。真实位置只有一个:$GOMODCACHE,默认是 $GOPATH/pkg/mod(没设 GOPATH 就 fallback 到 $HOME/go/pkg/mod)。
运行 go env GOMODCACHE 能立刻确认当前路径。别信网上说的 “下载到 src” 或 “在 bin 里”,那是 GOPATH 旧模式的残留印象。
-
go mod download只写这个目录,其他地方都不碰 - 所有项目共享同一份缓存,不是每个项目一份副本
- 目录结构按模块路径哈希分层,比如
golang.org/x/net@v0.25.0对应子目录里含完整源码、go.mod和.info校验文件 - 手动删子目录会破坏校验状态,后续
go build可能报checksum mismatch
为什么 go mod download 有时不下载全部依赖?
它默认只下 go.mod 里显式 require 的直接依赖,那些标记为 // indirect 的间接依赖,除非被 go list -m all 列出,否则不会触发下载。
现象:执行完 go mod download 后 go build 仍联网拉包,就是这个原因。
- 想下全依赖树,必须用
go mod download all(注意all是关键字,不是通配符) -
go mod download all等价于go list -m all | xargs go mod download,覆盖所有出现在模块图里的版本 - 它跳过
replace到本地路径的模块(本就不需下载),也忽略vendor/内已存在的模块 - 若
go.sum里有记录但网络不可达,命令直接失败,不会跳过
清理缓存该用 rm -rf 还是 go clean?
用 go clean -modcache。手动 rm -rf $GOMODCACHE 看似干净,实则危险。
Go 工具链在缓存外还维护校验索引和下载元数据(比如 $GOCACHE/download 下的 zip 和 checksum 文件),直接删目录会导致内部状态不一致。
-
go clean -modcache会同步清空缓存 + 更新工具链内部索引,安全可靠 - 它不影响
$GOCACHE(编译中间产物)或$GOPATH/bin(安装的二进制) - 如果只想删某个模块,不要手撕子目录,而是先
go clean -modcache,再go mod download example.com/foo@v1.2.3 - CI 流水线中建议为每个 job 设置独立
GOMODCACHE(如/tmp/go-mod-cache-$CI_JOB_ID),避免并发写入锁争用
哪些磁盘占用容易被 du -sh $GOMODCACHE 漏掉?
du 只算文件大小,但 Go 开发中真正吃空间的“隐形消耗”常不在这个目录下。
比如 VS Code 的 gopls 语言服务器会在后台索引整个 pkg/mod,生成临时符号表,峰值多占 1–2GB;go test -v ./ 产生的测试二进制(如 __debug_bin)默认不自动清理;cgo 编译时 gcc 的预编译头(PCH)和 .o 文件也计入磁盘——这些都不会出现在 $GOMODCACHE 里,但一样会撑爆磁盘。
-
$GOCACHE(默认$HOME/Library/Caches/go-buildmacOS /$HOME/.cache/go-buildLinux)存编译中间产物,启用-race或频繁切 Go 版本时可达 5–10GB - Docker 构建中若挂载
$HOME/go到容器,宿主机 HDD 上多次 build 失败会残留大量未清理的 .o 文件 - Windows 下
%LocalAppData%\go-build默认路径,NTFS 小文件元数据开销比 ext4 更高

















