Go 在 1.11 提出了 Go Module 作为 Go 的包管理模式。
官方文档在 这里,提供了非常多的常用流程。完整的参考文档在 这里。
Go 并不强制使用 go module。当在本地磁盘查找一个库时,go 有两种做法:
- 传统方式:从
GOPATH
或者项目的vendor
目录中寻找 - go module 方式:根据
go.mod
,go.sum
来安装或者寻找包。包默认放在$GOPATH/pkg/mod
中
新版本的 Go 中,go module 方式成为默认方式。
加速包拉取
可以设置 GOPROXY
环境变量为 七牛运营的中国镜像,下载速度极快:
go env -w GOPROXY="https://goproxy.cn,direct"
初始化新仓库
使用 go mod init <your-module-name>
,比如 go mod init github.com/onlyice/my-go-module
。
添加新依赖库
在工程目录中,使用 go get <your-package>[@version]
。比如 go get gorm.io/gorm
。加入 -u
参数,会把你要加的库及其依赖,升级到最新的 minor.patch 版本。-u=patch
的话,只升级 patch 版本,不升级 minor 版本。再加入 -t
参数,会对库的 test 依赖也进行升级。
加入新依赖库后,不要急着 go mod tidy
去生成它的 go.sum
条目。先要在代码中 import 此包;否则 go mod tidy
会认为你没有用到这个包,把它从 go.mod
文件中去除。
如何查看包的依赖路径?
go mod why [packages]
可以用来解释一个包是如何被依赖到的,但对于每个包,它只会显示一个最短路径的依赖。
go mod graph
可以把包之间的直接和间接依赖都打出来。可以在其中检索你想看的包。
多模块仓库
多模块仓库指,一个仓库中有多个模块。例如,对于下面这个仓库的目录结构:
myrepo
└── metaservice
├── go.mod
├── go.sum
├── option.go
└── store.go
└── userservice
├── go.mod
├── go.sum
├── option.go
└── store.go
好处是,假如 metaservice 依赖了 foo 包,userservice 依赖了 bar 包。对于只需要依赖 metaservice 的用户来说,它只会引入 foo 作为间接依赖,而不会引入 bar 包。
这种仓库下,发版本时打的 tag 需要是这样的:metaservice/v1.0.0
,userservice/v1.0.0
。它们的用户 go get 时则按正常来即可:
go get github.com/user/repo/metaservice@v1.0.0
GitHub wiki 中有一份 Multi-Module Repositories 的 FAQ。
Go modules 如何维护一个包的多个版本?
Go modules 在 $GOPATH/pkg/mod
下存放它下载的依赖、VCS 缓存等。这里面的目录结构使其可以保存一个包的多个版本。