go mod使用简介
go mod是什么
Golang从诞生之初就一直有个被诟病的问题:缺少一个行之有效的“官方”包依赖管理工具。其原因是在Google内部,所有人都是在一个代码库上进行开发的,因此并不是非常需要。但Golang变成一个社区化的工程语言之后,这个问题被放大了。
GOPATH不符合一般开发者习惯,大部分人更习惯maven、node modules之类的方式
GOPATH无法有效的管理版本依赖,没有一个地方能够表明依赖包的具体版本号,无法形成有效的版本配套关系
在Golang 1.5发布了vendor特性之后,社区在vendor基础上开发了很多包管理工具,例如glide, dep(这个最悲催,已经半官方了,结果横刀杀出来一个go mod),等等,具体参见拙文go依赖包管理工具对比 。但说实话,都不是非常满意。
你可能会说dep,glide我用的都挺爽的,有什么不满意的?
其实我不喜欢的是vendor这个特性。开发过前端的同学对node modules一定印象深刻,得益于前端混乱的包管理,一个普通的web前端,其node modules往往非常巨大,而且它是每工程的,也就是说如果有2个前端工程,就会有两份巨大的node moudles,里面有成千上万个文件,常常造成IDE挂死,也非常浪费硬盘。
那么,vendor是不是到后期也会变成这样呢?同样的库,同样的版本,就因为在不同的工程里用了,就要在vendor里单独搞一份,不浪费吗?所以这些基于vendor的包管理工具,都会有这个问题。
相比之下maven这种本地缓存库的管理方式就好很多。
Golang 1.11 版本引入的 go mod ,其思想类似maven:摒弃vendor和GOPATH,拥抱本地库。
先来看看怎么用。
go mod 具体介绍
前提工作
把 golang 升级到 1.11(现在1.12 已经发布了,建议使用1.12)
设置 GO111MODULE
GO111MODULE
- GO111MODULE 有三个值:off, on和auto(默认值)。
- GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
- GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
- GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:
- 当前目录在GOPATH/src之外且该目录包含go.mod文件
- 当前文件在包含go.mod文件的目录下面。
1 | 当modules 功能启用时,依赖包的存放位置变更为$GOPATH/pkg,允许同一个package多个版本并存,且多个项目可以共享缓存的 module。 |
go mod 命令
- golang 提供了 go mod命令来管理包。
- go mod 有以下命令:
命令 | 说明 |
---|---|
download | download modules to local cache(下载依赖包) |
edit | edit go.mod from tools or scripts(编辑go.mod) |
graph | print module requirement graph (打印模块依赖图) |
init | initialize new module in current directory(在当前目录初始化mod) |
tidy | add missing and remove unused modules(拉取缺少的模块,移除不用的模块) |
vendor | make vendored copy of dependencies(将依赖复制到vendor下) |
verify | verify dependencies have expected content (验证依赖是否正确) |
why | explain why packages or modules are needed(解释为什么需要依赖) |
go mod 使用
新项目
1.在GOPATH 目录之外新建一个目录,并使用go mod init 初始化生成go.mod 文件
1
2
3
4
5
6
7
8
9
10➜ ~> mkdir hello
➜ ~> cd hello
➜ ~/hello> go mod init hello
go: creating new go.mod: module hello
➜ ~/hello> ls
go.mod
➜ ~/hello> cat go.mod
module hello
go 1.13go命令(‘go build’, ‘go test’, 甚至 ‘go list’)执行时,会自己去修改go.mod文件。
go mod 的拉取指定版本
在go.mod中指定版本
在使用go get 如果我们想指定一些版本信息, 可以参照下面的操作:
1
2
3
4
5// 根据tag
go get -u github.com/gin-gonic/gin@v1.3.0
// 根据commit id
go get github.com/xx/xx@0f1dbe038589903023daa297102f8688641dbe73
Tips
- 此外,一些墙外的包(golang.org/x/…)如果下载有问题,可以说设置代理
1
export GOPROXY=https://goproxy.io