参考资料:https://mp.weixin.qq.com/s/zo7zmEVXvxgr80n6H_49Mg
什么是 Go Modules?
- Golang 的依赖库解决方案,于 Go1.14 推荐在生产环境上使用;
 
关于 GOPATH
GOPATH 是一个 golang 的语言环境变量,输入以下命令,可以查看本机的值:
 |  | 
GOPATH 指向一个绝对路径,这个路径下,应该有 bin/、pkg/、src/ 三个文件夹。
在 GOPATH 模式下:
- 应用的代码应该存放在固定的目录 
$GOPATH/src下; - 如果执行 
go get拉取外部的依赖,会将其自动下载并安装到$GOPATH目录下; 
GOPATH 模式的致命缺陷:没有版本控制的概念。
在 GOPATH 模式下诞生了许多依赖解决方案:vendor 目录模式,依赖工具 dep,Go 1.11 释放出 Go Modules 前身 vgo。
基本使用
在 Go modules 中,我们能够使用如下命令进行操作:
| 命令 | 作用 | 
|---|---|
| go mod init | 生成 go.mod 文件 | 
| go mod download | 下载 go.mod 文件中指明的所有依赖 | 
| go mod tidy | 整理现有的依赖 | 
| go mod graph | 查看现有的依赖结构 | 
| go mod edit | 编辑 go.mod 文件 | 
| go mod vendor | 导出项目所有的依赖到vendor目录 | 
| go mod verify | 校验一个模块是否被篡改过 | 
| go mod why | 查看为什么需要依赖某模块 | 
在 Go Modules 中有如下常用的环境变量(同样可以用 go env 命令查看):
GO111MODULE:是否开启 Go Modules 的开关,有三个值。auto表示通过是否存在文件go.mod文件判断,on表示启用,off表示禁用;GOPROXY:用于使 Go 在后续拉取模块版本时能够脱离传统的 VCS 方式,直接通过镜像站点来快速拉取。它的默认值是https://proxy.golang.org,direct;可以用以下命令切换成国内源:1$ go env -w GOPROXY=https://goproxy.cn,directGOSUMDB:一个远程的 checksum 数据库,默认指向sum.golang.org,它在国内也是无法访问的,但是它可以被 GOPROXY 所代理;GONOPROXY/GONOSUMDB/GOPRIVATE:功能与前三者类似,一般用于当前项目的依赖了私有模块。一般建议直接设置 GOPRIVATE,它的值将作为 GONOPROXY 和 GONOSUMDB 的默认值:1$ go env -w GOPRIVATE="git.example.com,github.com/eddycjy/mquote"
go.mod 文件
这个文件描述了当前项目(也就是当前模块)的元信息,每一行都以一个动词开头。
一般常用的动词有:
module:用于定义当前项目的模块路径。比如:1module github.com/eddycjy/module-repogo:用于标识当前模块的 Go 语言版本,值为初始化模块时的版本。比如:1go 1.13require:用于设置一个特定的模块版本。比如:1 2 3 4 5 6 7require ( example.com/apple v0.1.2 example.com/banana v1.2.3 example.com/banana/v2 v2.3.4 example.com/pear // indirect example.com/strawberry // incompatible )exclude:用于从使用中排除一个特定的模块版本。比如:1exclude example.com/banana v1.2.4replace:用于将一个模块版本替换为另外一个模块版本。比如:1 2replace example.com/apple v0.1.2 => example.com/fried v0.1.0 replace example.com/banana => example.com/fish
PostScript:
go.sum文件:存储着拉取模块依赖后,这些模块的哈希值防止它们被篡改。
go get 行为
拉取的过程大致分为三步:finding 发现、downloading 下载、extracting 提取。
常用的 go get 命令:
| 命令 | 作用 | 
|---|---|
| go get | 拉取依赖,会进行指定性拉取(更新),并不会更新所依赖的其它模块。 | 
| go get -u | 更新现有的依赖,会强制更新它所依赖的其它全部模块,不包括自身。 | 
| go get -u -t ./… | 更新所有直接依赖和间接依赖的模块版本,包括单元测试中用到的。 | 
指定版本的方式有以下这些:
xxx@latest最新版本,xxx@master对应分支的最新 commit,xxx@v0.3.0仓库 tag 对应的版本,xxx@342b2ecommit 的哈希值;