从 go.mod 手动获取依赖项?

Manually fetch dependencies from go.mod?

我正在使用支持模块的 go 1.11。我知道 go 工具现在会在 build/install 上自动安装依赖项。我也明白其中的道理。

我正在使用 docker 构建我的二进制文件。在许多其他生态系统中,复制依赖项清单(package.json、requirements.txt 等)并将依赖项安装为独立于构建的独立阶段是很常见的。这利用了 docker 的层缓存,并使重建速度更快,因为通常代码更改远远超过依赖项更改。

请问vgo有没有办法做到这一点?

你可以使用包管理器,有很多像 dep, glide, and govendordep 较新,将作为官方依赖管理工具集成到 go 工具链中。

我们还为 go 应用程序制作 docker 图像,我们使用 dind 制作这些图像,我们准备了一个预安装所有依赖项的 CI/CD 图像,以加快构建速度。不过,需要一些脚本才能将所有内容粘合在一起。

此外,对依赖项进行分层可能会导致 docker 图像尺寸过大。我建议尝试 multi-stage builds,这有助于使图像变得超级精简。

您可以使用go mod vendor 命令在主模块的根文件夹中创建一个vendor 文件夹,并将所有依赖项复制到其中。在此之后,您可以将 -mod=vendor 参数传递给 go 工具,然后 vendor 文件夹中的依赖项将用于构建/编译/测试您的应用程序。

那么你可以做些什么来加速你的构建:

  1. 运行 go mod vendor 命令以获得您的依赖项的实际版本。
  2. 保存/缓存此 vendor 文件夹。
  3. 在构建期间,恢复此 vendor 文件夹,并通过将 -mod=vendor 参数传递给 go 工具来构建/安装您的应用程序,因此不会下载任何依赖项,但 vendor 将使用文件夹。

引用自go help mod

Modules and vendoring

When using modules, the go command completely ignores vendor directories.

By default, the go command satisfies dependencies by downloading modules from their sources and using those downloaded copies (after verification, as described in the previous section). To allow interoperation with older versions of Go, or to ensure that all files used for a build are stored together in a single file tree, 'go mod vendor' creates a directory named vendor in the root directory of the main module and stores there all the packages from dependency modules that are needed to support builds and tests of packages in the main module.

To build using the main module's top-level vendor directory to satisfy dependencies (disabling use of the usual network sources and local caches), use 'go build -mod=vendor'. Note that only the main module's top-level vendor directory is used; vendor directories in other locations are still ignored.

这是一个问题 #26610,现已修复。

所以现在您可以使用:

go mod download

为此,您只需要 go.mod / go.sum 个文件。

例如,这里是缓存多阶段 Docker 构建的方法:(source)

FROM golang:1.17-alpine as builder
RUN apk --no-cache add ca-certificates git
WORKDIR /build

# Fetch dependencies
COPY go.mod go.sum ./
RUN go mod download

# Build
COPY . ./
RUN CGO_ENABLED=0 go build

# Create final image
FROM alpine
WORKDIR /
COPY --from=builder /build/myapp .
EXPOSE 8080
CMD ["./myapp"]

另请参阅文章 Containerize Your Go Developer Environment – Part 2,其中介绍了如何利用 Go 编译器缓存 进一步加快构建速度。

我想 re-download 使用 go mod 所有依赖项,这就是我所做的:

  1. 转到您的 GOROOT
  2. sudo rm -rf pkg/mod/
  3. 转到 go.mod 文件所在的目录
  4. go mod download