Go Modules介绍
Go Modules官方介绍:https://github.com/golang/go/wiki/Modules#semantic-import-versioning
Go Modules是Go语言中正式官宣的项目依赖解决方案,Go modules(前身vgo)于Go1.11版本正式发布,在Go1.14版本以后建议用在生产上,Go官方也鼓励用户从其他依赖管理工具迁移到Go modules

Go Modules使用
Go modules使用的前提是Go JDK版本必须在1.11及以上版本,最好是1.13或以上
一、 Go modules相关的命令
go help mod我们可以看到go mod的使用及参数

go mod参数命令
go mod download 下载 go.mod 文件中指明的所有依赖
go mod edit 编辑 go.mod 文件
go mod graph 查看现有的依赖结构
go mod init 生成 go.mod 文件
go mod tidy 整理现有的依赖,无用的依赖包会被删除,没有的依赖会自动下载
go mod vendor 导出项目所有的依赖到vendor目录
go mod verify 校验一个模块是否被篡改过
go mod why 查看为什么需要依赖某模块
其他相关的指令
go list -m all 查看直接或间接依赖的模块的最终版本信息
go list -u -m all 查看直接或间接依赖的模块及可升级的模块
Go modules相关的环境变量
> go env
GO111MODULE="auto"
GOPROXY="https://proxy.golang.org,direct"
GONOPROXY=""
GOSUMDB="sum.golang.org"
GONOSUMDB=""
GOPRIVATE=""
......
GO111MODULE
Go语言提供了 GO111MODULE 这个环境变量来作为 Go modules 的开关,其允许设置以下参数:
auto:只要项目包含了 go.mod 文件的话启用 Go modules,目前在 Go1.11 至 Go1.14 中仍然是默认值。
on:启用 Go modules,推荐设置,将会是未来版本中的默认值。
off:禁用 Go modules,不推荐设置。
注:GO111MODULE 这个命名代表着Go语言在 1.11 版本添加的,针对 Module 的变量,属于过渡变量,以后的版本可能会把111去掉。
GOPROXY
这个环境变量主要是用于设置 Go 模块代理(Go module proxy),其作用是用于使 Go 在后续拉取模块版本时能够脱离传统的 VCS 方式,直接通过镜像站点来快速拉取。
GOPROXY 的默认值是:https://proxy.golang.org,direct,这有一个很严重的问题,就是 proxy.golang.org 在国内是无法访问的,因此这会直接卡住你的第一步,所以你必须在开启 Go modules 的时,同时设置国内的 Go 模块代理
目前国内支持Go Modules代理仓库比较好的有:
阿里的:https://mirrors.aliyun.com/goproxy/
设置国内Go Modules代理
go env -w GOPROXY=https://goproxy.cn,direct
go env会持久化所设置的环境变量,通过go env设置的环境变量会保存在一个env文件中,windows保存的路径是:用户目录\AppData\Roaming\go\env , linux保存的路径是:用户home目录下的 ./config/go/env 。 (如linux root用户的目录为/root/.config/go/env)。
GOPROXY允许设置多个代理,多个代理之间用逗号分隔,如果你想禁用Go模块代理可以将其设置为”off”。
direct 是一个特殊的指示符,用于指示Go回源到模块版本的源地址去抓取(比如GitHub等)
GOSUMDB
它的值是一个 Go checksum database,用于在拉取模块版本时(无论是从源站拉取还是通过 Go module proxy 拉取)保证拉取到的模块版本数据未经过篡改,若发现不一致,也就是可能存在篡改,将会立即中止。
GOSUMDB 的默认值为:sum.golang.org,在国内也是无法访问的,但是 GOSUMDB 可以被 Go 模块代理所代理。因此我们可以通过设置 GOPROXY 来解决,而先前我们所设置的模块代理 goproxy.cn 就能支持代理 sum.golang.org。如果想要禁止Go在后续操作中校验模块版本,则可以将其设置为 off
GONOPROXY/GONOSUMDB/GOPRIVATE
这三个环境变量都是用在当前项目依赖了私有模块,例如像是你公司的私有 git 仓库,又或是 github 中的私有库,都是属于私有模块,都是要进行设置的,否则会拉取失败。
而一般建议直接设置 GOPRIVATE,它的值将作为 GONOPROXY 和 GONOSUMDB 的默认值,所以建议的最佳姿势是直接使用 GOPRIVATE。多个值可以用逗号分隔
例如:
go env -w GOPRIVATE=”git.myself.com,github.com/myself/project”
也可以通过通配符进行模糊匹配
go env -w GOPRIVATE="*.myself.com"
二、开启 Go Modules
目前 Go modules 并不是默认开启,因此Go语言提供了 GO111MODULE 这个环境变量来作为 Go modules 的开关,其允许设置以下参数:
- auto:只要项目包含了 go.mod 文件的话启用 Go modules,目前在Go1.11至 Go1.14 中仍然是默认值。
- on:启用 Go modules,推荐设置,将会是未来版本中的默认值。
- off:禁用 Go modules,不推荐设置。
go env 可以查看当前GO111MODULE变量的值
设置GO111MODULE环境变量的值
go env -w GO111MODULE=auto/on/off
linux系统也可通过 export设置系统环境变量
export GO111MODULE=auto/on/off
windows系统可以通过set 设置环境变量(暂时的,非持久化)
set GO111MODULE=auto/on/off
三、Go Modules使用示例
先检查GO111MODULE和GOPROXY变量是否已经设置
1. 新建项目gomodtest
main.go
main.go
package main
import (
"github.com/sirupsen/logrus"
)
func main() {
logrus.Info("hello mod")
}
该项目用了一个常用的日志框架logrus,并打印”hello mod”
2.初始化go mod
> go mod init
go: creating new go.mod: module gomodtest
会生成go.mod文件,文件内容如下:
module gomodtest
go 1.13
3.下载第三方包
> go get -u ./...
更新直接或间接的依赖包
go: finding github.com/sirupsen/logrus v1.6.0
go: downloading github.com/sirupsen/logrus v1.6.0
go: extracting github.com/sirupsen/logrus v1.6.0
go: downloading github.com/konsorten/go-windows-terminal-sequences v1.0.3
go: downloading golang.org/x/sys v0.0.0-20190422165155-953cdadca894
go: extracting github.com/konsorten/go-windows-terminal-sequences v1.0.3
go: extracting golang.org/x/sys v0.0.0-20190422165155-953cdadca894
go: finding github.com/konsorten/go-windows-terminal-sequences v1.0.3
下载所需的依赖包之后,go.mod文件中会新增如下内容
require github.com/sirupsen/logrus v1.6.0
并且生成了go.sum文件
下载的依赖包会缓存到第一个$GOPATH/pkg/mod 和 $GOPATH/pkg/sumdb目录中
注:go get未指定版本号,则默认下载最新的版本
注:这里为什么使用go get,而不用go mod download或go mod tidy。go get会直接更新或拉取对应的依赖模块,并将更新的模块同步到到go.mod和go.sum文件中。而go mod download是根据go.mod的内容来更新对应的模块。
4.go mod vendor
> go mod vendor
导出项目所有的依赖到vendor目录,此时该项目会生成vendor目录,并将所需的依赖包复制到该vendor目录下。
此时程序即可正常运行,运行结果如下:
time="2020-07-15T15:56:34+08:00" level=info msg="hello mod"
四、go.mod文件
一个常用的go.mod结构如下:
module github.com/eddycjy/module-repo
go 1.13
require (
example.com/apple v0.1.2
example.com/banana v1.2.3
example.com/banana/v2 v2.3.4
example.com/pear // indirect
example.com/strawberry // incompatible
)
exclude example.com/banana v1.2.4
replace example.com/apple v0.1.2 => example.com/fried v0.1.0
replace example.com/banana => example.com/fish
module:用于定义当前项目的模块路径。
go:用于标识当前模块的 Go 语言版本,值为初始化模块时的版本,目前来看还只是个标识作用。
require:用于设置一个特定的模块版本。
exclude:用于从使用中排除一个特定的模块版本。
replace:用于将一个模块版本替换为另外一个模块版本。
另外你会发现 example.com/pear 的后面会有一个 indirect 标识,indirect 标识表示该模块为间接依赖,也就是在当前应用程序中的 import 语句中,并没有发现这个模块的明确引用。
五、Go Modules下的go get
在拉取项目依赖时,你会发现拉取的过程总共分为了三大步,分别是 finding(发现)、downloading(下载)以及 extracting(提取)。
go get 的拉取行为
刚刚我们用 go get 命令拉取了新的依赖,那么 go get 又提供了哪些功能呢,常用的拉取命令如下:
| 命令 | 作用 |
| go get | 更新直接的模块依赖 |
| go get -u | 更新直接或间接的依赖模块 |
| go get -u -t ./... | 更新所有直接依赖和间接依赖的模块版本,包括单元测试中用到的。 |
go get 拉取指定版本
| 命令 | 作用 |
| go get golang.org/x/text@latest | 拉取最新的版本,若存在tag,则优先使用。 |
| go get golang.org/x/text@master | 拉取 master 分支的最新 commit。 |
| go get golang.org/x/text@v0.3.2 | 拉取 tag 为 v0.3.2 的 commit。 |
| go get golang.org/x/text@342b2e | 拉取 hash 为 342b231 的 commit,最终会被转换为 v0.3.2。 |
感谢:
https://blog.youkuaiyun.com/RA681t58CJxsgCkJ31/article/details/104568182
1147



被折叠的 条评论
为什么被折叠?



