后端 go mod day3 | 青训营笔记

83 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天

Go语言包依赖发展阶段:

GOPATH: 安装时需要指定的go语言工作区

  • bin : 项目编译出的二进制文件
  • pkg : 项目编译的中间产物, 加速编译
  • src : 项目源码

缺点: 无法解决多版本依赖问题

Vendor: 在项目目录下添加vendor文件夹, 将所有依赖包按项目组织, 类似于node_modules 缺点: 依然无法解决多依赖, PackageB依赖PackageD的v1版本, PackageC依赖PackageD的v2版本, 此时会出现依赖冲突

Go Module 当前的解决方案, go 1.11 引入

  • 通过 go.mod 文件管理依赖包版本
  • 通过 go get/go mod 指令管理依赖包 依赖管理三要素
  1. 配置文件, 描述依赖 go.mod
  2. 中心仓库管理依赖库 proxy
  3. 本地工具 go get/mod

以一个具体的go.mod文件为例

module example/project/app // 模块名, 每个模块作为依赖管理的基本单元

go 1.16  // 使用go的版本

require (
	example/lib1 v1.0.2
	// 每个依赖由 module name + version code 组成, 如果是间接依赖会用 indirect 标识.
)

版本号规则

  • 语义化版本 ${Major}.${Minor}.${Patch} 基于git tag功能发版, Major代表一个大的版本更新, 不同大版本前后直接可能不兼容, Minor为小版本, 代表不同版本间的迭代, Patch为提交版本, 既每次提交打包会在流水线上自增一个新版本. 由于大版本直接可能不兼容, 第一个大版本后面的版本的代码路径会添加当前的版本号, 比如my/pkg/xxx => my/pkg/v2/xxx
  • 基于commit伪版本 vx.0.0-yyyymmddhhmmss-abcdefgh1234 对于没有语义化版本的库, go自动为每个提交生成一个版本, 规则为语义化版本+提交时间戳+提交id

为了解决代码仓库(github)上的代码不稳定的问题(被修改, 代码被删除等等), 提出proxy机制, 通过定义GOPROXY环境变量设置, 在拉取代码前, 会首先通过proxy网站获取. proxy网站就类似于java中的maven central或npm的npm registry, 但不是中心化的, 用户需要自己选用proxy网站.

同时本地使用go.sum文件, 保存依赖项目的hash值, 避免依赖项目在版本号不变的情况下变更, 导致编译失败.

go.mod 如何解决依赖冲突? 最大版本选择规则. 既对相同项目出现多个不同版本的依赖时(深度优先遍历扫描所有依赖), 选择同一大版本下最高的次版本. go mod 的依赖源码会保存在$GOPATH/pkg/mod目录下, 并会针对同一项目的不同版本号分别存错