go mod tidy 不能自动删除私有模块残留,它只清理未被 import 的模块,而旧 tag、废弃分支或临时 replace 指向仍保留在 $gopath/pkg/mod 中;需手动用 go clean -modcache 或精准删除对应缓存目录。

go mod tidy 不能自动删掉私有模块残留
CI 流水线里 go mod tidy 只清理未被 import 的模块,但私有仓库的旧 tag、废弃分支或临时 replace 指向仍会留在 $GOPATH/pkg/mod 里。比如你曾用 replace example.com/internal => ./internal 本地调试,之后切回远程模块,tidy 不会清掉本地路径缓存,也不删掉之前拉下来的旧 commit hash 目录。
- 运行
go list -m all | grep "example\.com"看是否有多余版本(如v0.0.0-20230101120000-abc123) - 确认无误后手动删对应子目录:
rm -rf $(go env GOPATH)/pkg/mod/cache/download/example.com/internal/@v/v0.0.0-* - CI 脚本中加检查:失败时执行
go clean -modcache,但仅限失败后——避免每次构建都清,拖慢流水线
交叉编译产物让 $GOCACHE 瞬间膨胀 5GB+
流水线常跑多平台构建(GOOS=linux GOARCH=arm64 go build、GOOS=darwin GOARCH=amd64 go build),每个组合都会在 $GOCACHE 生成独立的 .a 文件。这些文件不共享,且 go clean -cache 默认只清当前环境变量下的缓存,其他 GOOS/GOARCH 的残留不动。
- 构建前统一设环境变量:
export GOCACHE=$(mktemp -d),让每次构建用全新缓存目录,结束后自动销毁 - 或改用
GOCACHE=off go build——适合单次构建场景,但注意go test也会变慢 - 别依赖
go clean -cache清多平台缓存;它只清当前GOOS/GOARCH下的,得手动find $(go env GOCACHE) -name "*linux*" -o -name "*darwin*" | xargs rm -rf
vendor 目录不是省空间的解法,反而更占磁盘
有些团队以为 go mod vendor 能把依赖“打包带走”,实际是把 $GOPATH/pkg/mod 全拷一份进项目,体积翻倍。尤其含大二进制依赖(如 cgo 绑定库)时,vendor 目录比 mod cache 还大。
- 流水线中禁用 vendor:
go build -mod=readonly,强制走模块缓存,避免重复存储 - 若必须 vendor(如离线环境),用
go mod vendor -o输出到临时目录,构建完立即rm -rf vendor -
go list -m -json all | jq -r '.Dir' | xargs du -sh 2>/dev/null | sort -hr | head -5快速定位哪些模块源码最占空间,针对性剔除
VS Code + gopls 在 CI 里偷偷吃掉 2GB
流水线若复用开发者机器镜像,或挂载了 $HOME,gopls 语言服务器可能在后台索引整个 pkg/mod,生成符号表缓存到 $HOME/.cache/gopls。这个目录不在 Go 官方缓存路径里,go clean 命令完全不管它。
- CI 镜像构建时加
RUN rm -rf $HOME/.cache/gopls - 流水线脚本开头加
export GOPATH=$(mktemp -d),隔离构建环境,避免污染宿主机缓存 - 禁用 gopls:在 CI 中设
GOFLAGS="-mod=readonly -buildmode=default",并确保没启动任何 IDE 相关进程
go mod graph 里,也不会被 tidy 扫到,得靠 du -sh 定向排查,再用对应工具精准清除。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











