这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天
课堂笔记
本堂课重点内容
- 依赖管理的重要性
- 如何进行依赖管理
详细知识点介绍
依赖管理
背景
- 工程项目不可能基于标准库0-1编码搭建
- 管理依赖库
Go依赖管理演进
- 不同环境(项目)依赖的版本不同
- 控制依赖库的版本
- GOPATH->Go Vendor->Go Module
GOPATH
- 环境变量GOPATH
- 项目代码直接依赖src下的代码
- go get下载最新版本的包到src目录下
弊端
场景
- A和B依赖于某一package的不同版本
问题
- 无法实现package的多版本控制
Go Vendor
- 项目目录下增加vendor文件,所有依赖包副本形式放在ProjectRoot/vendor
- 依赖寻址方式vendor=>GOPATH
- 通过每个项目引入一份依赖副本,解决了多个项目需要同一个package依赖的冲突问题
弊端
- 无法控制依赖的版本
- 更新项目可能出现依赖冲突,导致编译出错
Go Module
- 通过go.mod文件管理依赖包版本
- 通过go get/go mod指令工具管理依赖包
终极目标
- 定义版本规则和管理项目依赖关系
依赖管理三要素
- 配置文件,描述依赖 -> go.mod
- 中心仓库管理依赖库 -> Proxy
- 本地工具 -> go get/mod
依赖配置
go.mod
依赖管理基本单元
- module example/project/app
原生库
- go 1.16
单元依赖
require( example/lib1 v1.0.2
example/lib2 v1.0.0 /indirect
examp1e/Lib3v0.1.0-20190725025543-5a5fe074e612
example/lib4 v0.0.0-20180306012644-bacd9c7ef1dd /indirect
example/lib5/v3v3.0.2
example/lib6 v3.2.0+incompatible
)
version
语义化版本
{MAJOR}.{MINOR}.[PATCH}
大版本(可以不兼容).新增函数或功能(前后兼容).代码bug的修复
V1.3.0 V2.3.0
基于commit伪版本
vX.0.0-yyyymmddhhmmss-abcdefgh1234
v大版本<主版本>(可以不兼容).新增函数或功能(前后兼容).代码bug的修复-发行时间戳-12位哈希码前缀
v0.0.0-20220401081311-c38fb59326b7 v1.0.0-20201130134442-10cb98267c6c
indirect
依赖关系->非直接依赖
A依赖于B,B依赖于C
A间接依赖于C->非直接依赖,标记为// indirect
incompatible
依赖关系->直接依赖
A依赖于B->直接依赖,标记为+incompatible
- 主版本2+的模块会在模块路径增加/vN的后缀
- 对于没有go.mod版本并且主版本2+的依赖,会+incompatible
依赖分发
回源
可以直接引用代码托管平台github等来进行依赖分发
无法保证构建稳定性
- 增加/修改/删除软件版本
无法保证依赖可用性
- 删除软件
增加第三方压力
- 代码托管平台负载问题
Proxy
- 一个服务站点
- 缓存源站中的软件内容
- 缓存的软件版本不会改变
变量GOPROXY
GOPROXY="proxy1.cn,https://proxy2.cn,…"
服务站点URL列表,“direct”表示源站
Proxy1-->Proxy2-->Direct
工具-go get
go get example.org/pkg
- @upadte 拉取最新的(默认)
- @none 删除依赖
- @v1.12 tag版本,语义版本
- @23dfdd5 特定的commit
- @master 分支的最新commit
实践练习例子
依赖图
如果X项目依赖了A、B两个项目,且A、B分别依赖了C项目的v1.3、v1.4两个版本,最终编译时所使用的C项目的版本为如下哪个选项?(B)
选择最低兼容的版本
A.V1.3
B,v1.4
C,A用到c时用V1,3编译,B用到c时用v1.4编译
课后个人总结
- 对于依赖的管理非常重要,一不小心就会导致项目出错
- 依赖管理中使用的工具在循序渐进,最新使用的工具为go.mod进行依赖管理