一文搞懂Go语言的最新依赖管理:go mod的使用
2.1 背景
Go 依赖管理的演进经历了以下 3 个阶段:
目前被广泛应用的是 Go Module,整个演进路线主要围绕实现两个目标来迭代发展:
- 不同环境 (项目) 依赖的版本不同;
- 控制依赖库的版本。
2.2 Go 依赖管理的演进
2.2.1 GOPATH
GOPATH 是 Go 语言支持的一个环境变量,是 Go 项目的工作区。其目录有以下 3 个结构 (需要手动创建文件夹):
文件夹
作用
bin
项目编译的二进制文件
pkg
项目编译的中间产物
src
项目源码
- 项目代码直接依赖
src
下的代码; go get
下载最新版本的包到src
目录下。
2.弊端
下面的场景就体现了 GOPATH 的弊端:项目A 和项B 依赖于某一 package 的不同版本 (分别为 Pkg V1
和 Pkg V2
) 。而 src
下只能允许一个版本存在,那项目A 和项B 就无法保证都能编译通过。
在 GOPATH 管理模式下,如果多个项目依赖同一个库,则依赖该库是同一份代码,无法做到不同项目依赖同一个库的不同版本。这显然无法满足实际开发中的项目依赖需求,为了解决这个问题,Go Vendor 出现了。
2.2.2 Go Vendor
- 与 GOPATH 不同之处在于项目目录下增加了
vendor
文件,所有依赖包以副本形式放在$ProjectRoot/vendor
下。 - 在 Vendor 机制下,如果当前项目存在 Vendor 目录,会优先使用该目录下的依赖;如果依赖不存在,则会从 GOPATH 中寻找。这样,通过每个项目引入一份依赖的副本,解决了多个项目需要同一个 package 依赖的冲突问题。
2.弊端
但 Vendor 无法很好解决依赖包版本变动问题和一个项目依赖同一个包的不同版本的问题。
如图项目A 依赖 Package B 和 Package C,而 Package B 和 Package C 又依赖了 Package D 的不同版本。通过 Vendor 的管理模式不能很好地控制对于 Package D 的依赖版本。一旦更新项目,有可能出现依赖冲突,导致编译出错。归根到底: Vendor 不能很清晰地标识依赖的版本概念。
2.2.3 Go Module
- Go Module 是 Go 语言官方推出的依赖管理系统,解决了之前依赖管理系统存在的诸如无法依赖同一个库的多个版本等问题。
- Go Module 自 Go1.11 开始引入,Go 1.16 默认开启。可以在项目目录下看到
go.mod
文件:
名称
作用
go.mod
文件,管理依赖包版本
go get
/ go mod
指令,管理依赖包
【终极目标】定义版本规则和管理项目依赖关系。和 Java 中的 Maven 作用是一样的。
2.3 Go Module实践
2.3.1 依赖管理三要素
要素
对于工具
配置文件,描述依赖
go.mod
中心仓库管理依赖库
Proxy
本地工具