Go是一个开放的态度下新生的语言,并没有其他语言那样官方维护一个中心库,Go的库大多数都是直接github上的。当然因此Go的包管理发展也比较曲折。 像python的项目根目录有requirement.txt记录依赖包,nodejs是packages.json,同样go的包管理从早期的go dep(gopkg)到vendor到现在的go mod。我简单介绍目前常用的也是官方默认的go mod。
go mod是什么
Go.mod是Golang1.11版本新引入的官方包管理工具用于解决之前没有地方记录依赖包具体版本的问题,方便依赖包的管理。并且从 Go1.13 版本开始,go module 成为了Go语言默认的依赖管理工具。
Modules 官方定义为:
dules 是相关 Go 包的集合,是源代码交换和版本控制的单元。Go语言命令直接支持使用 Modules,包括记录和解析对其他模块的依赖性,Modules 替换旧的基于 GOPATH 的方法,来指定使用哪些源文件。
go mod命令
命令 | 说明 |
---|---|
go mod download | 下载依赖包到本地(默认为 GOPATH/pkg/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 mod
使用前提:首先将go的版本升级为1.11以上,并设置 GO111MODULE。
GO111MODULE
GO111MODULE有三个值:off, on和auto(默认值)。
-
GO111MODULE=off,go命令行将会不支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
-
GO111MODULE=on,只会使用go module的方式寻找依赖包。
-
GO111MODULE=auto,默认值,在gopath路径下会从gopath 或者vendor中寻找依赖包,在外部会使用go module的方式寻找依赖包。
GO PROXY
go module 的目的是依赖管理,所以使用 go module 时你可以舍弃 go get 命令(但是不是禁止使用, 如果要指定包的版本或更新包可使用go get,平时没有必要使用),因go的网络问题, 所以推荐使用 goproxy.cn设置.
// 阿里云镜像
GOPROXY=https://mirrors.aliyun.com/goproxy/
// 中国golang镜像
GOPROXY=https://goproxy.io
// 七牛云为中国的gopher提供了一个免费合法的代理goproxy.cn,其已经开源。只需一条简单命令就可以使用该代理:
go env -w GOPROXY=https://goproxy.cn,direct
初始化项目
项目第一次使用go module(没有go.mod文件) 需要初始化,在当前目录下,命令行运行 go mod init + 模块名称 初始化模块
go mod init test(test为项目名)
运行完之后,会在当前目录下生成一个go.mod文件,这是一个关键文件,之后的包的管理都是通过这个文件管理。
go.mod文件一旦创建后,它的内容将会被go toolchain全面掌控。go toolchain会在各类命令执行时,比如go get、go build、go mod等修改和维护go.mod文件。
go.mod文件 提供了module, require、replace和exclude四个命令
- module语句指定包的名字(路径)
- require语句指定的依赖项模块
- replace语句可以替换依赖项模块
- exclude语句可以忽略依赖项模块
检测依赖
go mod tidy
tidy会检测该文件夹目录下所有引入的依赖,写入 go.mod 文件。写入后你会发现 go.mod 文件有所变动,引入的包依赖以及版本信息被写入到了go.mod文件中,但是,此时依赖还是没有下载的。
下载依赖
go mod download
我们需要将依赖下载至本地,而不是使用 go get。 如果你没有设置 GOPROXY 为国内镜像,这步会卡到死。
此时会将依赖全部下载至 GOPATH 下,会在根目录下生成 go.sum 文件, 该文件是依赖的详细依赖, 但是我们开头说了,我们的项目是没有放到 GOPATH 下的,那么我们下载至 GOPATH 下是无用的,照样找不到这些包。
导入依赖
go mod vendor
执行此命令,会将刚才下载至 GOPATH 下的依赖转移至该项目根目录下的 vendor(自动新建) 文件夹下, 此时我们就可以使用这些依赖了
运行
执行 go run server.go 运行代码会发现 go mod 会自动查找依赖自动下载依赖并把依赖内容写入go.mod 文件。
由于某些已知的原因,并不是所有的package都能成功下载。
modules 可以通过在 go.mod 文件中使用 replace 指令替换成github上对应的库,比如:
replace (
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a => github.com/golang/crypto v0.0.0-20190313024323-a1f597ede03a
)