这是我参与「第五届青训营 」笔记创作活动的第 4 天
前言
在实际工程开发中,一个重要概念就是依赖管理,本文主要介绍 Go 的依赖管理,包括 Go 依赖管理的演进路线及 Go Module 实践等内容。
重点内容
- 背景
- Go 依赖管理演进
- Go Module 实践
知识点介绍
背景
依赖指各种开发包,在开发项目时,要学会站在巨人的肩膀上,也就是利用已经封装好的、经过验证的开发组件或开发工具来提升研发的效率。
在实际工程中,项目一般比较复杂,我们不可能基于标准库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
总结
本文主要介绍了 Go 依赖管理的相关内容,阐述了 Go 依赖管理的演进路线,对目前最常用的 Go Module 进行了详细的介绍,为后面做大型项目时的依赖管理打下基础。