依赖管理
Go的依赖管理主要分为3种:GOPATH、Go Vendor、Go Module,其中Go Module最为常用。
出现3种主要目的是围绕2个方面:不同项目依赖的版本不同、控制依赖库的版本。
GO PATH
GOPATH是Go支持的一个环境变量,他是Go项目的工作区,有三个关键点:
- bin 项目编译的二进制文件
- pkg 项目编译的中间产物,加速编译
- src 项目源码
GOPATH依赖指的是项目代码直接依赖src下的代码,通过go get下载最新版本的依赖包到src目录下。
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文件配置:
go
复制代码
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
shell
复制代码
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解释为什么需要依赖