拥有供应商文件夹的好处是什么?

27
我无法真正理解拥有供应商文件夹的目的。根据我所了解的,如果您正在尝试使您的存储库与早于1.11版的golang版本兼容,则供应商文件夹是有益的。我们正在运行golang 1.12.14。
当我向同事提出此问题时,他说:
请使用带有模块的供应商 - go没有全局工厂。这是目前确保您具有隔离构建并且在某人更改其存储库中的内容时您的代码不会中断的最佳选项。
我认为这就是Go模块所做的吗?我问了这个问题,评论者说我不应该使用vendor?将"go mod vendor"添加到预提交钩子中是否有意义?

8
“vendor”是在模块化之前冻结依赖项的一种方式。注意,在《如何编写 Go 代码》文档中没有提到它。 - JimB
你的同事当时是对的,现在仍然是对的,但他的结论是错误的。模块允许使用代理进行可重复构建。 - Volker
有时候,我发现在项目的根目录下有一个名为“vendor”的独立文件夹来存放第三方代码非常实用。这样很容易浏览和修改代码。就像获取一个组件并进行微调(我甚至修复了一些问题)。我想说,是否有一个vendor文件夹并不是好或坏的事情,这取决于具体情况。话虽如此,我必须说,与你所说的相比,拥有一个vendor文件夹在更广泛的意义上是有益的。 - Victor
如果不确定,请不要使用供应商目录。Go将自动使用GOMODCACHE,这将加快下载速度,如果您正在处理多个Go项目。但一定要将go.mod和go.sum提交到git。 - guettli
3个回答

54
Go modules带来了这样的保证:通过将依赖项锁定到go.sum中,您将能够确定性地构建软件包。但是,只有在将来仍然可以访问依赖项的情况下,才能保证确定性地构建项目。如果无法访问依赖项,则无法保证构建成功。
另一方面,使用供应商目录(vendoring),无论是否使用Go模块,都会提供更强的保证,因为它使得可以将依赖项与代码一起提交。因此,即使远程存储库不再可访问(已删除、重命名等),您仍将能够构建项目。
另一个选择是使用代理和Go模块一起使用。您可以在官方文档中找到更多信息。您还可以查看一些开源实现,例如gomods/athensgoproxy/goproxy。如果您不想设置和维护自己的代理,则市场上有一些商业提供。
那么,每次提交时是否应该使用go mod vendor呢?这最终取决于您想要的保证类型。但是,利用代理或将依赖项放入供应商目录有助于实现可重复构建。

4
另一方面,如果一个第三方依赖项被撤下,这意味着它将不再获得更新,因此不应再被认为是安全可用的。 - Adrian
7
这是个好观点,但并非所有的摧毁都是故意的。代理/供应商还可以保护您免受短暂错误的影响(例如:GitHub宕机)。 - aymericbeaumet
3
Google托管的默认模块代理在某些国家也无法使用,因此包含供应商目录还可以减少那些不习惯使用Go的国家的用户遇到的问题。 - Tim H.
1
Go(1.14)在go.mod/sum中不添加任何供应商信息。但是如果存在,它似乎专门查找./vendor目录。它还在某种程度上执行完整性检查。例如,rm -rf vendor && mkdir vendor && go run .将导致go:inconsistent vendoring错误。删除单个软件包也会导致错误。更改软件包源不会导致错误。 - aymericbeaumet
3
go mod vendor 命令将根据 go.mod/sum 文件的指示更新 vendor 文件夹,并且 vendor 文件夹是确定使用哪个包的最终依据。 - Daniel Kobe
显示剩余3条评论

8
注意:使用 Go 1.17go mod vendor(来自1.17 Go命令)可能更容易使用:

供应商内容

如果主模块指定了go 1.17或更高版本,则go mod vendor现在会使用每个供应程序模块中自己的go.mod文件中指示的go版本注释vendor/modules.txt
当从供应商源代码构建模块的软件包时,将使用注释版本。

如果主模块指定了go 1.17或更高版本,则go mod vendor现在会省略供应商依赖项的go.modgo.sum文件,否则这些文件可能会干扰go命令在供应商树中调用时识别正确的模块根目录的能力。


0

Vendor文件夹是在项目中组织和管理第三方依赖项的好方法。当您的代码依赖于外部库或框架时,它尤其有用。

拥有Vendor文件夹的好处:

  • 它有助于减少依赖冲突。
  • 它允许您在项目中安装每个库/框架的单独版本。
  • 它有助于保持项目结构清洁和有序。
  • 它使得更新、安装和删除任何依赖项变得更加容易,只需付出最小的努力。
  • 它使得在不同版本的库或框架之间切换变得更加容易。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接