使用 Go Modules
背景
Go 1.11 之前,包管理不太方便,所有的项目需要在 GOPATH 目录下统一管理。我们还可以同时使用 vendor 目录来保存所有的依赖。可用的包管理工具有官方的 dep 或第三方的 govendor 等。
从 Go 1.11 开始,Go 引入了新的版本管理机制 —— Go Modules。从 1.13 开始,Go Modules 成为了 Go 的默认包管理工具(在此之前是 GOPATH)。因此现在推荐使用 Go Modules 来管理所有的依赖。
使用 Go Modules,我们的代码就可以不必全部放在 GOPATH 下,并按照包的路径来存放代码目录了。我们可以把代码放在 GOPATH 之外的目录。
本文为 Go Modules 的初级使用指南。
开始使用
初始化
在使用 Go Modules 之前,我们需要把代码目录放在
GOPATH之外进入代码根目录执行
go mod init 包路径$ go mod init github.com/yuqingc/hello执行完成命令之后,代码根目录会生成
go.mod。类似 Node.js 项目中的package.jsonmodule github.com/yuqingc/hello go 1.15
添加依赖
如果代码中有外部依赖的包,在执行会触发编译 go 命令的时候(如
go run,go build,go install,go test等)会自动在go.mod中自动添加依赖module github.com/yuqingc/hello go 1.15 require rsc.io/quote/v3 v3.1.0同时会生成
go.sum文件。go.sum文件类似package-lock.json,记录了依赖树的版本及其 Hashgo.mod和go.sum需要包含在版本管理中 (不要写入.gitignore)下载下来的依赖,会保存在
$GOPATH/pkg/mod目录下
安装和升级依赖
在 Go Module 模式下,go get 的行为会发生改变。在 GOPATH 模式下,go get 会把代码下载到 GOPATH 下对应的 src 目录下。而在 Go Module 模式下,go get 会给当前的项目下载最新版本的依赖,并写入 go.mod 和 go.sum
如果下载的依赖没有被项目的代码直接 import,则会在 go.mod 的对应项目中自动添加注释 // indirect
module example.com/hello
go 1.15
require (
golang.org/x/text v0.3.3 // indirect
rsc.io/quote/v3 v3.1.0
)
依赖版本规则
所有的版本遵循 semantic 版本号规则。不论是通过代码中 import 自动解析的依赖,还是通过 go get 手动安装的依赖,都遵循如下规则
默认安装最新版本(
@latest),包括- 最新带有 tag 的稳定版
- 或者最新带有 tag 的 pre-release 版
- 或最新不带 tag 的版本(pseudo-version,则版本号为 git 最新提交记录的 Hash)
可以通过包名后加
@版本号来手动下载指定的版本的依赖$ go get rsc.io/sampler@v1.3.1如果某个包有含多个 Major 版本,则使用默认包路径下载的版本最大为
v1.x的版本为了使项目同时兼容多个包的 Major 版本,
v2.x之后的包名需要在结尾添加形如v3的后缀代码:
package hello import "rsc.io/quote/v3"命令:
$ go get rsc.io/quote/v3
依赖管理的相关命令
go list -mm代表modules,此命令集用来列出与 Modules 相关信息go list -m all列出项目中的所有依赖及其依赖树go list -m -versions 包名列出指定包的所有版本号
go mod tidy用来移除无用的依赖
