T4L2

Time to learn for everything

0%

Go基础之Modules

0. 引言

Golang 1.11版本引入了Go.mod作为官方的包管理工具。

Go.mod,也就是Module。Module是相关Go包的集合,是源代码交换和版本控制的单元。Modules替换旧的基于GOPATH的方法,来指定使用哪些源文件。

在引入go.mod之前,项目必须放在$GOPATH/src目录下,依赖要靠手动管理,并且依赖包没有版本一说,对开发造成了极大的困扰。之后的vendor部分解决了上述问题,但是依赖包需要全部下载到项目的vendor路径下。go.mod则将依赖包默认下载到$GOPATH/pkg/mod路径下,减少开发者对依赖的关心,只需关注个人代码,同时减轻了push/pull压力,也避免了他人随意修改依赖。

1. go mod命令

Golang提供了go mod命令来管理包,主要包含以下命令:

命令 说明
download 下载依赖包
edit 编辑go.mod
graph 打印模块依赖图
init 在当前目录初始化mod
tidy 拉取缺少的模块,移除不用的模块
vendor 将依赖复制到vendor下
verify 验证以来是否正确
why 解释为什么需要依赖

这里面init、tidy、和edit相对常用。

2. go.mod的使用

要使用go.mod,要将Golang版本升级到1.11以上,并将环境变量GO111MODULE改为on。

go.mod使用后,避免了项目只能放在$GOPATH/src下的问题,可以在任意位置创建项目。项目创建后,即可初始化go.mod。

1
go mod init <pkg_path>

go.mod文件主要包含以下内容。

1
module <pkg_path> //项目名称或路径
2
3
go 1.14 // Golang版本
4
5
// 依赖项模块
6
require (
7
    k8s.io/klog/v2 v2.8.0
8
    ...
9
)
10
11
// 可替换依赖项模块
12
replace (
13
    golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a => github.com/golang/crypto v0.0.0-20190313024323-a1f597ede03a
14
    ...
15
)
16
17
exclude (
18
    // 可忽略依赖项模块
19
)

刚刚创建好的go.mod文件一般只包含项目名称和Golang版本,但是go.mod文件创建好之后,go run等命令即可自动更新go.mod文件,自动查找项目中的依赖项并下载。其下载原则是优先拉取最新的release tag,其次是最新的commit。此外go还会自动生成go.sum文件记录依赖树。

replace用于替换无法直接获取的包或失效的包,例如将golang.org上的包替换成GitHub上对应的库,也可以在fork他人项目进行修改时将git上的依赖包替换为本地。

1
replace github.com/kubeedge/mapper-go => ./mappers-go

go.mod中常常会见到一长串的版本信息,默认为v0.0.0-<time>-<commit_id>。这种情况往往是依赖没有tag,版本信息来自于commit,实质上没有进行版本控制管理,不建议。