go modules 是 golang 1.11 新加的特性。
模块是相关Go包的集合。modules是源代码交换和版本控制的单元。 go命令直接支持使用modules,包括记录和解析对其他模块的依赖性。modules替换旧的基于GOPATH的方法来指定在给定构建中使用哪些源文件。
GO111MODULE
GO111MODULE 有三个值:off, on和auto(默认值)。
GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:
- 当前目录在GOPATH/src之外且该目录包含go.mod文件
- 当前文件在包含go.mod文件的目录下面。
当modules功能启用时,依赖包的存放位置变更为$GOPATH/pkg,允许同一个package多个版本并存,且多个项目可以共享缓存的 module
利用GO111MODULE和GOPROXY,可以直接将Github上的第三方库直接下载到本地使用,不需要使用go get命令。执行 go run 运行时,GOMODULES包管理工具会自动帮我们下载github上面的包
使用 go mod 创建新项目
1、初始化项目
mkdir maze-go
cd maza-go
go mod init maze-go
在项目根目录生成 go.mod 文件
module maze-go
go 1.17
go.mod文件一旦创建后,它的内容将会被go toolchain全面掌控。go toolchain会在各类命令执行时,比如go get、go build、go mod等修改和维护go.mod文件。
go.mod 提供了module, require、replace和exclude 四个命令
- module 语句指定包的名字(路径)
- require 语句指定的依赖项模块
- replace 语句可以替换依赖项模块
- exclude 语句可以忽略依赖项模块
2、添加依赖
新建main.go文件
执行 go run main.go
一般来说 go mod 模式下,运行go run 会自动安装所有依赖,但是没有安装
运行 go get ./ … 可以自动查找并下载所有的包
添加完包后,可以通过使用 go list -m all 查看当前模块所依赖的包列表。
在go.mod所在根目录下,除了维护go.mod文件外,还有一个go.sum文件。go.sum文件是对导入的依赖包的特定版本的hash校验值,作用就是确保将来下载的依赖包版本和第一次下载到的依赖版的版本号相同,以防止在将来有版本号升级后 程序不兼容的问题。所以,go.mod和go.sum文件都需要被加入版本管理中。
流程总结
- go mod init 创建一个新模块,初始化go.mod文件
- go 1.16版本之前,go build, go test以及其他包构建命令 自动查找并下载依赖包并将依赖添加到go.mod中,go 1.16及其以后,go command不再自动下载不在go.mod中的依赖,而是需要通过go get 命令手动下载
- go list -m all 打印出当前模块直接依赖的列表
- go get 升级依赖或添加新依赖。其中go get只能升级次版本。主版本的升级需要按主版本规则import后,再 go get package@version
- go mod tidy 从go.mod中移除不需要的依赖
- go 1.17计划移除GOPATH模式,建议尽快将非module-aware模式的老项目迁移到module-aware模式