go mod tidy仅删除两类模块:未被任何.go文件import语句引用、且未被其他已保留模块间接依赖的模块;它无法识别反射调用、配置驱动或测试专用模块,需人工交叉验证。

go mod tidy 能删掉大部分冗余依赖,但不会识别反射调用、配置驱动或测试专用模块——这些得靠人工交叉验证。
哪些模块会被 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 why -m xxx 比看 go.mod 更可靠
go mod why 显示的是模块实际进入依赖图的路径,比扫 go.mod 里有没有 require 行更贴近真实构建行为。常见用法:
-
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 mod tidy -v 输出里藏着关键线索
加 -v 后,控制台会逐行打印增删动作,重点关注带 unused 和 indirect 的行:
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
立即学习“go语言免费学习笔记(深入)”;
-
removing unused github.com/spf13/cobra v1.8.0→ 这个模块确实没被任何路径引用到 -
adding github.com/mattn/go-sqlite3 v1.14.15 // indirect→ 它是传递依赖,不是你直接 import 的 - 如果某模块反复出现“adding”又“removing”,可能是构建标签不一致或
replace冲突,需检查GOOS/GOARCH和//go:build注释 - 输出末尾没报错,不代表安全 —— 它不校验运行时行为,比如通过
reflect.Value.Call或 JSON 配置加载的模块,tidy完全看不见
清理后必须跑的三件事
删完不验证,等于白干。尤其要注意测试和交叉编译场景:
-
go build ./...→ 确保所有子命令能编译,别漏了cmd/目录下的二进制 -
go test ./...→ 测试文件可能引入独立依赖,go mod tidy默认处理它们,但得确认没 break -
go list -m all | wc -l对比前后数字,下降明显才说明真删了东西;再跑一次go mod graph | grep your-module-name确认它彻底不在图里
最常被忽略的是:某些数据库驱动、日志钩子、HTTP 中间件靠 init() 注册,代码里没调用函数,但删了 import 就直接失效。这类模块不能只看 tidy 输出,得翻源码确认注册逻辑是否还在生效路径上。

















