Go1-11新功能module的介绍及使用

Go1.1.1版本发布(2018-08-24发布)已经过去一段时间,从官方的博客中看到,有两个比较突出的特色,一个就是今天讲的module,模块概念。目前该功能还在试验阶段,有些地方还需要不断的进行完善。不过可以先尝尝鲜,感受下这个功能的魅力。

主要概念介绍

module是一个相关Go包的集合,它是源代码更替和版本控制的单元。模块由源文件形成的go.mod文件的根目录定义,包含go.mod文件的目录也被称为模块根目录。moudles取代旧的的基于GOPATH方法来指定在工程中使用哪些源文件或导入包。模块路径是导入包的路径前缀,go.mod文件定义模块路径,并且列出了在项目构建过程中使用的特定版本。

go.mod文件

go.mod文件还可以指定要替换和排除的版本,命令行会自动根据go.mod文件来维护需求声明中的版本。如果想获取更多的有关go.mod文件的介绍,可以使用命令go help go.mod。

1
go.mod文件用“//”注释,而不用“/**/”。文件的每行都有一条指令,由一个动作加上参数组成。例如:
1
2
3
4
5
module my/thing
require other/thing v1.0.2
require new/thing v2.3.4
exclude old/thing v1.2.3
replace bad/thing v1.4.5 => good/thing v1.4.5

上面三个动词分别表示:项目需要的依赖包及版本、排除某些包的特别版本、取代当前项目中的某些依赖包。
相同动作的命令可以放到一个动词+括号组成的结构中,例如:

1
2
3
4
require (
new/thing v2.3.4
old/thing v1.2.3
)

其他命令的支持
旧的版本,构建编译命令go build中的参数没有-mod参数,最新的版本现在多了这个,用来对go.mod文件进行更新或其他使用控制。形式如:go build -mod [mode],其中mode有以下几种取值:readonlyreleasevendor。当执行go build -mod=vendor的时候,会在生成可执行文件的同时将项目的依赖包放到主模块的vendor目录下。
go get -m [packages]会将下载的依赖包放到GOPATH/pkg/mod目录下,并且将依赖写入到go.mod文件。go get -u=patch会更新主模块下的所有依赖包。

Go mod工具
在最新的版本,为了支持在命令行直接控制module的操作,Go提供了mod工具。格式如下:go mod <command> [arguments]。其中命令有以下几种取值:

1
2
3
4
5
6
7
download                //下载模块到本地缓存,具体可以通过命令go env查看,其中环境变量GOCACHE就是缓存的地址,如果该文件夹的内容太大,可以通过命令go clean -cache
edit //从工具或脚本中编辑go.mod文件
graph //打印模块需求图
init //在当前目录下初始化新的模块
tidy //添加缺失的模块以及移除无用的模块
verify //验证依赖项是否达到预期的目的
why //解释为什么需要包或模块

虚拟版本号
go.mod文件和go命令通常使用语义版本作为描述模块版本的标准形式,这样可以比较不同版本的先后顺序。例如模块的版本是v1.2.3,那么通过重新对版本号进行标签处理,得到该版本的虚拟版本。形式如:v0.0.0-yyyymmddhhmmss-abcdefabcdef。其中时间是提交时的UTC时间,最后的后缀是提交的哈希值前缀。时间部分确保两个虚拟版本号可以进行比较,以确定两者顺序。
下面有三种形式的虚拟版本号:

  • vX.0.0-yyyymmddhhmmss-abcdefabcdef,这种情况适合用在在目标版本提交之前 ,没有更早的的版本。(这种形式本来是唯一的形式,所以一些老的go.mod文件使用这种形式)
  • vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef,这种情况被用在当目标版本提交之前的最新版本提交是vX.Y.Z-pre

  • vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef,同理,这种情况是当目标版本提交之前的最新版本是vX.Y.Z

  • 虚拟版本的生成不需要你去手动操作,go命令会将接收的commit哈希值自动转化为虚拟版本号。

环境变量——GO111MODULE
Go1.11 module支持一个临时的环境变量——GO111MODULE,它可以设置以下三个字符串中的一个:off,on或者auto,用来控制是否启用module功能。

  • GO111MODULE=off,设置成这个的时候,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
  • GO111MODULE=on,这种设置,go命令行会使用modules,而一点也不会去GOPATH目录下查找。这种方式也称为“模块-感知”或者“模块-感知 模式”。

  • GO111MODULE=auto,或者不设置此变量的值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:当前目录在GOPATH/src之外且该目录包含go.mod文件,或者当前文件在包含go.mod文件的目录下面。

当module功能启用时,GOPATH在项目构建过程中不再担当import的角色,但它仍然存储下载的依赖包,具体位置在GOPATH/pkg/mod

具体使用步骤:

  1. 首先将你的版本更新到最新的Go版本1.11,如何更新版本可以自行百度。

    2.通过go命令行,进入到你当前的工程目录下,在命令行设置临时环境变量set GO111MODULE=on

    3.执行命令go mod init在当前目录下生成一个go.mod文件,执行这条命令时,当前目录不能存在go.mod文件。如果之前生成过,要先删除;

    4.如果你工程中存在一些不能确定版本的包,那么生成的go.mod文件可能就不完整,因此继续执行下面的命令;

    5.执行go mod tidy命令,它会添加缺失的模块以及移除不需要的模块。执行后会生成go.sum文件(模块下载条目)。添加参数-v,例如go mod tidy -v可以将执行的信息,即删除和添加的包打印到命令行;

    6.执行命令go mod verify来检查当前模块的依赖是否全部下载下来,是否下载下来被修改过。如果所有的模块都没有被修改过,那么执行这条命令之后,会打印all modules verified

    7.执行命令go mod vendor生成vendor文件夹,该文件夹下将会放置你go.mod文件描述的依赖包,文件夹下同时还有一个文件modules.txt,它是你整个工程的所有模块。在执行这条命令之前,如果你工程之前有vendor目录,应该先进行删除。同理go mod vendor -v会将添加到vendor中的模块打印出来;

-------------本文结束感谢您的阅读-------------

本文标题:Go1-11新功能module的介绍及使用

文章作者:Wuman

发布时间:2018年11月10日 - 19:11

最后更新:2018年11月10日 - 19:11

原始链接:http://yoursite.com/2018/11/10/Go1-11新功能module的介绍及使用/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。