what is the purpose of `go mod vendor` command?

huangapple go评论105阅读模式
英文:

what is the purpose of `go mod vendor` command?

问题

根据文档所说,

go mod vendor命令在主模块的根目录下构建一个名为vendor的目录,其中包含支持主模块中的包的构建和测试所需的所有包。仅由主模块外的包的测试导入的包不包括在内。

golangbyexample中提到:

您还可以将vendor目录检入到您的版本控制系统(VCS)中。这样做的好处是,在运行时不需要下载任何依赖项,因为它们已经存在于检入VCS的vendor文件夹中。

我认为模块(go.modgo.sum)负责版本控制。我还认为只有在第一次运行程序时才会下载依赖项。

那么,go mod vendor命令有什么用处?它的目的或用例是什么?

英文:

The documentation says,

> The go mod vendor command constructs a directory named vendor in the
> main module's root directory that contains copies of all packages
> needed to support builds and tests of packages in the main module.
> Packages that are only imported by tests of packages outside the main
> module are not included.

golangbyexample says:

> You can also check in the vendor directory to your VCS (Version
> Control System). This becomes useful in sense that none of the
> dependency needs to be downloaded at run time as it is already present
> in the vendor folder checked into VCS

I think modules (go.mod,go.sum) take care of the versioning. I also think that dependencies are only downloaded when I run the program for the first time.

So, how is the command go mod vendor useful? What is its purpose or use case?

答案1

得分: 35

Go Modules负责版本控制,但并不一定能处理模块从互联网上消失或互联网不可用的情况。如果一个模块不可用,代码就无法构建。

Go Proxy通过镜像模块在一定程度上缓解了模块消失的问题,但并不一定对所有模块永久有效:

为什么之前可用的模块在镜像中变得不可用?

proxy.golang.org并不会永久保存所有模块。有很多原因,其中之一是如果proxy.golang.org无法检测到合适的许可证。在这种情况下,只会提供一个临时缓存的模块副本,如果它从原始源中被删除并变得过时,可能会变得不可用。无论这些模块是否在镜像中变得不可用,校验和仍将保留在校验和数据库中。

更多信息请参见:https://proxy.golang.org/

另一种方法是fork模块并使用Go Modules的replace指令,它允许在go.mod文件中将导入路径重定向到另一个路径,例如你的fork,而无需更改你的代码。这个方法是由colm.anseo提供的。

关于互联网访问,如果你运行一个大型服务器群并且需要在多台机器上使用代码,从互联网下载到每台机器可能效率低下且存在安全风险。将代码使用go mod vendor命令放入内部仓库,并在各机器之间进行复制可能更加高效。大公司使用内部方法将代码部署到数据中心的多台服务器上。

英文:

Go Modules takes care of versioning, but it doesn't necessarily take care of modules disappearing off the Internet or the Internet not being available. If a module is not available, the code cannot be built.

Go Proxy will mitigate disappearing modules to some extent by mirroring modules, but it may not do it for all modules for all time:

> Why did a previously available module become unavailable in the mirror?
>
> proxy.golang.org does not save all modules forever. There are a number of reasons for this, but one reason is if proxy.golang.org is not able to detect a suitable license. In this case, only a temporarily cached copy of the module will be made available, and may become unavailable if it is removed from the original source and becomes outdated. The checksums will still remain in the checksum database regardless of whether or not they have become unavailable in the mirror.

See more at: https://proxy.golang.org/

An alternative approach for this is to fork modules and use the Go Modules replace directive which allows redirecting an import path to another, e.g. your fork, in the go.mod file without changing your code. This approach was provided by colm.anseo.

Regarding Internet access, if you run a large server farm and need the code on multiple machines, downloading from the Internet to every machine in your farm can be inefficient and a security risk. It may be much more efficient to use go mod vendor into an internal repo and copy this around. Large companies use internal methods to deploy code to multiple servers in their data centers.

答案2

得分: 0

我也认为只有在第一次运行程序时才会下载依赖项。

首先,你需要运行go build来进行编译。现在,go mod ...是一个工具,用于配置在整个项目可以构建之前将依赖项放在哪里。然而,这并不是为了只是想运行程序的人,而是为了程序的开发者,无论是为了开发/测试目的还是进一步的部署/CI等等。

这个工具非常有用,因为它允许编辑依赖项并使用此修改重新构建源代码树。模块被编译器使用的默认方式(你可能已经看到了)是使用用户主目录/全局安装,其中:1)它与项目无关;2)在该位置进行的更改可能会对其他共享这些依赖项的系统上的构建产生副作用。

因此,这实际上是实现完全自定义构建和完整源代码树的唯一方式,其中任何文件的任何更改都会反映在构建中并保持隔离。此外,这也是我能想象到的唯一一种“调试”依赖项的方式,即更改代码或添加日志等(澄清:这里不是指使用调试器)。

英文:

> I also think that dependencies are only downloaded when I run the program for the first time

You have to first take into account, to run you first need to go build. Now go mod ... is a tool configuring where to put dependencies before the whole thing can be built. This however not by someone just interested to run it - but the developer of a program, be it for dev/test purpose or further deploy/ci etc.

It is mostly useful as it will allow to edit a dependency and rebuild the sourcetree with this modification. The default way of modules to be consumed by the compiler (as you may have seen) uses a user-home/global installation, where 1) it is not tied to the project 2) changes done there would have side-effects on other builds on the system sharing these deps eventually.

So, in a way it is really the only way to have a fully custom build and integral source-tree for your project, where any change in any file will reflect in the build and stay isolated however. Also, it is really to only way for me to envision to "debug" a dependency in the sense of changing the code or adding logs etc (disambiguation: not talking of using a debugger here).

huangapple
  • 本文由 发表于 2021年7月27日 20:14:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/68544611.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定