go list -m -direct 才是查看直接依赖的正确命令,它只列出 go.mod 中 require 显式声明的模块,排除 indirect 标记和隐式引入的 transitive 依赖。

go list -m all 列出的是所有模块依赖,不是直接依赖
很多人执行 go list -m all 后以为看到的就是自己 go.mod 里显式声明的那些包,其实不是。它列出的是整个构建图中**所有被间接引入的模块版本**,包括 transitive 依赖——哪怕你代码里一行都没 import 过它。
真正想看“直接依赖”,得换命令,否则会误判依赖范围、搞错升级影响面。
查直接依赖要用 go list -m -direct
go list -m -direct 才是 Golang 官方提供的、专门筛选直接依赖的命令。它只输出 go.mod 中由 require 显式声明的模块(不含 indirect 标记的,也不含隐式拉进来的)。
- 如果模块在
go.mod里带// indirect注释,-direct不会显示它 - 如果模块被多个路径引入,但只在
require行里写了一次,它仍算直接依赖,会被列出 - 不加
-f时默认输出格式是module/path v1.2.3,适合人眼阅读;加-f '{{.Path}}'可纯提取路径,方便脚本处理
为什么 go list -m all 经常被误用
常见错误现象:go list -m all 输出里包含 golang.org/x/net、github.com/golang/protobuf 这类明显没在自己 go.mod 里 require 的包,于是以为项目“用了它们”,结果删掉后编译失败——其实是某个直接依赖(比如 grpc-go)悄悄带进来的。
- 它反映的是“当前构建实际加载的模块集合”,受
replace、exclude、go version和本地缓存共同影响 - 不同 Go 版本下输出可能不同:Go 1.17+ 默认启用 lazy module loading,
all结果更“精简”;旧版可能多出一堆未实际使用的模块 - CI 环境里若没清理
$GOCACHE或pkg/mod,all可能包含历史残留模块,造成误判
想导出干净的直接依赖列表,推荐组合命令
单纯 go list -m -direct 有时还不够——比如你想排除测试专用依赖(test 目录下的 require),或过滤掉 golang.org/x 这类标准扩展库。
立即学习“go语言免费学习笔记(深入)”;
- 只取模块路径(不含版本):
go list -m -direct -f '{{.Path}}' - 排除标准库相关模块:
go list -m -direct -f '{{if not (eq .Path "golang.org/x/net")}}{{.Path}}{{end}}'(注意:模板逻辑简单,复杂过滤建议用awk或grep -v后处理) - 检查是否遗漏了
indirect但实际被 import 的模块:用go mod graph | grep 'your-module' | cut -d' ' -f2辅助验证调用链
直接依赖的真实边界,藏在 go.mod 的 require 行和实际 import 语句的交集里,命令只是帮你看清其中一环。别跳过 grep import 这步,尤其当你准备做依赖瘦身或合规审计时。










