Go mod使用指南

海阳之新 · · 8660 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一、启用go mod

go env -w GO111MODULE=on #开启 MODULE
go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct   #默认值为https://proxy.golang.org,direct

GO111MODULE可以设置为:off、on、auto(默认值),从GO111MODULE变量名可以看出,是Go1.11版本之后才出来有依赖包管理办法。

  • off时,则不使用go mod,查找依赖包的顺序是:当前项目根目录/vendor,其次是$GOPATH/src(这是Golang1.11版本之前的用法)。
  • on时,则开启go mod,查找依赖包是以当前项目根目录的go.mod文件为基准,会忽略 $GOPATHvendor 文件夹,只根据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,模块名为你的项目名,必须为英文名称,允许字母数字下划线和/,但是不能以/开头。

go mod init [模块名]

如果我们的项目根目录在$GOPATH/src/中,模块名可以不填写,将自动生成,一般是与项目根目录名称同名,如project1github.com/project1;如果项目根目录不在$GOPATH/src/中,则模块名必须填写,模块名同样可以命名如project1github.com/project1,也就是说模块名不一定与路径对应起来,但如果我们使用了路径,如github.com/project1,后续也可以把项目搬到$GOPATH/src/github.com目录下去。
执行完后,会在当前项目根目录下创建一个go.mod文件,内容如:

module project1

go 1.13

此时还没有任何依赖包信息。

三、整理依赖包

go mod tidy

命令执行后,go mod会去项目文件中发现依赖包,将依赖包名单添加到go.mod文件中,自动删除那些有错误或者没有使用的依赖包。

四、将依赖包拷贝到项目vendor

go mod vendor

在项目完工时,我们也可以把依赖包复制到项目根目录/vendor/,以便存档,其实也可以不做这个操作,有go.mod文档就够了。
项目根目录下有了vendor后,就可以这样编译:

go build -mod vendor -o ./project1  //project1为编译后的包名,或如下面,加上文件名
go build -mod vendor -o ./project1 main.go

五、其他常用命令

下载依赖包到本地缓存

go mod download

若之前拉过一次代码,会把该次go.mod里面的版本信息缓存到$GOPATH/pkg/mod/cache里面,
下载时如果cache有该版本信息,就用cache里面的版本信息去下载,否则重新下载。
注意:如果你已经拉取了一个tag版本下的包,若这个tag包含的信息被修改了,需要清除cache才能重新拉取这个这个更新后tag的信息。

清理本地依赖包

go clean -modcache

以上命令是go mod download的反操作,执行后会删除放置在$GOPATH/pkg/mod/cache下的依赖包缓存,有时依赖包出现错误,可以先清理后再重新下载到本地缓存。

添加单个依赖包

go mod edit -require=golang.org/x/text

移除单个依赖包
如果我们不再使用某个包了,可以单独移除,如:

go mod edit -droprequire=golang.org/x/text

验证依赖是否正确

go mod verify

解释为什么需要依赖

go mod why

校验所有依赖包的正确性

go mod verify

六、go.mod文档说明

go.mod文件可以通过require,replace,exclude语句来说明依赖包的管理规则:
require语句用于指定必不可少的依赖包
replace语句用于指定需要替换依赖包的地址,比如golang.org/x/text包替换成github.com/golang/text
exclude语句用于指定可以忽略依赖项模块
例如:

replace (
    cloud.google.com/go => github.com/googleapis/google-cloud-go v0.34.0
    github.com/go-tomb/tomb => gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7
    go.opencensus.io => github.com/census-instrumentation/opencensus-go v0.19.0
    go.uber.org/atomic => github.com/uber-go/atomic v1.3.2
    go.uber.org/multierr => github.com/uber-go/multierr v1.1.0
    go.uber.org/zap => github.com/uber-go/zap v1.9.1

    golang.org/x/crypto => github.com/golang/crypto v0.0.0-20181001203147-e3636079e1a4
    golang.org/x/lint => github.com/golang/lint v0.0.0-20181026193005-c67002cb31c3
    golang.org/x/net => github.com/golang/net v0.0.0-20180826012351-8a410e7b638d
    golang.org/x/oauth2 => github.com/golang/oauth2 v0.0.0-20180821212333-d2e6202438be
    golang.org/x/sync => github.com/golang/sync v0.0.0-20181108010431-42b317875d0f
    golang.org/x/sys => github.com/golang/sys v0.0.0-20181116152217-5ac8a444bdc5
    golang.org/x/text => github.com/golang/text v0.3.0
    golang.org/x/time => github.com/golang/time v0.0.0-20180412165947-fbb02b2291d2
    golang.org/x/tools => github.com/golang/tools v0.0.0-20181219222714-6e267b5cc78e
    google.golang.org/api => github.com/googleapis/google-api-go-client v0.0.0-20181220000619-583d854617af
    google.golang.org/appengine => github.com/golang/appengine v1.3.0
    google.golang.org/genproto => github.com/google/go-genproto v0.0.0-20181219182458-5a97ab628bfb
    google.golang.org/grpc => github.com/grpc/grpc-go v1.17.0
    gopkg.in/alecthomas/kingpin.v2 => github.com/alecthomas/kingpin v2.2.6+incompatible
    gopkg.in/mgo.v2 => github.com/go-mgo/mgo v0.0.0-20180705113604-9856a29383ce
    gopkg.in/vmihailenco/msgpack.v2 => github.com/vmihailenco/msgpack v2.9.1+incompatible
    gopkg.in/yaml.v2 => github.com/go-yaml/yaml v0.0.0-20181115110504-51d6538a90f8
    labix.org/v2/mgo => github.com/go-mgo/mgo v0.0.0-20160801194620-b6121c6199b7
    launchpad.net/gocheck => github.com/go-check/check v0.0.0-20180628173108-788fd7840127
)

主要包括: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子模块拉取。

查看指定包可以下载的版本

go list -m -versions github.com/gogf/gf

下载项目依赖

go get ./...

拉取最新的版本(优先择取 tag)

go get golang.org/x/text@latest

拉取 master 分支的最新 commit

go get golang.org/x/text@master

拉取 tag 为 v0.3.2 的 commit

go get golang.org/x/text@v0.3.2

拉取 hash 为 342b231 的 commit,最终会被转换为 v0.3.2:

go get golang.org/x/text@342b2e

指定版本拉取,拉取v3版本

go get github.com/smartwalle/alipay/v3

更新

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/路径中,配合着国内的依赖包镜像源,体验很顺滑,推荐!


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:海阳之新

查看原文:Go mod使用指南

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

8660 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传