go mod tidy 不能真正“清理”依赖,因为它只同步 go.mod 与代码 import 引用关系,不删除已下载但未被引用的模块缓存;安全清空本地模块缓存需用 go clean -modcache,它清空 $gopath/pkg/mod 中所有模块,不影响 go.mod 和 go.sum,后续构建会按需重下。

为什么 go mod tidy 不能真正“清理”依赖?
go mod tidy 只保证当前代码引用的模块被声明在 go.mod 中,但它**不会删除已下载但未被直接或间接引用的模块**。这些模块仍留在 $GOPATH/pkg/mod(或 GOPATH 外的模块缓存目录)里,长期积累会显著占用磁盘空间,尤其在 CI/CD 或多项目开发中容易被误认为“已清理”。
如何安全清空本地模块缓存?
Go 的模块缓存是全局共享的,不是按项目隔离的。直接删整个缓存会影响其他项目,所以得区分“项目级瘦身”和“全局清理”:
- 若只想释放当前项目无关的缓存:运行
go clean -modcache—— 它会清空整个pkg/mod目录,但之后首次go build或go test会重新下载所有依赖,无风险 - 若只想清理“未被任何项目引用”的模块(更精准):用
go mod graph+ 脚本分析,但 Go 官方不提供内置命令,实际操作成本高,多数人直接选go clean -modcache - 注意:该命令不碰
go.sum或go.mod,只动缓存;执行前确保网络通畅,否则后续构建会卡在下载环节
go mod vendor 后还能删缓存吗?
能,而且推荐删。启用 vendor 后,构建默认不再读取 pkg/mod,所以 go clean -modcache 对项目无影响。但要注意:
- 必须确认
vendor目录完整:运行go mod vendor后检查是否包含所有依赖子目录,特别是含cgo或特定平台构建的模块 - CI 环境中若禁用了
vendor模式(如设GO111MODULE=on且没加-mod=vendor),删缓存会导致构建失败 -
go list -m all仍会从缓存读取模块信息,删完后首次运行会慢一点,属正常现象
项目级“瘦身”的真正关键点
模块缓存只是表象,真正的臃肿往往来自 go.mod 里残留的间接依赖。比如某个旧版工具链引入了大量 transitive 依赖,升级主依赖后它们还在 go.mod 里躺着:
- 用
go mod graph | grep -v 'your-module-name'查看哪些模块没被当前项目直接引用 - 逐个检查
go.mod中非主模块的require行,确认是否仍被go list -deps -f '{{.Path}}' ./...输出覆盖 - 手动删掉确认无用的
require行后,再跑一次go mod tidy—— 这步才会真正缩小go.mod体积
缓存可一键清,但 go.mod 里的冗余 require 得靠人工判断,漏掉一个就可能让下次 go get 带回整棵依赖树。











