go list -m all不能直接查大小,但能筛出可疑模块:它输出所有模块路径和版本,是排查二进制膨胀的轻量起点,可配合grep -v 'indirect$'聚焦直接依赖,再对疑似大户用go list ... | wc -l粗估包数量,或结合go tool dist list -json、go mod vendor+du深入分析体积来源。

go list -m all 不能直接查大小,但能筛出可疑模块
Go 没有内置命令直接显示每个依赖包的磁盘占用或编译后体积,go list -m all 只输出模块路径和版本,不包含尺寸信息。但它是最轻量、最可靠的起点——你能快速确认哪些模块被拉进来了,尤其适合排查“为什么二进制突然变大”这类问题。
常见误操作是盯着 go mod graph 看边数,其实边多≠体积大;真正占空间的往往是带 cgo、嵌入资源(如字体/图标)、或大量子包被间接引入的模块(比如 golang.org/x/tools 或某些 SDK)。
- 执行
go list -m all | grep -v 'indirect$'先过滤掉纯传递依赖,聚焦直连模块 - 对疑似大户(如
github.com/aws/aws-sdk-go-v2、github.com/uber-go/zap)单独查其子模块:运行go list github.com/aws/aws-sdk-go-v2/... | wc -l看包数量(粗略 proxy) - 注意伪版本(
v0.0.0-2023...)模块——它们往往来自未打 tag 的 commit,可能含调试代码或冗余测试文件
用 go tool dist list -json 查构建产物体积分布
go tool dist list -json 不是标准文档常提的命令,但它在 Go 1.20+ 中真实存在,能导出当前构建中各包的符号表大小、文本段(.text)占比等底层数据,比单纯看 ls -lh ./pkg 更贴近实际影响。
它不依赖外部工具,也不需改代码,但输出是 JSON,得配合 jq 解析。关键不是总大小,而是识别“异常高占比”的包——比如某个 vendor/xxx 占了 .text 的 40%,就值得深挖。
- 先构建一次:
go build -o app . - 再跑:
go tool dist list -json | jq '.[] | select(.text > 500000) | {name: .name, text: .text}'(阈值按需调) - 结果里
.name是包路径,.text是字节数;数值 >500KB 的通常值得 inspect - 注意:该命令只反映当前
GOOS/GOARCH下的构建,交叉编译时需指定GOOS=linux GOARCH=arm64 go tool dist list -json
go mod vendor 后用 du -sh 排查物理体积
go mod vendor 把所有依赖复制到本地 vendor/ 目录,这时 du -sh vendor/** | sort -hr | head -10 就能直观看到哪些模块占磁盘最多。这不是最终二进制大小,但能暴露“下载即庞大”的模块(比如含大量 proto 文件、doc 或 testdata 的 SDK)。
容易踩的坑是忽略 vendor/ 里的隐藏目录(如 .git、.github),它们会被 du 统计进去,造成误判。
- 执行前确保
go mod vendor成功,且没报no modules to vendor - 用
du -sh vendor/* | grep -v '\.git\|\.github\|testdata$' | sort -hr | head -10过滤干扰项 - 若发现某模块体积远超同类(如
golang.org/x/net占 20MB),大概率是它带了未清理的examples/或testdata/ - 这个方法对私有模块同样有效——只要它们进了
vendor/,就能被du扫到
别信 go mod graph 的“深度”,真正影响体积的是 import 链长度和包内聚度
go mod graph 显示谁依赖谁,但无法告诉你一个包被 import 了多少次、是否触发了 cgo 编译、或者是否因条件编译(// +build windows)引入了平台专属大文件。体积膨胀常发生在“浅依赖但高内聚”的模块上——比如一个只被 import 一次的 github.com/minio/minio,却因自带完整 S3 客户端逻辑,拉入几十个子包。
这时候 go mod why 比 graph 更有用:它给出最短引用链,帮你判断“是不是非得用这个模块”。如果 go mod why github.com/minio/minio 返回路径里有 yourapp/cmd,说明是主逻辑强依赖;如果只出现在 github.com/some/log/pkg 的间接依赖里,就该考虑换日志库。
- 优先查
go mod why -m <module></module>,而不是先画图 - 对返回路径里含
cmd/或main.go的模块,基本就是体积主力 - 若路径里只有
test或example目录,说明它可能只是测试依赖——检查go.mod是否漏加// +build ignore或该模块是否该用-tags构建排除
真正难处理的不是大模块本身,而是它如何被你的代码触发——同一模块,import "xxx" 和 import _ "xxx" 对体积的影响可能差 10 倍。动手前先确认 import 方式,比盲目删依赖更有效。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











