Vendor 目录
随着 Go 1.5 的发布,vendor/
目录除了GOPATH
和GOROOT
之外的依赖包的解析位置。Go 1.6 之前这是一个需要设置环境变量GO15VENDOREXPERIMENT=1
才能启用的功能,Go 1.6 中是一个默认启用的功能。
_注意,即使你使用了vendor/
,你的代码库还是需要放置在GOPATH
之中,这对 Go
工具链来说是无法避免的。
一个依赖包的解析位置是:
- 当前包中的
vendor/
目录。 - 目录树中查找父级中的
vendor/
目录。 - 查找
GOPATH
中的包。 - 如果存在于
GOROOT
(标准库所在的位置)中,则使用GOROOT
中的包。
建议
自从它们首次发布依赖,使用vendor/
目录过程中,我们得出了一些结论和建议。Glide 试图在以下几方面帮助你:
- 库(不带
main
包的代码库)不应将外部包存储在其 VCS 中的vendor/
中,除非它们具有特定的原因并且了解为什么要执行此操作。 - 在应用程序(带有
main
包的代码库)中,代码库顶层只应该有一个vendor/
目录。
这些建议有一些重要的原因。
- 包的每个实例,即使是同一个版本的包,在目录结构中将会在编译进最终的二进制文件中。如果每个包分别存储自己的依赖包,这将很快导致二进制文件变大。
- 不同位置的相同的包创建的实例不兼容,那么它们是相同的版本。你可以自己查看。这意味着日志记录器、数据库连接和其他共享的实例无法正常工作。
因此 Glide 将依赖关系平铺到单一的顶层vendor/
目录中。如果一些包刚好在它自己的vendor/
中有一些依赖包,go
工具会正确的解析该版本。
为何使用一个vendor
目录?
如果我们已经有了GOPATH
来存储包,那么为什么需要一个vendor/
目录?这完全是一个正常的问题。
如果GOPATH
中的多个应用程序使用同一个包的不同版本怎么办?这是一个在Go
应用程序中遇到的正常问题,并且已经存在了很长时间。
vendor/
目录允许不同的代码库具有自己的版本,而不会受到另一个需要不同版本的代码库的干扰。 它为每个项目提供了一个隔离级别。