一、启用go mod
1 | go env -w GO111MODULE=on #开启 MODULE |
GO111MODULE可以设置为:off、on、auto(默认值),从GO111MODULE变量名可以看出,是Go1.11版本之后才出来有依赖包管理办法。
- 为
off
时,则不使用go mod,查找依赖包的顺序是:当前项目根目录/vendor
,其次是$GOPATH/src
(这是Golang1.11版本之前的用法)。 - 为
on
时,则开启go mod,查找依赖包是以当前项目根目录的go.mod
文件为基准,会忽略$GOPATH
和vendor
文件夹,只根据go.mod
下载依赖。 - 为
auto
或未设置,则go命令根据当前目录启用或禁用模块支持。仅当当前目录位于$GOPATH/src
之外且其本身包含go.mod
文件或位于包含go.mod
文件的目录下时,才启用模块支持。
GOPROXY为依赖包代理地址,由于像golang.org/x
这种依赖包需要翻墙才能下载,所以建议设置成国内镜像地址:
https://goproxy.cn 为国内七牛云维护的GO的镜像地址。
https://goproxy.io 为国内另一个镜像地址。
二、初始化go.mod
进入项目根目录(假如目录名为project1),初始化一个moudle,模块名为你的项目名,必须为英文名称,允许字母数字下划线和/
,但是不能以/
开头。
1 | go mod init [模块名] |
如果我们的项目根目录在$GOPATH/src/
中,模块名可以不填写,将自动生成,一般是与项目根目录名称同名,如project1
或github.com/project1
;如果项目根目录不在$GOPATH/src/
中,则模块名必须填写,模块名同样可以命名如project1
或github.com/project1
,也就是说模块名不一定与路径对应起来,但如果我们使用了路径,如github.com/project1
,后续也可以把项目搬到$GOPATH/src/github.com
目录下去。
执行完后,会在当前项目根目录下创建一个go.mod
文件,内容如:
1 | module project1 |
此时还没有任何依赖包信息。
三、整理依赖包
1 | go mod tidy |
命令执行后,go mod会去项目文件中发现依赖包,将依赖包名单添加到go.mod
文件中,自动删除那些有错误或者没有使用的依赖包。
四、将依赖包拷贝到项目vendor
1 | go mod vendor |
在项目完工时,我们也可以把依赖包复制到项目根目录/vendor/
,以便存档,其实也可以不做这个操作,有go.mod
文档就够了。
项目根目录下有了vendor后,就可以这样编译:
1 | go build -mod vendor -o ./project1 //project1为编译后的包名,或如下面,加上文件名 |
五、其他常用命令
下载依赖包到本地缓存
1 | go mod download |
若之前拉过一次代码,会把该次go.mod
里面的版本信息缓存到$GOPATH/pkg/mod/cache
里面,
下载时如果cache有该版本信息,就用cache里面的版本信息去下载,否则重新下载。
注意:如果你已经拉取了一个tag版本下的包,若这个tag包含的信息被修改了,需要清除cache才能重新拉取这个这个更新后tag的信息。
清理本地依赖包
1 | go clean -modcache |
以上命令是go mod download
的反操作,执行后会删除放置在$GOPATH/pkg/mod/cache
下的依赖包缓存,有时依赖包出现错误,可以先清理后再重新下载到本地缓存。
添加单个依赖包
1 | go mod edit -require=golang.org/x/text |
移除单个依赖包
如果我们不再使用某个包了,可以单独移除,如:
1 | go mod edit -droprequire=golang.org/x/text |
验证依赖是否正确
1 | go mod verify |
解释为什么需要依赖
1 | go mod why |
校验所有依赖包的正确性
1 | go mod verify |
六、go.mod文档说明
go.mod
文件可以通过require,replace,exclude
语句来说明依赖包的管理规则:require
语句用于指定必不可少的依赖包replace
语句用于指定需要替换依赖包的地址,比如golang.org/x/text
包替换成github.com/golang/text
exclude
语句用于指定可以忽略依赖项模块
例如:
1 | replace ( |
主要包括:golang.org google.golang.org gopkg.in go.uber.org cloud.google.com
在下载包时会有timeout 导致编译失败,以上是对应的github库的替换。
七、go get的使用
使用go mod
之后,go get
拉取依赖的方式就发生了变化:
1、老的go get取包过程类似:git clone + go install
, 开启Go Module功能后go get
就只有git clone
或者 download过程了。
2、新老实现还有一个不同是,两者存包的位置不同。前者,存放在$GOPATH/src
目录下;后者,存放在$GOPATH/pkg/mod
目录下。
3、老的go get
取完主包后,会对其repo下的submodule
进行循环拉取。新的go get
不再支持submodule
子模块拉取。
查看指定包可以下载的版本
1 | go list -m -versions github.com/gogf/gf |
下载项目依赖
1 | go get ./... |
拉取最新的版本(优先择取 tag)
1 | go get golang.org/x/text@latest |
拉取 master 分支的最新 commit
1 | go get golang.org/x/text@master |
拉取 tag 为 v0.3.2 的 commit
1 | go get golang.org/x/text@v0.3.2 |
拉取 hash 为 342b231 的 commit,最终会被转换为 v0.3.2:
1 | go get golang.org/x/text@342b2e |
指定版本拉取,拉取v3版本
1 | go get github.com/smartwalle/alipay/v3 |
更新
1 | go get -u |
八、go mod与原GOPATH的区别
1、环境变量GOPATH
不再用于解析imports包路径,即原有的$GOPATH/src/
下的包,通过import是找不到了
2、Go Module功能开启后,下载的包将存放与$GOPATH/pkg/mod
路径
3、$GOPATH/bin
路径的功能依旧保持
总结
在Go1.11版本之前,依赖包管理一直是GOPATH的包管理方式,不太灵活方便,1.11版本发布后,带来了全新的go mod
管理方式,用官方的话说,这是 GOPATH 的替代方案,集成了对版本控制和软件包分发的支持。可以看出借鉴了nodejs等包管理方式,项目的创建不再需要放在固定的$GOPATH/src/
路径中,配合着国内的依赖包镜像源,体验很顺滑,推荐!