长期以来,Golang 对外部依赖都没有很好的管理方式,只能从 $GOPATH
下查找依赖。这就造成不同用户在安装同一个项目时可能从外部获取到不同的依赖库版本,同时当无法联网时,无法编译依赖缺失的项目。
Golang 自 1.5 版本开始重视第三方依赖的管理,将项目依赖的外部包统一放到 vendor 目录下(类比 Nodejs 的 node_modules 目录),并通过 vendor.json 文件来记录依赖包的版本,方便用户使用相对稳定的依赖。
Daniel Theophanes 等人开发了 govendor 工具,方便对第三方依赖进行管理。
govendor 的安装十分简单,可以通过 go get 命令:
$ go get -u -v github.com/kardianos/govendor
对于 govendor 来说,主要存在三种位置的包:项目自身的包组织为本地(local)包;传统的存放在 $GOPATH 下的依赖包为外部(external)依赖包;被 govendor 管理的放在 vendor 目录下的依赖包则为 vendor 包。
具体来看,这些包可能的类型如下:
状态 | 缩写状态 | 含义 |
---|---|---|
+local | l | 本地包,即项目自身的包组织 |
+external | e | 外部包,即被 $GOPATH 管理,但不在 vendor 目录下 |
+vendor | v | 已被 govendor 管理,即在 vendor 目录下 |
+std | s | 标准库中的包 |
+unused | u | 未使用的包,即包在 vendor 目录下,但项目并没有用到 |
+missing | m | 代码引用了依赖包,但该包并没有找到 |
+program | p | 主程序包,意味着可以编译为执行文件 |
+outside | 外部包和缺失的包 | |
+all | 所有的包 |
常见的命令如下,格式为 govendor COMMAND
。
通过指定包类型,可以过滤仅对指定包进行操作。
命令 | 功能 |
---|---|
init |
初始化 vendor 目录 |
list |
列出所有的依赖包 |
add |
添加包到 vendor 目录,如 govendor add +external 添加所有外部包 |
add PKG_PATH |
添加指定的依赖包到 vendor 目录 |
update |
从 $GOPATH 更新依赖包到 vendor 目录 |
remove |
从 vendor 管理中删除依赖 |
status |
列出所有缺失、过期和修改过的包 |
fetch |
添加或更新包到本地 vendor 目录 |
sync |
本地存在 vendor.json 时候拉去依赖包,匹配所记录的版本 |
get |
类似 go get 目录,拉取依赖包到 vendor 目录 |
为了方便管理依赖,Golang 团队 2016 年 4 月开始开发了 dep 工具,试图进一步简化在 Golang 项目中对第三方依赖的管理。该工具目前已经被试验性支持,相信很快会成为官方支持的工具。
dep 目前需要 Golang 1.7+ 版本,兼容其他依赖管理工具如 glide、godep、vndr、govend、gb、gvt、govendor、glock 等。
类似于 govendor 工具,dep 将依赖都放在本地的 vendor 目录下,通过 Gopkg.toml 和 Gopkg.lock 文件来追踪依赖的状态。
安装可以通过 go get 命令:
$ go get -v -u github.com/golang/dep/cmd/dep
dep 使用保持简洁的原则,包括四个子命令。
其中,ensure 命令最为常用,支持的子命令参数主要包括:
自 1.11 版本开始,Golang 实验性支持了模块(module),作为未来取代 $GOPATH 的方案,将所有的包当做模块来统一管理,并且每个模块都支持版本号。所有依赖模块存在在 $GOROOT 目录下的 pkg/mod 子目录中。模块是若干个包(package)的集合。
模块信息通过 go.mod 文件来管理,该文件可以通过 go mod init
go mod 命令支持多个子命令,含义如下:
基本使用过程为:
go mod init <module name>
来初始化本地的 go.mod 文件;go get <package name>@<version>
来获取某个依赖包(不添加版本号会默认获取当前最新),同时自动更新 go.mod 文件;go build -mod=readonly
可以避免在编译过程中修改 go.mod;go build -mod=vendor
;go list -m -u all
。如果要执行更新,可以使用 go get -u
;go
相关命令(build、get、list、test 等)时,也会自动下载依赖并更新 go.mod 文件。