Go Modules

go.mod、版本选择、replace、私有仓库、以及多模块工作区。

Intermediate
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
LineMeaning
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.sum
Output
$ 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-abcdef123456
replace 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.com
Bash
# 让 git 用 SSH 而不是 https(避免每次输密码)
git config --global url."git@git.mycorp.com:".insteadOf "https://git.mycorp.com/"

多模块工作区

Bash
go work init ./service ./shared ./tools
Text
# 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.

Friends & Partners