有过开发经验的人都知道,在大型项目中存在大量代码又是多人开发,如果没有合理的管理方式,就会因为混乱的代码导致项目的开发和维护极其困难。
而常规的管理方式就是:模块、包和版本,从 1.12 开始,Go 有了 Modules 包管理工具。
Go 模块其实就是为了方便管理 Go 代码,也是为了方便不同开发者共享代码,避免重复造轮子。
为了共享和管理,比较重要的就是仓库和模块,仓库表示代码的存储服务,而模块就是一个共享的代码集合。
包是处于同一目录中的一些源代码文件的集合,这些文件将被编译在一起。
可以简单理解为模块内的子目录,虽然不太准确,大概是目录的意思,就是分类整合 Go 代码的管理层级。
包也有路径,并且其全路径就是:模块路径 + 包相对模块的路径
例如模块 devnolo/module 有一个子目录为 dir,一般这个 dir 就是该模块的一个包存在,包含管理了一些列源代码。
模块由一系列已发布、版本化、被分发的包构成。
有一个特殊的模块(main)是指包含了 go 命令的目录所对应的模块。
模块根目录是指包含 go.mod 文件的目录。例如 go.mod 文件在目录 /workspace/project
里,在这个例子里根目录就是 /workspace/project
。
模块路径
模块的唯一标识:模块路径,模块路径在 go.mod 文件中声明。
完整的模块路径包含了两部分:仓库地址 + 模块地址。
例如:“github.com/用户名/项目名” 通过该路径可以定位到代码仓库 ---> https://github.com/用户名/项目名
仓库(repository)是存放模块的服务,就是熟知的代码仓库。
开发者可以共享自己的模块到代码仓库,使用者可以通过代码仓库使用他人共享的模块。
版本(version)指模块的不同时刻的模块快照,开发人员根据可以版本定位到唯一的模块。
意味着只要能确定版本,任何人任何时刻根据这个版本号获取到的模块都是一摸一样的。
一个版本标示着模块的不可变快照,每个版本都以字母 v 开头,后紧跟着语义版本,例如:v2.3.4。
主要版本号
在发布不兼容的公共接口更新后,例如模块里的某个包被删除,必须递增,并且将次要和补丁版本设置为零。
例如版本 v2.28.18 发生不兼容发布,版本号将递增为 v3.0.0。
次要版本号
在发布向后兼容的更新后,例如添加新函数后,必须递增且补丁版本设置为零。
例如版本 v2.28.18 发生不兼容发布,版本号将递增为 v2.29.0。
补丁版本号
在不修改到公共接口的情况下,例如 Bug 修复或者做了一些优化,必须递增。
预发版本
-pre
后缀意味着某个版本的预发版,在指定版本的后面添加。
例如在 v1.2.3 之前,会先发布 v1.2.3-pre 预发版,完全确定后,才会正式发布 v1.2.3。
元数据
使用 +
符号连接元数据,例如 +incompatible
表示在迁移到模块版本主版本 2 或更高版本之前发布的版本。
构建元数据会在版本比较时被忽略。附带构建元数据的标识符会在版本库中被忽略,然而在 go.mod 文件中会被保留。
伪版本是一种特殊格式,主要是对版本控制存储库(Git)中特定修订的信息进行编码。
多用于开发过程中,并没有正式发布的时候就会使用伪版本打包,例如:v0.0.0-20191109021931-daa7c04131f5。
每个伪版本有三个部分:
从第 2 个版本开始,模块路径必须有个类似 /v2 的后缀,以此来匹配主版本。
就是 v0.x.x 或 v1.x.x 没有主版本后缀。因为 v0.x.x 版本不稳定且没有兼容性保证,v1.x.x 版本与最后一个 v0.x.x 版本向后兼容。
例如一个模块在版本 v1.x.x 的模块路径为 example.com/model,那么它在 v2.x.x 的模块路径将是 example.com/model/v2。
关于模块的下载就不得不提到 GOPROXY 代理,如果不用代理下载就极其缓慢。
通过代理就可以访问到代理服务缓存的模块,实现加速下载。
使用代理也带来了新的问题,只能下载代理服务上有的模块。这个时候可以通过配置 GOPRIVATE 指定仓库不走代理。
例如
我使用自己的 GitLab 管理我的模块代码,定义模块路径:gitlab.devnolo.com/liqingsong/go-modules-demo
,其仓库地址是:https://gitlab.devnolo.com/liqingsong/go-modules-demo
。并创建相应的 Tag 或者 GitHub 上创建 release ===> v0.1.0。
模块路径和仓库地址是按约定的存在,换种说法:仓库地址去掉网络协议就是模块路径。
在需要引用模块的电脑上配置 GOPRIVATE。
go env -w GOPRIVATE="gitlab.devnolo.com/*"
在模块的文件 go.mod 文件中声明需要引用模块的模块路径。
require gitlab.devnolo.com/liqingsong/go-modules-demo v0.1.0
通过模块路径 gitlab.devnolo.com/liqingsong/go-modules-demo
识别出仓库地址 https://gitlab.devnolo.com。
再拼接剩余路径,就可获得完整的仓库地址。