Vendor 目录

随着 Go 1.5 的发布,vendor/目录除了GOPATHGOROOT之外的依赖包的解析位置。Go 1.6 之前这是一个需要设置环境变量GO15VENDOREXPERIMENT=1才能启用的功能,Go 1.6 中是一个默认启用的功能。

_注意,即使你使用了vendor/,你的代码库还是需要放置在GOPATH之中,这对 Go工具链来说是无法避免的。

一个依赖包的解析位置是:

  • 当前包中的vendor/目录。
  • 目录树中查找父级中的vendor/目录。
  • 查找GOPATH中的包。
  • 如果存在于GOROOT(标准库所在的位置)中,则使用GOROOT中的包。

建议

自从它们首次发布依赖,使用vendor/目录过程中,我们得出了一些结论和建议。Glide 试图在以下几方面帮助你:

  1. 库(不带main包的代码库)不应将外部包存储在其 VCS 中的vendor/中,除非它们具有特定的原因并且了解为什么要执行此操作。
  2. 在应用程序(带有main包的代码库)中,代码库顶层只应该有一个vendor/目录。

这些建议有一些重要的原因。

  • 包的每个实例,即使是同一个版本的包,在目录结构中将会在编译进最终的二进制文件中。如果每个包分别存储自己的依赖包,这将很快导致二进制文件变大。
  • 不同位置的相同的包创建的实例不兼容,那么它们是相同的版本。你可以自己查看。这意味着日志记录器、数据库连接和其他共享的实例无法正常工作。

因此 Glide 将依赖关系平铺到单一的顶层vendor/目录中。如果一些包刚好在它自己的vendor/中有一些依赖包,go 工具会正确的解析该版本。

为何使用一个vendor 目录?

如果我们已经有了GOPATH来存储包,那么为什么需要一个vendor/目录?这完全是一个正常的问题。

如果GOPATH中的多个应用程序使用同一个包的不同版本怎么办?这是一个在Go应用程序中遇到的正常问题,并且已经存在了很长时间。

vendor/目录允许不同的代码库具有自己的版本,而不会受到另一个需要不同版本的代码库的干扰。 它为每个项目提供了一个隔离级别。