这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天
Go语言依赖管理
Go的依赖管理主要分为3种:GOPATH、Go Vendor、Go Module,其中Go Module最为常用。
GOPATH
GOPATH是Go语言环境变量,是Go项目的工作区:
- bin 项目编译的二进制文件
- pkg 项目编译的中间产物,加速编译
- src 项目源码
GOPATH依赖指的是项目代码直接依赖src下的代码,通过go get下载最新版本的依赖包到src目录下。
弊端
无法实现package的多版本控制。
Go Vendor
Go Vender的出现解决了GOPATH不能多版本控制的麻烦。
Go Vender依赖管理模式在项目目录下增加vendor文件,所有依赖包副本形式放$ProjectRoot/vendor目录下,其依赖寻址方法为vendor=>GOPATH。
Go Vender通过每个项目引入一份依赖的副本方式,解决了多个项目需要同一个package依赖的冲突问题。
弊端
Go Vender存在以下问题:
- 无法控制依赖的版本
- 更新项目又可能出现依赖冲突,导致编译出错。
出现这样问题的原因归根结底还是因为直接依赖的是项目的源码,不能清晰标识版本的概念。
Go Module
Go Module的出现解决了Go Vender出现的问题,可以管理依赖的版本。
Go Module通过go.mod文件管理依赖包的版本,通过go get/go mod指令工具管理依赖包。
Go Module的终极目标为:定义版本规则和管理项目的依赖关系。
依赖管理三要素
依赖管理存在以下三要素:
- 配置文件,描述依赖 go.mode
- 中心仓库管理依赖库 Proxy
- 本地工具 go get/mod
go.mod
go.mod文件配置:
module example/project/app 依赖管理基本单元
go 1.16 原生库
require( 单元依赖
example/lib1 v1.0.2
example/lib2 v1.0.0
example/lib3 v0.1.0-20190725
example/lib4 v0.0.0-20180036
example/lib5/v3 v3.0.2
example/lib6 v3.2.0+incompatible
)
复制代码
依赖标识:[Module Path][Version/Pseudo+version]
module为模块路径,用来标识一个模块,可以根据这个来找到模块,依赖托管的路径。
go为项目依赖原生库的版本号。
require为最关键的一部分,主要是描述单元依赖,主要由两部分组成:Module Path、Version/Pseudo+version。
版本定义
go.mod版本主要有两种类型:语义化版本、基于commit伪版本。
语义化版本 组成形式:${MAJOR}.${MINOR}.${PATCH}
示例:V1.3.0、V2.3.0
基于commit伪版本 组成形式:vx.0.0-yyyymmddhhmmss-abcdefgh1234
示例:v0.0.0-20220401081311-c38fb59326b7、v1.0.0-20201130134442-10cb98267c6c
indirect
如果不是直接依赖的模块,用indirect标识出来。
假如依赖关系为:A->B->C,其中A->B为直接依赖,A->C为间接依赖。
incompatible
在依赖后面加上incompatible,代表代码中可能存在不兼容的问题。
Go在处理版本兼容的问题时,会选择最低的兼容版本。
Proxy
依赖是从哪里下载的呢?
比较常见的是GitHub,GitHub是一个代码托管平台,但是访问的时候可能存在不稳定性的问题,所以使用代码托管平台下载依赖的话会存在以下几个问题:
- 无法保证构建稳定性,可能存在增加、修改、删除软件版本。
- 无法保证依赖可用性,软件被删除
- 增加第三方压力,代码托管平台负载问题
为了解决这些问题,就出现了Proxy这个概念。
Proxy是一个中间站点,他会缓存软件版本的内容,而且缓存的版本不会改变。
通过Proxy可以保证站点的稳定性、可靠性。
Proxy配置
设置环境变量GOPROXY
GOPROXY="https://proxy1.cn,https://proxy2.cn,direct"
可以配置多个url用逗号分隔,direct代表源站。
在获取依赖时,会从前往后依次查找依赖。
go get
使用示例:go get example.org/pkg + 参数
参数示例:
- @update 默认参数
- @none 删除依赖
- @v1.1.2 指定tag版本,语义版本
- @23dfdd5 特定的commit版本
- @master 指定分支的最新commit
附加参数:
- -d 只下载不安装
- -f 只有在你包含了 -u 参数的时候才有效,不验证
- -fix 在获取源码之后先运行 fix,然后再去做其他的事情
- -t 同时也下载需要为运行测试所需要的包
- -u 强制使用网络去更新包和它的依赖包
- -v 显示执行的命令日志信息
go mod
使用示例:go mod + 参数
常用参数如下:
- download 下载依赖的到本地
- edit 编辑go.mod文件
- graph 打印模块依赖图
- init 初始化当前文件夹, 创建go.mod文件
- go mod tidy 拉取缺少的模块,移除不用的模块
- go mod vendor 将依赖复制到vendor下
- go mod verify 验证依赖是否正确
- go mod why 解释为什么需要依赖