go mod tidy仅删除两类模块:既未被任何.go文件import语句引用,也未被其他已保留模块间接依赖的模块;它无法识别反射调用、配置驱动、测试专用或带构建标签的依赖,需结合go mod why、go build、go test人工验证。

go mod tidy 会删掉哪些模块
它只删两类:既没出现在任何 .go 文件的 import 语句中,也没被其他已保留模块间接依赖的模块。比如你执行过 go get github.com/gorilla/mux,但后续删了所有 import "github.com/gorilla/mux",且没别的包依赖它 → 就会被删。
但以下情况它“看不见”,也不会删,反而可能误删本该留下的模块:
- 注释掉的
// import "net/http"不算有效引用 → 对应模块可能被误删 - 仅在
//go:build integration下才生效的import,若当前构建未启用该 tag →go mod tidy默认忽略,模块可能被删 -
import _ "github.com/lib/pq"这类空白导入,若无其他包依赖github.com/lib/pq,且它没注册任何init()副作用 → 也会被删
怎么验证某个模块是不是真能删
别光看 go.mod 里有没有那行 require,go mod why -m xxx 才是关键。它显示的是模块实际进入依赖图的路径,比扫文件更贴近真实构建行为。
常见判断方式:
立即学习“go语言免费学习笔记(深入)”;
-
go mod why golang.org/x/sync→ 查主模块是否直接或间接需要它 -
go mod why -m golang.org/x/sync -test→ 加上-test才能看到是否只被测试文件引用 - 返回
(main module does not need module)是安全可删信号 - 返回路径含
vendor/或internal/子目录,说明它被子模块显式require,不能单靠根目录tidy清理
清理后必须跑的三件事
删完不验证,等于白干。尤其要注意测试和交叉编译场景:
-
go build ./→ 确保所有子命令能编译,别漏了cmd/目录下的二进制 -
go test ./→ 测试文件可能引入独立依赖,go mod tidy默认处理它们,但得确认没 break -
go list -m all | wc -l对比前后数字,下降明显才说明真删了东西;再跑一次go mod graph | grep your-module-name确认
容易被忽略的运行时依赖
go mod tidy 是静态分析,完全看不到运行时行为。比如:
- 通过
reflect.Value.Call或字符串拼接调用的包(如插件系统) - 由 JSON/YAML 配置驱动加载的模块(如
driver := config.DriverName→import _ "github.com/xxx/driver") -
//go:embed引用的资源虽不触发 import,但某些驱动包依赖它做初始化
这类依赖必须人工核对:检查所有 init() 函数、配置项枚举、反射调用点,并确保对应空白导入仍存在且未被误删。


















