这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记
Go语言的构建模式经历过三次迭代,从最早的GOPATH,到后来的Vendor机制,到现在的Go Module。
GOPATH
在GOPATH构建模式下,Go编译器在GOPATH环境变量的路径下搜索依赖的第三方包,如果不存在,编译器会报错。
在本地没有找到没有找到第三方依赖的情况下,我们可以使用go get命令将第三方包导入到GOPATH环境变量的配置目录下,同时它还能检测第三方包依赖的包,如果不存在,go get命令可以将他们一并下载到本地。
需要注意的是,go get下载的包只是你执行该命令时刻的那个版本,如果依赖的包版本发生迭代,则在不同时刻执行同样的代码可能产生不同的结果。
vendor
Go在1.5版本中引用了vendor机制,vendor机制能够将项目的所有依赖包缓存在vendor目录中。Go编译器会优先使用vendor目录下缓存的第三方包版本,而不是GOPATH环境变量路径中的版本。这样就解决了GOPATH模式下代码可能无法复现的问题。 注:要想开启vendor机制,你的Go项目必须位于GOPATH环境变量配置的某个路径的 src 目录下面,否则编译器会忽略Go项目中的vendor目录。
但是,vendor需要手动管理项目依赖的包,包括项目依赖包的分析、版本的记录、依赖包的存放等。
Go Module
Go在1.11版本中增加了Go Moudle构建模式,Go module使用了语义导入版本和最小版本选择等机制来解决来解决包的依赖管理问题。
创建一个Go Module需要以下几个步骤:
- 通过
go mod init命令初始化Go Module. - 通过
go mod tidy命令自动更新依赖信息. - 执行
go build完成构建。
创建Go Module会在项目目录下生成一个go.mod文件,确定第三方包的版本,并下载该module的依赖包以及依赖的依赖。依赖包的版本信息在go.mod中的require后。go build命令会读取go.mod中的依赖及版本信息,并在本地module缓存路径下找到对应版本的依赖,执行编译和链接。
语义导入版本:go.mod中require后的依赖版本号都是vX.Y.Z格式,其中X是主版本号,Y是次版本号,Z是补丁号。Go Module根据版本号确定是否兼容,主版本号不同的两个版本是相互不兼容的。主版本号相同时,次版本号大都是向后兼容次版本号小的。补丁版本号不影响兼容性。Go Module规定:如果同一个包的新旧版本是兼容的,那么它们的包导入路径应该是相同的。 当版本不兼容时,我们可以将包主版本号引入到包导入路径中,通过在包导入路径中引入主版本号的方式,来区别同一个包的不兼容版本。
最小版本选择:当两个依赖包同时依赖另一个第三方包时,Go 会在该项目依赖项的所有版本中,选出符合项目整体要求的“最小版本”。 比如:
此时Go Module会选择C的版本是v1.3.0