Go Modules
go.mod、版本选择、replace、私有仓库、以及多模块工作区。
Key Points`go.mod` 声明依赖,`go.sum` 锁定校验和;`go mod tidy` 保持两者一致。
go.mod 长什么样
Text
module example.com/shop
go 1.22
require (
github.com/gin-gonic/gin v1.10.0
github.com/jmoiron/sqlx v1.4.0
)
require (
github.com/bytedance/sonic v1.11.6 // indirect
golang.org/x/sys v0.20.0 // indirect
)
replace example.com/legacy => ../legacy| Line | Meaning |
|---|---|
module | 模块路径,也是别人 import 的路径 |
go 1.22 | 最低语言版本 |
require | 直接依赖 |
// indirect | 传递依赖,没被直接 import |
replace | 替换依赖来源 |
exclude | 排除某个版本 |
常用命令
Bash
go mod init example.com/shop
go mod tidy # 同步依赖(最常用)
go get github.com/gin-gonic/gin@v1.10.0
go get -u ./... # 升级全部到最新兼容版
go list -m all # 依赖树
go mod why github.com/gin-gonic/gin # 谁引入了它
go mod graph # 依赖图
go mod vendor # 复制依赖到 vendor/
go mod verify # 校验 go.sumOutput
$ go mod why github.com/bytedance/sonic
# github.com/bytedance/sonic
example.com/shop/internal/api
github.com/gin-gonic/gin
github.com/bytedance/sonic版本选择规则
Go uses Minimal Version Selection (MVS): if A needs lib v1.2 and B needs lib v1.5, the result is v1.5 — the lowest version satisfying everyone. Builds stay reproducible and nothing upgrades just because a new release appeared.
replace
Go
# 本地调试自己的另一个模块
go mod edit -replace example.com/legacy=../legacy
# 换成 fork 的版本
go mod edit -replace github.com/orig/pkg=github.com/you/pkg@v1.2.3
# 换成某个 commit
go mod edit -replace github.com/x/y=github.com/x/y@v0.0.0-20240101120000-abcdef123456replace applies only to the current module and is not transitive. Use it for local debugging; to fix someone else's dependency, send a PR or fork.私有仓库
Bash
go env -w GOPRIVATE=git.mycorp.com,github.com/mycorp
go env -w GONOSUMDB=git.mycorp.com
go env -w GONOPROXY=git.mycorp.comBash
# 让 git 用 SSH 而不是 https(避免每次输密码)
git config --global url."git@git.mycorp.com:".insteadOf "https://git.mycorp.com/"多模块工作区
Bash
go work init ./service ./shared ./toolsText
# go.work
go 1.22
use (
./service
./shared
./tools
)go.work lets several local modules reference each other without replace. It usually stays out of git (or only the main repo), since directory layouts differ per developer.
go.sum must be committed — it is the checksum list preventing tampering or substitution. Deleting it still builds, but you lose the first line of supply-chain defence.go.mod 长什么样
Text
module example.com/shop
go 1.22
require (
github.com/gin-gonic/gin v1.10.0
github.com/jmoiron/sqlx v1.4.0
)
require (
github.com/bytedance/sonic v1.11.6 // indirect
golang.org/x/sys v0.20.0 // indirect
)
replace example.com/legacy => ../legacy| 行 | 含义 |
|---|---|
module | 模块路径,也是别人 import 的路径 |
go 1.22 | 最低语言版本 |
require | 直接依赖 |
// indirect | 传递依赖,没被直接 import |
replace | 替换依赖来源 |
exclude | 排除某个版本 |
常用命令
Bash
go mod init example.com/shop
go mod tidy # 同步依赖(最常用)
go get github.com/gin-gonic/gin@v1.10.0
go get -u ./... # 升级全部到最新兼容版
go list -m all # 依赖树
go mod why github.com/gin-gonic/gin # 谁引入了它
go mod graph # 依赖图
go mod vendor # 复制依赖到 vendor/
go mod verify # 校验 go.sumOutput
$ go mod why github.com/bytedance/sonic
# github.com/bytedance/sonic
example.com/shop/internal/api
github.com/gin-gonic/gin
github.com/bytedance/sonic版本选择规则
Go 用最小版本选择(MVS):如果 A 需要 lib v1.2、B 需要 lib v1.5,最终选 v1.5——选能满足所有人的最低版本。这保证构建可复现,也不会因为某个包发了新版就自动升。
replace
Go
# 本地调试自己的另一个模块
go mod edit -replace example.com/legacy=../legacy
# 换成 fork 的版本
go mod edit -replace github.com/orig/pkg=github.com/you/pkg@v1.2.3
# 换成某个 commit
go mod edit -replace github.com/x/y=github.com/x/y@v0.0.0-20240101120000-abcdef123456replace 只在当前模块生效,不会传递给依赖你的项目。所以它适合本地调试,不能用来「修好」别人的依赖——那种情况应该提 PR 或 fork。私有仓库
Bash
go env -w GOPRIVATE=git.mycorp.com,github.com/mycorp
go env -w GONOSUMDB=git.mycorp.com
go env -w GONOPROXY=git.mycorp.comBash
# 让 git 用 SSH 而不是 https(避免每次输密码)
git config --global url."git@git.mycorp.com:".insteadOf "https://git.mycorp.com/"多模块工作区
Bash
go work init ./service ./shared ./toolsText
# go.work
go 1.22
use (
./service
./shared
./tools
)go.work 让几个本地模块互相引用时不必写 replace。它通常不进 git(或只进主仓库),因为每个人的目录结构可能不同。
go.sum 必须提交。它是校验和清单,防止依赖被篡改或替换。删掉它虽然能装,但失去了供应链安全的第一道防线。