Go 的依赖管理 | 青训营

113 阅读1分钟

Go 的依赖管理

包和模块

Go 程序被组织到 Go 包中,Go 包是同一目录中一起编译的 Go 源文件的集合。在一个源文件中定义的函数、类型、变量和常量,对于同一包中的所有其他源文件可见。模块是存储在文件树中的 Go 包的集合,并且文件树根目录有 go.mod 文件。go.mod 文件定义了模块的名称及其依赖包,通过导入路径和版本描述一个依赖。

模块和包的关系更像是集合和元素的关系,包属于模块,一个模块是零个或者多个包的集合。下面的代码段,引用了一些包:

import (
    // Go 标准包
    "fmt"
    // 第三方包
    "github.com/spf13/pflag"
    // 匿名包
     _ "github.com/jinzhu/gorm/dialects/mysql"
     // 内部包
    "github.com/marmotedu/iam/internal/apiserver"
)

这里的fmt、github.com/spf13/pflaggithub.com/marmotedu/i…都是 Go 包。

Go 中有 4 种类型的包:

• Go 标准包:在 Go 源码目录下,随 Go 一起发布的包。

• 第三方包:第三方提供的包,比如来自于 github.com 的包。

• 匿名包:只导入而不使用的包。通常情况下,我们只是想使用导入包产生的副作用,即引用包级别的变量、常量、结构体、接口等,以及执行导入包的init()函数。

• 内部包:项目内部的包,位于项目目录下。

下面的目录定义了一个模块:

$ ls hello/
go.mod  go.sum  hello.go  hello_test.go  world

hello 目录下有一个 go.mod 文件,说明了这是一个模块,该模块包含了 hello 包和一个子包 world。该目录中也包含了一个 go.sum 文件,该文件供 Go 命令在构建时判断依赖包是否合法。

Go Modules 命令

Go Modules 的管理命令为go mod,go mod有很多子命令,你可以通过go help mod来获取所有的命令。

下面我来具体介绍下这些命令。

• download:下载 go.mod 文件中记录的所有依赖包。

• edit:编辑 go.mod 文件。

• graph:查看现有的依赖结构。

• init:把当前目录初始化为一个新模块。

• tidy:添加丢失的模块,并移除无用的模块。默认情况下,Go 不会移除 go.mod 文件中的无用依赖。当依赖包不再使用了,可以使用go mod tidy命令来清除它。

• vendor:将所有依赖包存到当前目录下的 vendor 目录下。

• verify:检查当前模块的依赖是否已经存储在本地下载的源代码缓存中,以及检查下载后是否有修改。

• why:查看为什么需要依赖某模块。

Go Modules 开关

如果要使用 Go Modules,在 Go1.14 中仍然需要确保 Go Modules 特性处在打开状态。

你可以通过环境变量 GO111MODULE 来打开或者关闭。

GO111MODULE 有 3 个值:

• auto:在 Go1.14 版本中是默认值,在$GOPATH/src下,且没有包含 go.mod 时则关闭 Go Modules,其他情况下都开启 Go Modules。

• on:启用 Go Modules,Go1.14 版本推荐打开,未来版本会设为默认值。

• off:关闭 Go Modules,不推荐。

所以,如果要打开 Go Modules,建议直接设置export GO111MODULE=on。