Golang 项目的依赖管理策略——go.mod 管理、安装/升级包、最小版本选择、漏洞扫描、过时依赖跟踪、二进制体积分析、Dependabot/Renovate 配置、冲突解决以及 go.work 工作区。在添加、删除或升级 Go 依赖、审计漏洞、解决版本冲突或设置自动依赖更新时使用。
角色: 你是一名 Go 依赖管理者。你将每一个新依赖视为长期的维护承诺——在引入外部包之前,你会先问标准库是否已经解决了问题。
依赖:
- govulncheck:
go install golang.org/x/vuln/cmd/govulncheck@latest
Go 依赖管理
AI 代理规则:添加依赖前先询问
在运行 go get 添加任何新依赖之前,AI 代理必须向用户确认。 AI 代理可能会建议一些无人维护、质量低下或不必要的包,而标准库已经提供了等效功能。使用 go get -u 升级现有依赖是安全的。
在提议依赖之前,评估:
- 标准库是否已经覆盖了该用例?
- 许可证是否兼容?
- 是否有知名的替代方案?
- 它的功能以及为什么需要它?
samber/cc-skills-golang@golang-popular-libraries 技能包含一份精选的、经过验证的生产就绪库列表。优先推荐该列表中的包。当没有经过验证的选项时,优先选择 Go 团队(golang.org/x/...)或知名组织的包,而不是晦涩的替代品。
关键规则
go.sum必须提交——它记录了每个依赖版本的加密校验和,让go mod verify能够检测供应链篡改。没有它,被攻破的代理可能会静默替换恶意代码。- 每次发布前运行
govulncheck ./...或go tool govulncheck ./...——在已知 CVE 进入生产环境之前捕获它们。 - 在添加依赖之前,维护状态、许可证兼容性和标准库替代方案是重要的考虑因素——每个依赖都会增加攻击面、维护负担和二进制体积。
- 每次更改依赖的提交前运行
go mod tidy——移除未使用的模块并添加缺失的模块,保持 go.mod 诚实。
go.mod 和 go.sum
基本命令
| 命令 | 目的 |
|---|---|
go mod tidy |
添加缺失的依赖,移除未使用的依赖 |
go mod download |
将模块下载到本地缓存 |
go mod verify |
验证缓存的模块是否匹配 go.sum 校验和 |
go mod vendor |
将依赖复制到 vendor/ 目录 |
go mod edit |
以编程方式编辑 go.mod(脚本、CI) |
go mod graph |
打印模块需求图 |
go mod why |
解释为什么需要某个模块或包 |
依赖 vendoring
当你需要封闭构建(无网络访问)、超越校验和的可复现性保证,或者部署到没有模块代理访问的环境时,使用 go mod vendor。CI 流水线和 Docker 构建有时会受益于 vendoring。在每次依赖更改后运行 go mod vendor 并提交 vendor/ 目录。
安装和升级依赖
添加依赖
go get github.com/google/uuid # 最新版本
go get github.com/google/uuid@v1.6.0 # 特定版本
go get github.com/google/uuid@latest # 明确指定最新版本
go get github.com/google/uuid@<commit> # 特定提交(伪版本)
在固定版本之前,在 pkg.go.dev 上检查模块的可用版本、导入者和已知漏洞 → 参见 samber/cc-skills-golang@golang-pkg-go-dev 技能。
升级
go get -u ./... # 将所有直接和间接依赖升级到最新的次要或补丁版本
go get -u=patch ./... # 仅升级到最新的补丁版本(更安全)
go get github.com/pkg@v1.5 # 升级特定包
对于常规更新,优先使用 go get -u=patch。补丁和次要版本升级通常比主要版本风险低,但仍需审查。对于依赖更新,运行:
go get -u=patch ./...
go mod tidy
go test ./...
go vet ./...
govulncheck ./... # 或:go tool govulncheck ./...
影响持久化、序列化、网络、认证、授权、加密或公共 API 的库的发布说明和变更日志可能包含关于破坏性变更的重要信息。
移除依赖
go get github.com/google/uuid@none # 标记为移除
go mod tidy # 清理 go.mod 和 go.sum
安装 CLI 工具
对于 Go 1.24+ 模块,使用 tool 指令在 go.mod 中固定可执行工具。除非模块必须支持 Go <1.24,否则不要创建新的 tools.go 空白导入文件。
# 将工具添加到当前模块。
go get -tool github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
go get -tool golang.org/x/vuln/cmd/govulncheck@latest
go get -tool golang.org/x/perf/cmd/benchstat@latest
# 可复现地运行固定的工具。
go tool golangci-lint run ./...
go tool govulncheck ./...
go tool benchstat old.txt new.txt
# 在需要时将模块固定的所有工具安装到 GOBIN/PATH。
go install tool
# 有意识地更新固定的工具,然后审查 go.mod/go.sum。
go get -u tool
go mod tidy
针对 Go 1.26 或更新版本的模块的 go.mod 示例。这是一个示例目标,不是上限;保持项目的实际 go 指令,不要仅仅为了添加工具而更改它。
module example.com/project
go 1.26
tool (
github.com/golangci/golangci-lint/v2/cmd/golangci-lint
golang.org/x/vuln/cmd/govulncheck
golang.org/x/perf/cmd/benchstat
)
仅对于 Go <1.24,使用传统的 tools.go 空白导入变通方法:
//go:build tools
package tools
import (
_ "github.com/golangci/golangci-lint/v2/cmd/golangci-lint"
_ "golang.org/x/vuln/cmd/govulncheck"
)
规则:Go 1.24+ 使用 tool 指令。Go <1.24 使用 tools.go 回退。
Go 1.26+ 模块目标说明
当使用 Go 1.26 或更新版本的工具链时,go mod init 可能会创建一个带有较旧默认 go 指令的模块。如果项目有意针对 Go 1.26+ API,请有意识地更新指令:
go mod edit -go=1.26
go mod tidy
对于未来的 Go 版本,使用项目预期的目标版本。在项目明确同意升级之前,不要使用比模块的 go 指令更新的 API。
深入探讨
-
版本控制与 MVS — 语义化版本规则(主版本.次版本.补丁),何时递增每个数字,预发布版本,最小版本选择(MVS)算法(为什么不能直接选择“最新”),以及主版本后缀约定(v0、v1、v2 后缀用于破坏性变更)。
-
审计依赖 — 使用
govulncheck进行漏洞扫描,跟踪过时的依赖,分析哪些依赖导致二进制体积过大(goweight),以及区分仅测试依赖和二进制依赖以保持go.mod整洁。 -
依赖冲突与解决 — 诊断版本冲突(当你请求不兼容版本时
go get的行为),解决策略(用于本地开发的replace指令,用于损坏版本的exclude,用于已发布但应跳过的版本的retract),以及跨依赖树的冲突处理工作流。 -
Go 工作区 — 用于多模块开发的
go.work文件(例如,库 + 示例应用程序),何时使用工作区 vs 单体仓库,以及工作区最佳实践。 -
自动依赖更新 — 设置 Dependabot 或 Renovate 以自动创建依赖更新 PR,自动合并策略(何时自动合并 vs 需要审查),以及处理安全更新。
-
可视化依赖图 — 使用
go mod graph检查完整的依赖树,使用modgraphviz可视化它,以及使用交互式工具找出导致臃肿的依赖链。
交叉引用
- → 参见
samber/cc-skills-golang@golang-continuous-integration技能以了解 Dependabot/Renovate CI 设置 - → 参见
samber/cc-skills-golang@golang-security技能以了解使用 govulncheck 进行漏洞扫描 - → 参见
samber/cc-skills-golang@golang-popular-libraries技能以获取经过验证的库推荐
快速参考
# 启动一个新模块
go mod init github.com/user/project
# 添加依赖
go get github.com/google/uuid@v1.6.0
# 升级所有依赖(仅补丁,更安全)
go get -u=patch ./...
# 移除未使用的依赖
go mod tidy
# 检查漏洞
govulncheck ./... # 或:go tool govulncheck ./...
# 检查过时的依赖
go list -u -m -json all | go-mod-outdated -update -direct
# 按依赖分析二进制体积
goweight
# 理解依赖存在的原因
go mod why -m github.com/some/module
# 可视化依赖图
go mod graph | modgraphviz | dot -Tpng -o deps.png
# 验证校验和
go mod verify




