一、基本流程
go mod init example.com/myapp # 初始化,生成 go.mod
go get github.com/gin-gonic/gin # 添加依赖
go mod tidy # 整理:加缺失的、删没用的
go mod download # 下载到本地缓存
go mod verify # 校验完整性
go.mod 记录直接依赖与版本,go.sum 记录所有模块的哈希值用于校验。两个文件都要提交到仓库,go.sum 不加会导致 CI 上校验失败。
二、go.mod 长什么样
module example.com/myapp
go 1.22
require (
github.com/gin-gonic/gin v1.10.0
golang.org/x/sync v0.7.0
)
replace example.com/old => example.com/new v1.2.0
module:模块路径,也是导入路径前缀。go 1.22:语言版本,影响编译行为。require:依赖及版本。replace:替换依赖来源(本地调试、临时修复常用)。exclude:排除某个版本。
三、版本号与伪版本
Go 用语义化版本 v1.2.3。没有打 tag 的提交会生成伪版本:
v0.0.0-20261103081244-abcdef123456
格式是「基础版本 + 时间戳 + 提交哈希」。看到这种版本说明依赖自某个 commit,不是正式发布。
主版本号 ≥ 2 时,模块路径要带 /v2,例如 github.com/x/y/v2。这是 Go 的兼容性约定,不同主版本可以共存。
四、GOPROXY:国内必须配
go env -w GOPROXY=https://goproxy.cn,direct
go env -w GOSUMDB=sum.golang.org
goproxy.cn(七牛)或 proxy.golang.org 的国内镜像,direct 表示代理找不到时直连。不配代理在国内经常卡在下载。
公司内网可以用私有代理(Athens、JFrog),或 GOPROXY=off + vendor。
GONOSUMDB / GOPRIVATE 用于让私有仓库跳过校验:
go env -w GOPRIVATE=git.example.com/*
五、replace 的三种用法
// 1. 用本地目录(调试自己的库)
replace example.com/lib => ../lib
// 2. 换成 fork 的版本
replace github.com/original/pkg => github.com/me/pkg v1.0.0
// 3. 锁定到某个提交
replace github.com/x/y => github.com/x/y v0.0.0-20261101000000-abcdef123456
replace 只在当前模块生效,不会传递给依赖你的项目。所以用它打补丁是「本地可用」,长期方案还是提 PR 或 fork 后统一替换。
改完 replace 要 go mod tidy 更新 go.sum。
六、vendor 模式
go mod vendor # 把依赖复制到 vendor/
go build -mod=vendor # 用 vendor 构建(Go 1.14+ 自动检测)
适合「构建环境不能联网」或「要求完全可复现」。代价是仓库体积变大,升级依赖要重新 vendor。CI 里可以加 go mod verify 和 go mod tidy -diff 检查一致性。
七、常见问题
| 现象 | 原因与解决 |
|---|---|
| 下载超时 | 未配 GOPROXY |
checksum mismatch | go.sum 与源不一致,删掉对应行重下,或检查是否被中间人替换 |
missing go.sum entry | 执行 go mod tidy 或 go mod download |
module declares its path as ... | 导入路径与 module 声明不一致 |
| 升级后编译失败 | 依赖有破坏性变更,看 CHANGELOG 或退回旧版本 |
| 循环依赖 | 拆分公共包,避免 A→B→A |
升级依赖:
go get -u ./... # 升级所有直接依赖(小版本)
go get github.com/x/y@v2.0.0 # 指定版本
go list -m -u all # 查看可升级的模块
-u 只升小版本和补丁版本,不会跨主版本。
八、多模块仓库
一个仓库多个 go.mod 时,可以在根目录用 go.work(工作区模式):
go 1.22
use (
./service-a
./service-b
./shared
)
本地开发时几个模块互相引用不用改 replace,非常方便。go.work 一般不提交(或按团队约定)。
小结
go mod init 起步,go mod tidy 收尾;go.mod 和 go.sum 都提交;国内配 GOPROXY=https://goproxy.cn,direct;本地调试用 replace,离线构建用 vendor;主版本 ≥2 路径带 /v2。