go mod由来
文章主要是针对新人来介绍 go mod 是啥以及新手如何使用,老手不用看。现阶段go mod已经完全GA了,你会用了的话会非常方便
像 python 的项目根目录有requirement.txt
记录依赖包,nodejs 是packages.json
,同样 go 的包管理从早期的go dep(gopkg)到vendor到现在的go mod.
go dep 很早,没有接触过,如果你接触的项目有go dep,看完本文希望你可以学会改造你手上的老项目,vendor则是把包都存放项目的根路径的vendor
文件夹里,就像下面。这会导致一个项目很大,多达40M以上。
1 | $ tree -d -L 1 |
go是一个开放的态度下诞生的语言,并没有其他语言那样官方维护一个中心库,go的库大多数都是直接github上的。
开发者把包存放到github上,一般打tag作为版本,master作为pr和修补,定期cut出新tag。这个做法和实际的开发流程一样。在这个环境下,go的包管理不可能单单存放一个版本号,所以go.mod
是存放版本号,go.sum
记录git的hash值,以防止篡改。
这样并没有依赖包存在项目文件夹里导致项目代码体积过大,用户通过go mod download
命令会调用git去拉取依赖,或者直接go run
或者go build
也会下载。
go mod如何使用
基础配置和相关环境变量
新手的话推荐使用1.13+版本的go,go mod是诞生于1.11版本,在1.13差不多定型了。1.12之前使用gomod的话需要配置环境变量GO111MODULE=on
,这样才会开启 go mod,而 1.13 以后变量默认值为auto
,会根据项目下的文件夹和文件自动识别是否是go mod。例如下面就是一个纯go mod项目
1 | api/ |
如果之前用 vendor 由于依赖在本地,所以刚上手 go mod 的时候会发现go get
拉取超时,实际上我们可以配置环境变量让go拉取包的时候走代理过墙,也就是配置GOPROXY
。这个变量只有 go mod 启用下才能使用。
同时要注意的一点是,1.13+ 后GOPROXY
能配置多个代理地址,1.13
之前则只能1个地址,下面是常见的地址
1 | export GO111MODULE=on |
direct是直连,用于内网开发拉取内网的私有库。默认拉取的时候会从前到后retry,也可以GONOPROXY
配置某个不走代理
配置不走GOPROXY的私有库
1 | GOPRIVATE=*.a.example.com,*.b.example.com |
go env -w key=value
也可以快速配置,但是是用户家目录的配置文件,不是全局的,这点要注意。如果电脑个人使用就无所谓了
同时,也不要像以前以及网上的那些老视频教程那样把项目放在 GOPATH
上,现在 GOPATH
的概念越来越淡化了,不懂go mod下如果还是把项目创建在GOPATH下会容易出错。
同时也不要创建啥src pkg bin
目录了,都是过去式了,可以看上面那个 go mod 的项目文件列表,压根没有src啥的。同时不要像网上的老视频里一个项目整好几个demo,day0x或者lesson这样。
终端编译或者run
配置了两个环境变量,项目也是 go mod 的话我们直接 go run main.go
或者 go build
以及 go get
都会自动拉取包,不用担心墙
gomod和vendor共存
现在并不是所有用户都接受gomod,很多开源项目为了兼容新老用户,go mod和vendor都是有的,类似目录
1 | ... |
这样的项目我们编译的时候命令为
1 | go build -mod vendor main.go |
goland下的使用
分为新建项目和直接打开项目文件作为项目,不要把项目存放在GOPATH
下
goland新建gomod开局项目
New Project
的时候选择 Go Modules(vgo)
,我们写Proxy
就是GOPROXY
,勾上Vendoring mode
就是上面go mod和vendor共存的项目,如果你自己写新项目就不要勾选vendor了,vendor应该是过去式了。新版本goland里vendor是不可取消,不用管。
goland打开一个项目,或者改造一个项目
如果是打开一个文件夹的项目,或者New Project
的时候已经选择了Go Modules(vgo)
上面的Go
,我们需要配置下面
Settings
–>GO
–>GOPATH
–> Project GOPATH下面如果不为空,就选中后点击右边的减号删掉Settings
–>GO
–>Go Modules(vgo)
勾选Enable Go Modules(vgo) integration
,最新版goland会自动识别,可以不管- goland的
vgo Execute
下面如果是PROXY则直接写上Proxy的值,如果是Environment
则写GOPROXY=https://goproxy.cn,https://mirrors.aliyun.com/goproxy/,https://goproxy.io,direct
- 如果是改造项目的话记得写了
Proxy
后得重新关闭下goland里的terminal触发下新的环境变量
我们也可以终端操作
1.13 go mod init的话默认会以项目文件夹名为module名,例如下面
1 | F:\go\Installer>go mod init |
执行后go.mod第一行为
1 | module Installer |
假如我们项目路径为
1 | . |
我们要在main.go里引用api包的话就写
1 | import "Installer/api" |
第一个就是go.mod里第一行的module名,不仅限于一个单词,有的人会以公司网站或者github地址,例如
1 | module github.com/zhangguanzhang/Installer |
这种名字下我们引用api就是
1 | import "github.com/zhangguanzhang/Installer/api" |
1.14开始go mod init
后面必须接 module 名字
1 | $ go mod init |
有时候goland里设置改了不一定生效,所以我们得终端执行go mod init
触发下,然后关闭goland重开,还不行就删除掉项目下的.idea
,然后右击项目文件夹用goland打开。在设置里去配置下GOPROXY之类的。
goland里使用github上的包的话直接写在import里,goland会提示红色,鼠标悬停在上面根据提示按键按下就会自动go get