接触Go Modules

Go Modules 特性是在 go1.11 开始加入的, 写这篇文章时官方刚刚发布了 go1.11Beta3 版本,如果你的 go 版本低于 1.11 则需要更新你的 go tools。

module 具体指的是什么

按照官方文档的说法, module是一个带版本信息的package集合,它们之间的关系如下图:

module、package、version-control repository 三者之间的关系

module 之间没有父子关系,它们都是独立的。

module 声明方式

go module 使用一个名叫go.mod的文件来定义你的 module,该文件记录 module 的一些基本信息。 module 目录可以不在 GOPATH 下,Go Tools 也能识别。

go.mod文件内容示例:

1
2
3
4
5
6
module blog

require (
github.com/gitwillsky/slimgo v1.0.0
github.com/pkg/errors v0.8.0
)

关键字 module

用来定义 module 的路径(非文件系统路径),这个路径可以定义为以下几种形式:

1
2
3
4
example.com/my/module
example.com/my/module/v2
my/module // 本地module
module

关键字 require

用来声明该 module 所依赖的其他 module(package),声明以后,每当执行go tools都会检查依赖的完整性并自动下载依赖。

即使你不在go.mod中声明依赖,go tools也会在执行时自动检查代码的import块并自动将没有声明的 modue(package)写入go.mod文件,依赖版本默认为最后的 Release 版本。

module 的版本

go module 规定 module 必须按照 v(major).(minor).(patch) 的形式来定义版本(Release tag),其中major如果大于 2 则必须同时在module path中指出,比如:me.io/my/mod/v2

依赖同一模块不同版本时如何选择?

go tools 从仓库拉取依赖的时候,使用minimal version selection算法:分析go.modrequire, 在major相同的情况下,选取requireminor最大的那个版本作为依赖模块的版本。

更新依赖版本

更新 minor 版本:

1
$ go get -u

更新 patch 版本:

1
$ go get -u=patch

更新到指定版本:

1
2
3
4
$ go get github.com/gorilla/mux@latest
$ go get github.com/gorilla/mux@master
$ go get github.com/gorilla/mux@v1.6.2
$ go get github.com/gorilla/mux@''<v1.6.2''

如何创建一个 module

进入即将创建 module 的根目录

1
2
$ cd $GOPATH/src/<project path>
$ export GO111MODULE=on

1
$ cd <project path outside $GOPATH/src>

如果之前该工程由dep等依赖管理工具管理,则使用下面的命令创建:

1
go mod init

go tools会自动分析之前的依赖信息并写入go.mod文件。

或者,使用下面的命令来手动新建一个空的go.mod文件:

1
go mod init module_path

执行go build 命令,让go tools分析 module 的源代码,找出在go.mod文件中没有声明的 module 并自动添加进去。

下载的依赖存放在什么地方?

$GOPATH/pkg/mod/cache/ 目录下

使用感受

  • go module给 go 的依赖管理增加了版本功能。
  • gopath不再显得那么僵硬了。

参考

作者

m3m0ry

发布于

2020-04-11

更新于

2020-09-20

许可协议

评论