背景 依赖指各种开发包,在开发项目时,要学会站在巨人的肩膀上,也就是利用已经封装好的、经过验证的开发组件或开发工具来提升研发的效率。
在实际工程中,项目一般比较复杂,我们不可能基于标准库0-1编码搭建,而更多的是考虑业务逻辑的实现,像其他的涉及框架、日志、driver、以及 collection 等一系列依赖都会通过 sdk 的方式引入,因此对依赖包的管理就显得尤为重要。
Go 依赖管理演进 Go 的依赖管理主要经历了三个阶段,如下图所示,目前应用最广泛的是 Go Module,整个演进路线主要围绕实现两个目标:
不同环境(项目)依赖的版本不同
控制依赖库的版本
GOPATH GOPATH 是 Go 语言支持的一个环境变量,工作区目录有以下结构:
src:存放项目源码
pkg:存放编译的中间产物,加快编译速度
bin:存放编译生成的二进制文件
存在的问题:如果多个项目依赖同一个库,则依赖该库是同一份代码,所以不同的项目不能依赖同一个库的不同版本,简单来说就是无法实现库的多版本控制。
Go Vendor 项目目录下增加 vendor 文件,所有依赖包的副本存放在里面。通过每个项目引入一份依赖的副本,解决了多个项目需要同一个 package 依赖的冲突问题。
存在的问题:
无法控制依赖的版本
更新项目又可能出现依赖冲突,导致编译出错
Go Module Go Module 是 Go 语言推出的依赖管理系统,解决了之前存在的问题。
通过 go.mod 文件管理依赖包版本
通过 go get/ go mod 指令工具管理依赖包
Go Module 实践 依赖管理三要素 配置文件,描述依赖 go.mod
中心仓库管理依赖库 Proxy
本地工具 go get/mod
依赖配置 go.mod:配置文件,描述依赖
version:分为语义化版本和基于 commit 伪版本
indirect:indirect 后缀表示 go.mod 对应的当前模块属于间接依赖
incompatible:让 go Module 按照不同的模块来处理同一个项目不同主版本的依赖
依赖分发 依赖分发也就是从哪里下载依赖及如何下载。
回源:直接从对应仓库中下载指定软件依赖,但是存在多个问题
无法保证构建稳定性
无法保证依赖可用性
增加第三方压力
Proxy:Go Proxy 是一个服务站点,它会缓存源站中的软件内容,缓存的软件版本不会变,且在源战软件删除后依然可用
工具 go get 使用
go mod