在 Go 中指定依赖项

Go 中的 Cloud Functions 函数必须通过包含 go.mod 文件的 Go 模块或 vendor 目录提供其所有依赖项。但您的函数不能同时使用 Go 模块和 vendor 目录来指定依赖项。

Go 运行时在执行环境中添加了多个系统软件包。如果您的函数使用的依赖项需要未列出的系统软件包,您可以请求添加软件包

本文档中的内容适用于 Go 1.11 和 Go 1.13。

使用 Go 模块

Cloud Functions 支持 Go 的实验性模块功能,使您可以在项目根目录下的 go.mod 文件中指定依赖项。部署您的函数时,系统将自动提取和构建 go.mod 文件中指定的依赖项。

根据您在 GOPATH 之内还是之外开发,Go 模块的行为也有所不同。要确定您是否在 GOPATH 之内,请执行以下操作:

  1. 导航到您的项目目录。

  2. 通过运行以下命令查找您的 GOPATH

    go env GOPATH
    

    该命令将输出如下所示的一行:

    GOPATH=YOUR_GOPATH
    
  3. 通过运行以下命令查找当前工作目录:

    pwd
    

如果您的工作目录以 YOUR_GOPATH 开头,则表明您在 GOPATH 内部。这种情况下,通过运行以下三条命令生成 go.mod 文件:

export GO111MODULE=on
go mod init
go mod tidy

如果您的工作目录不以 YOUR_GOPATH 开头,则表明您在 GOPATH 外部。这种情况下,通过运行以下命令生成 go.mod 文件:

go mod init MODULE
go mod tidy

在上述示例中,MODULE 是您的模块名称。 例如,您的模块名称可能是 example.com/myproject(请注意,域名必填)。如果您在 go 内部,则 GOPATH 命令会自动检测模块名称。

创建 go.mod 文件后,您可以使用 go get 命令提取依赖项并自动将它们添加到项目中。例如:

go get DEPENDENCY

在上述示例中,DEPENDENCY 是您要添加到函数的依赖项。例如,命令 go get cloud.google.com/go/storage 会将 Cloud Storage 客户端库添加到您的函数中。

使用 vendor 目录

借助 Cloud Functions,您还可以通过 vendor 目录添加您的依赖项。在大多数情况下,vendor 目录使用依赖项管理器进行维护。您可以使用您喜欢的任何依赖项管理器。例如,您可以使用 Go 的模块功能通过 go.mod 文件创建 vendor 目录。

如果依赖项不能通过依赖项管理器获取,或者您的 Cloud Functions 环境的互联网访问受限,则使用 vendor 目录很有用。

设置 vendor 目录后,您可能需要执行额外的步骤,以确保遵循其内容,具体取决于您使用的 Go 版本:

Go 1.16 版或更高版本

如果您使用的是 Go 1.16 或更高版本,则可以保持 vendor 目录不变。如果主模块包含顶级 vendor 目录,并且其 go.mod 文件指定了 Go 1.16 或更高版本,则对于接受该标志的操作,go 命令将默认为 -mod=vendor标志。

Go 1.16 之前的版本

如果您使用的是早于 1.16 的 Go 版本,则必须执行以下操作才能遵循 vendor 目录的内容。

对于早于 1.16 的 Go 版本,如果您有一个 go.mod 文件和 vendor 目录,则在部署函数时,vendor 目录将被忽略。您可以使用 .gcloudignore 文件来避免上传 go.modgo.sum 文件:

  1. 使用以下内容在项目根目录下创建 .gcloudignore 文件:

    go.mod
    go.sum
    
    # Also ignore Git directories. Delete the following two lines if you want to
    # upload them.
    .git
    .gitignore
    
  2. 通过运行以下命令,使用 go.mod 文件的内容创建 vendor 目录:

    go mod vendor
    

使用 gcloud 命令行工具部署函数时,您可以使用 .gcloudignore 确保不上传 go.mod

使用专用依赖项

如果函数的依赖项托管在不可公开访问的代码库中,则部署函数之前,您必须先使用 vendor 目录提取您的依赖项。如果您打算使用 go.mod 文件,请参阅上述说明以避免 go.mod 文件和 vendor 目录之间发生冲突。