Go 最初使用 GOPATH
模式管理第三方扩展包。但是,项目使用的第三方包多了,依然使用这种方式一个个下载,则显得太过麻烦。随后在 golang 1.5
引入了 vendor
机制。但是,依然需要将文件下载到本地项目中的 vendor
目录中。所以在 go 1.11 版本后推出了 go module
功能,go module 只需要在本地保存 go.mod 文件以及用作校验的 go.sum 文件即可。
go module 目前尚在初期阶段,还需要完善。例如,之前发布的 go 1.13 版本中。对 go module 进行了优化。
在环境变量中提供了 GO111MODULE
选项,该选项默认为 auto
,当项目中有 go.mod
文件,则使用 go module。否则,使用 GOPATH
或 vendor
方式作为包管理。如果不想使用 GOPATH
,则可将其设置为 on
。只使用 go module
。
在 Golang 1.12 版本之前,如果需要引入 Go modules 需要设置 Go env 中的 GO111MODULES 控制项目使用那种包管理方式:
在 Golang 中可以使用 go mod 子命令对依赖进行管理,可使用 go mod 查看支持的选项,如下图:
具体解释一下,虽然我的英语也很渣,但是勉勉强强还是能看得懂一点。
新建项目时只需要创建一个文件夹。值得注意的是,这里不需要新建 src
pkg
等文件夹。只需要在新建的项目文件夹下,命令行中执行 go mod init
初始化引入 go mod。具体命令如下:
go mod init [module name]
例如,这里创建一个 test
项目:
go mod init test
执行上面的命令会在目录下生成一个 go.mod 文件,其中主要记录了项目所需的包。如下:
可以看到在目录下创建了 go.mod
文件,其中便是引用的依赖包。
module 就是你这个项目的名称,在使用 go mod init
指定的。
包含的所有当前 module 中依赖的包名以及版本号
主要作用就是解决某些包名改变的问题,当然也可以替换某些你不能下载的包。例如,golang/x/net 包在国内无法下载,但是在 github 中有这个项目。就可以使用 replace 将其替换为 github 的地址。如:
replace golang.org/x/net v0.0.0-20180906233101-161cd47e91fd => github.com/golang/net v0.0.0-20180906233101-161cd47e91fd
但是,这里不推荐使用这种做法。因为,了解 golang 依赖的朋友都知道,你替换的这个包里面也可能依赖其他的包,那你就需要一个一个这样替换下去。非常的麻烦。
如果需要添加一个依赖包,可以通过编辑 go.mod 文件在文件中添加你需要的包,但是这个时候你不能使用 go mod tidy
获取项目,你需要使用 go mod download
因为这个时候你的项目中通常还没有引用新加入包。使用 go mod tidy
会直接移除你添加的内容。
值得注意的是,在 Go MODULES 的包管理方式中,赋予了 go get 新的使命。以前使用 GOPATH
或者 Vendor
方式管理依赖的时候,go get 就是将依赖拉取到本地。但是在 GO MODULES 中 go get 兼职了包个升降级的功能。具体的使用方式如下:
go get package@version
这个的话可以让你指定你需要的依赖包的版本。
需要注意的是,如果你没有指定 @version
的情况下,会默认下载打了 tag 的 release
版本;如果没有 release 版本,则会下载最新的 pro release
版本。如果这个也没有的话,则会下载最近一次的 commit
。
从这里就可以看到,一定要按照规范来命名我们的 package
的 tag
。否则 modules 将无法管理这个 package。 version 的格式为 `v(major).(minor).(patch),更多详细内容可以参考 https://semver.org/
由于一些不能说的原因,有些包在国内无法直接拉取的。例如,go 的 net
包。为了解决这个问题,就可以通过设置 GOPROXY
环境变量指定一个代理地址,通过这个地址拉取代码。
在 1.13 之前,没有推出国内的代理地址。需要配置 http_proxy
和 https_proxy
两个环境变量翻出去拉代码,非常麻烦。于是在 1.13 提供了一个新的代理地址 goproxy.cn
这个是由 七牛云
提供的一个代理服务器。只需要将 GOPROXY
设置为这个地址即可正常拉取代码。
同时,你也可以实现自己的 GOPROXY 服务,只需要你实现了 module proxy protocol
协议即可。
Go modules 在 1.13 版本下时默认开启的。
主要的作用就是标示出那些 package 是 private 的,对于 private 的包将不会从 proxy 中下载。值以是一个以逗号分割的列表,支持正则表达式,可以参照 Go 的path.Match 包。
详细 GOPRIVATE 的配置示例参照下面的内容
GOPRIVATE=*/common,leor.com.cn/utils/*
上面的例子中任何以 common
结尾,或者以 leor.com.cn/utils
开头的包都被标识为 private 的。
GOSUMDB 的全称为 Go CheckSum Database,主要用来对下载的包进行安全性校验。包的安全性在使用 GOPROXY 之后更容易出现,对于这种情况可以通过 GOSUMDB 对包的 hash 值进行校验。如果想关闭校验,则可以将 GOSUMDB 设置为 off;如果只对部分的包取消校验,则可以参照 GOPRIVATE 的设置方式。将包的前缀设置到 GOSUMDB 中。具体格式如下:
GOSUMDB="sum.golang.org"
GOSUMDB="sum.golang.org+"
GOSUMDB="sum.golang.org+ https://sum.golang.org"
以上三种配置都是合法的,对于 sum.golang.org
Go 本身知道它的 publickey
与 url
,所以只需要配置一个名称即可。第二个也是一样的。除此之外其他的包都需要同时指定包名、publickey以及url。url 默认是 https://
更多关于 GOSUMDB 的详细信息也可以参考 : https://golang.org/cmd/go/#hdr-Module_authentication_failures