golang-dependency-management

golang-dependency-management

热门

Golang 项目的依赖管理策略——go.mod 管理、安装/升级包、最小版本选择、漏洞扫描、过时依赖跟踪、二进制体积分析、Dependabot/Renovate 配置、冲突解决以及 go.work 工作区。在添加、删除或升级 Go 依赖、审计漏洞、解决版本冲突或设置自动依赖更新时使用。

2261Star
150Fork
更新于 2026/6/6
SKILL.md
只读
名称
golang-dependency-management
描述

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