go mod tidy 删除未被 import 的包,仅依据实际 import 语句判定依赖必要性,不保留注释、测试提及或备用包;它扫描所有 .go 文件构建使用清单,对比 go.mod 增删依赖,并保留空白导入、反射调用、replace/exclude 干预等情况。
go mod tidy 删除包,是因为它严格按“代码是否实际 import”来判断依赖必要性。 它不看注释、不猜意图、不保留备用项——只认真实出现在 .go 文件里的 import 语句。只要没被导入,哪怕包还在文档里写着、测试里提过、或者你“以后可能会用”,它都会删。
tidy 扫描项目中所有 .go 文件(包括测试文件 *_test.go),逐行解析 import 声明,构建一张“当前正在用的模块清单”。然后对比
go.mod 中的 require 列表:
go.mod 里没有 → 自动添加(含版本推导)go.mod 里却有 → 标记为“未使用”,准备删除import 直接或间接触发到,且没被其他显式 require 锁定,tidy 也可能移除 C(尤其在 -compat 版本较新时)go mod tidy 只改 go.mod 和 go.sum,不碰磁盘上的模块缓存。你看到的 $GOPATH/pkg/mod 里残留的包,是 Go 的全局模块缓存,供所有项目复用。删了 go.mod 不等于清缓存。
go clean -modcache(注意:这会清空所有项目共享的缓存,下次构建可能要重下)$GOPATH/pkg/mod,找对应路径如 github.com/some/pkg@v1.2.3 文件夹删掉不是所有没 import 的包都会被删。以下情况 tidy 通常保留:
_ "github.com/xxx"):即使没调用,也算“被引用”//go:linkname 或反射等非常规方式使用:tidy 看不到,但运行时需要replace 或 exclude 显式干预过:tidy 尊重这些声明,不会擅自绕过删包不是终点,编译和测试才是确认安全的关键:
go build ./... 看是否全部通过go test ./...,尤其关注集成测试和 e2e 测试git diff go.mod 快速定位删了什么基本上就这些。tidy 的逻辑很朴素:代码没 import,就不该在依赖列表里。它不复杂,但容易忽略隐式引用和缓存残留。