命令 作用
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 查看为什么需要依赖某模块

GO111MODULE

Go语言提供了 GO111MODULE 这个环境变量来作为 Go modules 的开关,其允许设置以下参数:

  • auto:只要项目包含了 go.mod 文件的话启用 Go modules,目前在 Go1.11 至 Go1.14 中仍然是默认值。
  • on:启用 Go modules,推荐设置,将会是未来版本中的默认值。
  • off:禁用 Go modules,不推荐设置。

如果需要对GO111MODULE的值进行变更,推荐通过go env命令进行设置:

  1. go env -w GO111MODULE=on

又或是可以通过直接设置系统环境变量(写入对应的.bash_profile文件亦可)来实现这个目的:

  1. export GO111MODULE=on

GOPROXY

GOPROXY 的默认值是:[https://proxy.golang.org,direct](https://proxy.golang.org,direct),这有一个很严重的问题,就是 proxy.golang.org 在国内是无法访问的,因此这会直接卡住你的第一步,所以你必须在开启 Go modules 的时,同时设置国内的 Go 模块代理,执行如下命令:

  1. go env -w GOPROXY=https://goproxy.cn,direct

GOPROXY的值是一个以英文逗号 “,” 分割的 Go 模块代理列表,允许设置多个模块代理,假设你不想使用,也可以将其设置为 “off” ,这将会禁止 Go 在后续操作中使用任何 Go 模块代理。

实际上 “direct” 是一个特殊指示符,用于指示 Go 回源到模块版本的源地址去抓取(比如 GitHub 等)

GOPRIVATE

例如像是你公司的私有 git 仓库,又或是 github 中的私有库,都是属于私有模块,都是要进行设置的,否则会拉取失败。

  1. go env -w GOPRIVATE="git.example.com,github.com/eddycjy/mquote"

前缀为 git.xxx.com 和 github.com/eddycjy/mquote 的模块都会被认为是私有模块。
如果不想每次都重新设置,我们也可以利用通配符,例如:

  1. go env -w GOPRIVATE="*.example.com"

如果你希望清理所有已缓存的模块版本数据,可以执行 go clean -modcache 命令。

Go Get

命令 作用
go get 拉取依赖,会进行指定性拉取(更新),并不会更新所依赖的其它模块。
go get -u 更新现有的依赖,会强制更新它所依赖的其它全部模块,不包括自身。
go get -u -t ./… 更新所有直接依赖和间接依赖的模块版本,包括单元测试中用到的。
go get golang.org/x/text@latest 拉取最新的版本,若存在tag,则优先使用。
go get golang.org/x/text@master 拉取 master 分支的最新 commit。
go get golang.org/x/text@v0.3.2 拉取 tag 为 v0.3.2 的 commit。
go get golang.org/x/text@342b2e 拉取 hash 为 342b231 的 commit,最终会被转换为 v0.3.2。

go get的版本选择

我们回顾一下我们拉取的 go get github.com/eddycjy/mquote,其结果是 v0.0.0-20200220041913-e066a990ce6f,对照着上面所提到的 go get 行为来看,你可能还会有一些疑惑,那就是在 go get 没有指定任何版本的情况下,它的版本选择规则是怎么样的,也就是为什么 go get 拉取的是 v0.0.0,它什么时候会拉取正常带版本号的 tags 呢。实际上这需要区分两种情况,如下:

  1. 所拉取的模块有发布 tags:
    • 如果只有单个模块,那么就取主版本号最大的那个tag。
    • 如果有多个模块,则推算相应的模块路径,取主版本号最大的那个tag(子模块的tag的模块路径会有前缀要求)
  2. 所拉取的模块没有发布过 tags:
    • 默认取主分支最新一次 commit 的 commithash。