Go语言入门-Go Module | 青训营

68 阅读3分钟

2.3 go module

2.3.1 依赖配置 - go.mod

模块路径用来标识一个模块,从模块路径可以看出从哪里找到该模块,如果是github前缀则表示可以从github仓库中找到该模块,依赖包的源代码则由github托管,如果项目的子包想被单独引用,则需要通过单独的init go.mod文件进行管理。依赖配置模块分为依赖管理基本单元、原生库和单元依赖。
依赖标识 : [Module Path] [Version/Pseudo-version]

2.3.2 依赖配置 - version

GOPATH和Go Vendor都是源码副本方式依赖,没有版本规则概念,而go module为了方便管理则定义了版本规则,分为语义化版本和基于commit伪版本。其中语义化版本包括:${MAJOR}.${MINOR}.${PATCH},不同的MAJOR版本表示是不兼容的API,所以即使是同一个库,MAJOR版本不同也会被认为是不同的模块;MINOR版本通常是新增函数或功能,向后兼容;而PATCH版本版本一般是修复bug;
而基于commit的伪版本包括:vx.0.0-yyyymmddhhmmss-abcdefgh1234,基础版本前缀是和语义化版本一样的;时间戳(yyyymmddhhmmss),也就是提交commit的时间,最后是校验码(abcdefgh1234),包含12位的哈希前缀;每次提交commit后Go都会默认生成一个伪版本号。

2.3.3 依赖配置 - indirect

indirect后缀是依赖单元中的特殊标识符,表示go.mod对应的当前模块,没有直接导入该依赖模块的包,也就是非直接依赖,标示间接依赖。

2.3.4 依赖配置 - incompatible

incompatible也很常见,主版本2+模块模块会在模块路径增加/vN后缀,这能让go module按照不同的模块来处理同一个项目不同主版本的依赖。还有一种是对于没有go.mod文件并且主版本2+的依赖,会在版本号后加上+incompatible后缀。

2.3.5 依赖分发 - 回源

github是比较常见给的代码托管系统平台,而Go Module系统中定义的依赖,最终可以对应到多版本代码管理系统中某一项目的特定提交或版本,这样的话,对于go.mod中定义的依赖,则直接可以从对应仓库中下载指定软件依赖,从而完成依赖分发。
但直接使用版本管理仓库下载依赖,存在多个问题,首先无法保证构建确定性:软件作者可以直接代码平台增加/修改/删除软件版本,导致下次构建使用另外版本的依赖,或者找不到依赖版本。无法保证依赖可用性:依赖软件作者可以直接代码平台删除软件,导致依赖不可用;大幅增加第三方代码托管平台压力。

2.3.6 依赖分发 - Proxy

而go proxy就是解决这些问题的方案,Go Proxy是一个服务站点, 它会缓源站中的软件内容,缓存的软件版本不会改变,并且在源站软件删除之后依然可用,从而实现了供"immutability和"avilable"的依赖分发:使用Go Proxy之后,构建时会直接从Go Proxy站点拉取依赖。