1.8.1 Go语言模块管理

一、go语言模块管理

  1. 从Go1.11版本开始对模块(module)进行支持,主要目的就是使用模块来管理依赖

  2. 在Go1.16版本中,GO111MODULE默认是开启状态,在Go1.16版本一下,请确保已经设置了GO111MODULE = on状态

  3. 一个模块就是一个包的集合,即go.mod文件所在目录下定义的所有包都属于这个模块

  4. go.mod文件定义了模块的路径(path),这个路径是用于import包的路径的集合,在编译时该模块会依赖其它模块

  5. 该模块依赖的模块通过模块路径加语义化版本号的格式添加到go.mod中

  6. go.mod常用命令见下表

    命令
    解释

    go mod download

    下载依赖的module到本地cache(缓存)

    go mod edit

    编译go.mod文件

    go mod graph

    打印模块依赖图

    go mod init

    在当前文件夹下初始化一个新的module,创建go.mod文件

    go mod tidy

    增加都是的module,去掉未用的module

    go mod vendor

    将依赖复制到vendor下

    go mod verify

    校验依赖

    go mod why

    解释为什么需要依赖

二、创建module

  1. 还可以在$GOPATH/src之外创建新的项目,go mod init module名命令可以创建一个空的go.mod文件

    module module名
    go 1.16  // 版本
  2. go.mod文件在项目根目录下创建一次即可,如果该根目录下再有根目录,则子目录下就不在需要重复创建go.mod文件了,因为所有子目录中的包都同属于该模块。该模块中的包在被导入的时候,import的路径使用module/package的模式导入即可

三、添加依赖

  1. 通过在程序中import(导入)对应的包,在Go1.16之前的版本中,运行go命令(如go rungo buildgo test)时,Go语言会通过一下规则自动解析并下载包

    1. 添加特定版本的包:需要import的包在go.mod文件中有对应的require描述,才能按对应描述的版本下载

    2. 添加最新版本的包:如果import的包在go.mod中没有require描述,则按最新版本下载该包,同时将该包加入到go.mod中

  2. 在Go1.16版本中,运行go命令时,如果import的依赖在go.mod文件中没有,则不会再自动下载并修改go.mod和go.sum文件,而提示错误,需要手动执行go get命令下载对应的包。原因:自动修复的方式不是在任何场景下都适用:如果导入的包在没有提供任何和依赖的情况下自动添加新以来,可能会引起公共依赖包的升级等

  3. 通过运行go get ./ ...命令可以自动查找并下载所有的包。添加完包后,可以通过使用go list -m all命令查看当前模块所依赖的包列表

  4. 在go.mod所在根目录下,除了维护go.mod文件外,还有一个go.sum文件

  5. go.sum文件是对导入依赖包特定版本的hash校验值,作用就是确保将来下载的依赖包版本和第一次下载到依赖包的版本号相同,以防在将来有版本号升级后程序不兼容的问题。所以,go.mod和go.sum文件都需要被加入版本管理中

  6. Go命令下载依赖包的来源有两个,分别是:

    1. 代理网站(如:http://proxy.golang.org)

    2. 版本控制仓库(如:http://github.com等源码管理仓库)

  7. 尤其是当依赖包是私有包、未在代理网站上传时,从版本控制仓库下载源代码尤为重要;但也涉及安全问题:恶意服务器可能会利用版本控制工具中的BUG来运行错误代码。因此,Go语言通过GOVCS环境变量的配置来确保安全,格式如下:

    如:

    解释:

    可以使用git命令下载包路径是http://gitee.com;

    任何版本控制命令都不可以下载http://evil.com路径的包;

    其余路径的包都可以用git或hg命令下载

四、升级依赖

  1. 在Go模块中,使用语义化的版本号来标记所依赖的包的版本

  2. 一个语义的版本号由3部分组成:主版本号、次版本号、补丁版本号

  3. 版本升级方式:

    1. 主版本升级:

      1. Go模块规定包的不同主版本号需要使用不同的模块路径

      2. 升级方式

    2. 次版本升级:

      1. 使用go get -u xxxxxx将会升级到最新的次版本或修订版本

      2. 运行go get -u = patch将会升级到最新的修订版本

      3. 运行go get package@version将会升级到制定的版本号version

五、移除依赖

  1. 如果不再使用一个依赖包,则从代码文件的import中移除。但在go.mod文件的require中并不会自动移除,需要使用go get tidy命令将其从go.mod文件中移除

  2. 因为go.mod的作用是在构建包时(如go build或go.test)告诉编译器需要那些包,那些包是缺失的,而不是告诉编译器什么时候该删除包

  3. 所以,安全移除包需要使用命令go mod tidy

Last updated