go mod tidy只删除两类模块:既未被任何.go文件import语句引用、也未被其他已保留模块间接依赖的模块;它基于静态导入图分析,不识别反射调用、配置驱动、测试专用或条件编译等隐式依赖,需人工交叉验证。

go mod tidy 会删掉哪些模块
它只删掉两类东西:代码里没 import 的、且没被任何现存依赖间接拉进来的模块。不是“看着没用就删”,而是严格按 import 图做静态推导。所以你手动删 go.mod 里某一行,大概率下次 go mod tidy 又给加回来——因为某个你还留着的第三方库内部 import 了它。
常见误删场景包括:
-
//go:embed引用的模块(如embed.FS读取的包)不算 import,go mod tidy会删 - 仅在
//go:build integration下才 import 的模块,若当前构建 tag 未启用,tidy 不识别 - 测试文件(
*_test.go)里的 import 默认不参与 tidy 分析,除非你显式加-modfile go.sum或确保GOOS环境一致 -
import _ "xxx"(空导入)会被保留,因它算显式声明
清理前必须检查的三个地方
别急着敲 go mod tidy,先确认这三件事是否已处理:
- 所有刚删掉
import的 .go 文件已保存,否则 tidy 仍看到旧引用 - 项目里没有子目录含独立
go.mod(多 module 结构),有则需逐个进入执行 tidy - CI 或本地构建是否依赖某些构建 tag(如
//go:build !windows),tidy 默认启用全部 tag,但实际 build 时可能禁用,导致运行时缺依赖
验证删除是否真安全
删完不能只看 go.mod 行数变少,得验证是否破坏实际能力:
- 跑
go build ./...和go test ./...,确保全量通过 - 如果项目用
go:generate,记得先go generate ./...再 build,否则生成代码可能隐式依赖已删模块 - 对疑似冗余的
// indirect模块,可临时注释go.mod中对应行,再 build/test;失败说明仍有隐式链路(比如 plugin 加载、反射调用或代码生成器依赖) - 别碰
golang.org/x/sys这类高频间接依赖——即使你没直接 import,标准库多个包都靠它,删了大概率编译报错
vendor 目录和 tidy 的关系
如果你用了 go mod vendor,注意:go mod tidy 不会动 vendor/ 里的文件,但它会影响 go.mod。一旦 vendor/ 已存在,tidy 删除模块后,vendor/ 就变成“本地有但 mod 没声明”的状态,后续 go build -mod=vendor 仍能过,但 go list -m all 会漏掉那些模块,CI 环境若混用 -mod=readonly 就可能失败。
安全做法是:先 tidy 清理 go.mod,再重新 go mod vendor,最后提交更新后的 vendor/ 和 go.mod。











