go mod tidy 仅删除未被任何 Go 源文件 import 的模块及其子包,不删 replace/exclude 声明项、条件编译导入项及间接依赖项。

go mod tidy 会删掉哪些依赖
go mod tidy 不是“清理冗余包”的通用工具,它只删除两类内容:未被任何 Go 源文件 import 的模块,以及 该模块下没有任何被 import 的包。比如你 go get github.com/sirupsen/logrus,但整个项目没写 import "github.com/sirupsen/logrus",它就会被删;但如果写了 import,哪怕只在 test.go 或 build tag 条件下才生效(如 //go:build integration),go mod tidy 默认也会保留。
- 它不关心包是否“实际运行时用到”,只看静态 import 图
- 它不会删除
replace或exclude指令里显式声明的模块,哪怕它们没被引用 - 如果某模块被间接依赖(A → B → C),而你的代码只 import A 和 C,
go mod tidy仍会保留 B —— 因为 C 的go.mod声明了对 B 的依赖,Go 认为这是构建一致性所需
什么时候必须加 -compat=1.17 或更高版本
当你项目中用了泛型、切片操作符 ~、或 any 类型别名等 Go 1.18+ 特性,但 go.mod 文件里 go 指令仍是 go 1.16,go mod tidy 可能误判依赖兼容性,甚至拒绝拉取需要新版本 go.mod 语义的模块(例如某些使用 //go:build 的测试依赖)。
- 运行
go mod tidy -compat=1.18会强制按 Go 1.18 规则解析依赖图,避免因版本标记不匹配导致的no required module provides package错误 - 这个参数只影响 tidy 过程中的模块选择逻辑,不修改源码或生成新文件
- 推荐做法:先用
go version确认当前 SDK 版本,再把go.mod第一行升级为对应版本,最后再跑go mod tidy
go mod tidy 后 vendor 目录没更新怎么办
go mod tidy 本身不碰 vendor/ 目录。要同步 vendor,必须额外执行 go mod vendor。而且注意:如果之前手动改过 vendor/modules.txt 或删过某些子目录,go mod vendor 默认不会恢复缺失内容 —— 它只按当前 go.mod + go.sum 忠实复制。
- 确保
GO111MODULE=on,否则go mod vendor可能静默失败 - 若需强制刷新(包括删除已不存在的模块),加
-v和-o参数:go mod vendor -v -o ./vendor - CI 中建议组合使用:
go mod tidy && go mod vendor
为什么 go mod tidy 有时卡住或报 proxy 错误
常见原因是 GOPROXY 设置不当,或模块托管平台(如 GitHub)返回了非标准 HTTP 状态码(如 429),触发了 Go 的重试退避机制。尤其在企业内网或代理不稳定时,go mod tidy 可能长时间等待某个超时请求,而不是快速失败。
立即学习“go语言免费学习笔记(深入)”;
- 临时跳过代理:运行
GOPROXY=direct go mod tidy(仅调试用,不推荐长期设置) - 设超时:通过环境变量
GO111MODULE=on GOSUMDB=off GOPROXY=https://proxy.golang.org,direct go mod tidy - 检查
go env GOPROXY输出,确认不是空值或拼错地址(比如写成https://goproxy.io而不是https://goproxy.io) - 若用私有模块,确保
GOPRIVATE包含对应域名,否则 Go 仍会尝试走公共 proxy 导致 403
真正难处理的是跨模块循环依赖或 replace 指向本地路径但路径不存在的情况 —— 这类问题不会报明确错误,而是反复拉取失败后静默退出,得靠 go list -m all 对比前后差异才能发现。










