使用modules依赖管理的好处是非常明显的:
- 自动下载依赖包
- 不需要将代码再放入$GOPATH/src
- 所有来自第三方的包都会指定版本(使用dep是无法指定第三方包的版本的)
- 对于已经转移的包,可以用replace在go.mod文件中替换,不需要修改代码
如何使用Modules
- 把 golang 升级到 1.11+ (现在已经到1.19了)
- 设置
GO111MODULE
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。
注:使用go modules最好搭配go proxy一起使用,否则在go get一些包时会出现get不到的问题
go.mod
go mod命令
| 命令 | 说明 |
|---|---|
| download | download modules to local cache(下载依赖包到本地缓存) |
| edit | edit go.mod from tools or scripts (编辑go.mod) |
| graph | print module requirement graph (打印模块依赖图) |
| init | initialize new module in current directory (在当前目录初始化go.mod) |
| tidy | add missing and remove unused modules(拉取缺少的模块,移除不用的模块) |
| vendor | make vendored copy of dependencies(将依赖复制到vendor下) |
| verify | verify dependencies have expected content (验证依赖是否正确) |
| why | explain why packages or modules are needed(解释为什么需要依赖) |
通常在项目中我们通过go get或者是go install的方式拉取指定版本的依赖包: 执行 go get命令,在下载依赖包的同时还可以指定依赖包的版本
- 运行
go get -u命令会将项目中的包升级到最新的次要版本或者修订版本 - 运行
go get -u=patch命令会将项目中的包升级到最新的修订版本 - 运行
go get [包名]@[版本号]命令会下载对应包的指定版本或者将对应包升级到指定的版本
当然我们也可以先不go get,在最后go run main.go时,go.mod同样会自动查找依赖自动下载
go.mod关键字
| 命令字 | 作用 |
|---|---|
| module | 指定包的名字(路径) |
| require | 指定依赖项模块 |
| replace | 替换依赖项模块 |
| exclude | 忽略依赖项模块 |
进入go.mod文件中,基本都是这样的结构
注:
indirect 表示这个库是间接引用进来的
go.sum
相较于go.mod,go.sum看上去就像是天书,可读性实在是太低,但是我们日常开发仍不得不要跟其打交道(通常是解决这个文件带来的合并冲突,或是想手动调整其中的内容)。
先下一个粗浅定义:go.sum就是依据hash来检测下载下来的依赖,是不是和该版本依赖复合
go.sum格式
go.sum的内容格式基本上是如图所示
go.sum的每一行都是一个条目,大致是这样的格式
xml
代码解读
复制代码
<module> <version>/go.mod <hash>
或者
xml
代码解读
复制代码
<module> <version> <hash>
<module> <version>/go.mod <hash>
其中module是依赖的路径, version是依赖的版本号,hash是以h1开头的字符串,表示生成checksum的算法是第一版的hash算法(sha256)