

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 默认版本使用 Amazon SAM
<a name="serverless-sam-cli-using-build"></a>

要构建无服务器应用程序，请使用 `sam build` 命令。此命令还会收集应用程序依赖项的构建构件，并将其以适当的格式和位置放置以供后续步骤（例如本地测试、打包和部署）使用。

您可以在清单文件（例如 `requirements.txt` (Python) 或 `package.json` (Node.js)）中指定应用程序的依赖项，也可以使用函数资源的 `Layers` 属性来指定。`Layers` 属性包含 Lambda 函数所依赖的 [Amazon Lambda 层](https://docs.amazonaws.cn/lambda/latest/dg/configuration-layers.html)资源列表。

应用程序构建构件的格式取决于每个函数的 `PackageType` 属性。此属性的选项有：
+ **`Zip`** – .zip 文件归档，包括您的应用程序代码及其依赖项。如果您将代码打包为 .zip 文件存档，则必须为函数指定 Lambda 运行时。
+ **`Image`** – 容器映像，除了应用程序代码及其依赖项之外，还包括基本操作系统、运行时和扩展。

有关 Lambda 包类型的更多信息，请参阅《Amazon Lambda 开发人员指南》**中的 [Lambda 部署包](https://docs.amazonaws.cn/lambda/latest/dg/gettingstarted-package.html)。

**Topics**
+ [

## 创建 .zip 文件存档
](#build-zip-archive)
+ [

## 构建容器映像
](#build-container-image)
+ [

## 容器环境变量文件
](#serverless-sam-cli-using-container-environment-file)
+ [

## 通过在源文件夹中构建项目来加快构建时间
](#serverless-sam-cli-using-build-in-source)
+ [

## 示例
](#building-applications-examples)
+ [

## 在外部构建函数 Amazon SAM
](#building-applications-skip)

## 创建 .zip 文件存档
<a name="build-zip-archive"></a>

要将无服务器应用程序构建为 .zip 文件存档，请为无服务器函数声明 `PackageType: Zip`。

Amazon SAM 针对您指定的[架构](sam-resource-function.md#sam-function-architectures)构建应用程序。如果您未指定架构，则`x86_64`默认 Amazon SAM 使用。

如果 Lambda 函数依赖于具有本地编译程序的包，请使用 `--use-container` 标志。此标志在本地将您的函数编译到一个行为类似于 Lambda 环境的容器中，因此当您将它们部署到云端时，它们的格式是正确的。 Amazon 

当您使用该`--use-container`选项时，默认情况下会从 [Amazon ECR](https://docs.amazonaws.cn/AmazonECR/latest/public/what-is-ecr.html) Public 中 Amazon SAM 提取容器映像。如果您想从其他存储库或特定版本的 Amazon SAM CLI 中提取容器映像，则可以使用`--build-image`选项并提供备用容器镜像的 URI。以下是使用来自特定版本的 Amazon SAM CLI 的容器镜像构建应用程序的两个示例命令：

```
# Build a Node.js 20 application using a container image for a specific version of Amazon SAM CLI (1.136.0)
sam build --use-container --build-image public.ecr.aws/sam/build-nodejs22.x:1.136.0

# Build a function resource using the Python 3.13 container image from a specific version of Amazon SAM CLI (1.136.0)(
sam build --use-container --build-image Function1=public.ecr.aws/sam/build-python3.13:1.136.0
```

有关构建 .zip 文件存档应用程序的其他示例，请参阅本主题后面的“示例”部分。

## 构建容器映像
<a name="build-container-image"></a>

要将无服务器应用程序构建为容器映像，请为无服务器函数声明 `PackageType: Image`。您还必须使用以下条目声明 `Metadata` 资源属性：

`Dockerfile`  
与 Lambda 函数关联的 Dockerfile 的名称。

`DockerContext`  
Dockerfile 的位置。

`DockerTag`  
（可选）应用于已构建映像的标签。

`DockerBuildArgs`  
为构建设置参数。  
 Amazon SAMCLI 不会对包含在 `DockerBuildArgs` 参数中的任何信息进行编辑或模糊处理。我们强烈建议您不要使用此部分存储敏感信息，例如密码或密钥。

以下是 `Metadata` 资源属性部分的示例：

```
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: ./hello_world
      DockerTag: v1
```

要下载配置了 `Image` 软件包类型的示例应用程序，请参阅[教程：使用以下命令部署 Hello World 应用程序 Amazon SAM](serverless-getting-started-hello-world.md)。当系统提示您要安装哪种软件包类型时，选择 `Image`。

**注意**  
如果您在 Dockerfile 中指定了多架构基础镜像，则需要为主机的架构 Amazon SAM 构建容器镜像。要针对不同的架构进行构建，请指定使用特定目标架构的基础映像。

## 容器环境变量文件
<a name="serverless-sam-cli-using-container-environment-file"></a>

要为构建容器提供包含环境变量的 JSON 文件，请在 `sam build` 命令中使用 `--container-env-var-file` 参数。您可以提供适用于所有无服务器资源的单个环境变量，也可以为每种资源提供不同的环境变量。

### Format
<a name="serverless-sam-cli-using-container-environment-file-format"></a>

向构建容器传递环境变量的格式取决于您为资源提供的环境变量的数量。

要为所有资源提供单个环境变量，请指定如下所示的 `Parameters` 对象：

```
{
  "Parameters": {
    "GITHUB_TOKEN": "TOKEN_GLOBAL"
  }
}
```

要为每种资源提供不同的环境变量，请如下所示为每种资源指定对象：

```
{
  "MyFunction1": {
    "GITHUB_TOKEN": "TOKEN1"
  },
  "MyFunction2": {
    "GITHUB_TOKEN": "TOKEN2"
  }
}
```

将您的环境变量另存为文件，例如名为 `env.json`。以下命令使用此文件将环境变量传递到构建容器：

```
sam build --use-container --container-env-var-file env.json
```

### 优先级
<a name="serverless-sam-cli-using-container-environment-file-precedence"></a>
+ 您为特定资源提供的环境变量优先于所有资源的单个环境变量。
+ 您在命令行中提供的环境变量优先于文件中的环境变量。

## 通过在源文件夹中构建项目来加快构建时间
<a name="serverless-sam-cli-using-build-in-source"></a>

对于受支持的运行时和构建方法，您可以使用 `--build-in-source` 选项直接在源文件夹中生成项目。默认情况下，在临时目录中 Amazon SAM CLI构建，其中包括复制源代码和项目文件。使用`--build-in-source`， Amazon SAM CLI可以直接在源文件夹中进行构建，无需将文件复制到临时目录，从而加快构建过程。

有关支持的运行时和构建方法的列表，请参阅 `--build-in-source`。

## 示例
<a name="building-applications-examples"></a>

### 示例 1：.zip 文件存档
<a name="examples-zip-archives"></a>

以下 `sam build` 命令可创建 .zip 文件存档：

```
# Build all functions and layers, and their dependencies
sam build

# Run the build process inside a Docker container that functions like a Lambda environment
sam build --use-container

# Build a Node.js 20 application using a container image for a specific version of Amazon SAM CLI (1.136.0)
sam build --use-container --build-image public.ecr.aws/sam/build-nodejs22.x:1.136.0

# Build a function resource using the Python 3.13 container image from a specific version of Amazon SAM CLI (1.136.0)(
sam build --use-container --build-image Function1=public.ecr.aws/sam/build-python3.13:1.136.0

# Build and run your functions locally
sam build && sam local invoke

# For more options
sam build --help
```

### 示例 2：容器映像
<a name="examples-container-image-1"></a>

以下 Amazon SAM 模板以容器镜像的形式构建：

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
      ImageConfig:
        Command: ["app.lambda_handler"]
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: ./hello_world
      DockerTag: v1
```

以下是 Dockerfile 的示例：

```
FROM public.ecr.aws/lambda/python:3.12

COPY app.py requirements.txt ./

RUN python3.12 -m pip install -r requirements.txt

# Overwrite the command by providing a different command directly in the template.
CMD ["app.lambda_handler"]
```

### 示例 3：npm ci
<a name="examples-npm-ci"></a>

对于 Node.js 应用程序，您可以使用 `npm ci` 代替 `npm install` 来安装依赖项。要使用 `npm ci`，请在 Lambda 函数的 `Metadata` 资源属性中的 `BuildProperties` 下指定 `UseNpmCi: True`。要使用 `npm ci`，您的应用程序必须在 Lambda 函数的 `CodeUri` 中存在 `package-lock.json` 或 `npm-shrinkwrap.json` 文件。

以下示例使用 `npm ci` 在运行 `sam build` 时安装依赖项：

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.handler
      Runtime: nodejs20.x
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
    Metadata:
      BuildProperties:
        UseNpmCi: True
```

### Python 父软件包
<a name="building-applications-python-parent-packages"></a>

对于 Python 应用程序，您可以在构建过程中保留软件包结构，从而启用绝对导入。保留软件包结构，请在您 Lambda 函数的 `Metadata` 资源属性的 `BuildProperties` 下指定 `ParentPackageMode`。

以下示例在您运行 `sam build` 时保留 `app` 软件包结构：

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.main.handler
      Runtime: python3.12
      Architectures:
        - x86_64
    Metadata:
      BuildProperties:
        ParentPackageMode: explicit
        ParentPackages: app
```

通过此配置，您的代码可以使用 `from app.utils import logger` 这样的绝对导入，而非 `from .utils import logger` 这样的相对导入。

## 在外部构建函数 Amazon SAM
<a name="building-applications-skip"></a>

默认情况下，当您运行时**sam build**， Amazon SAM 会生成所有函数资源。其他选项包括：
+ **在之外构建所有函数资源 Amazon SAM** — 如果您手动或通过其他工具构建所有函数资源，**sam build**则不需要这样做。您可以跳过 **sam build** 并继续执行流程的下一步，例如执行本地测试或部署应用程序。
+ **在外部构建一些函数资源 Amazon SAM** — 如果您 Amazon SAM 想构建一些函数资源，同时在外部构建其他函数资源 Amazon SAM，则可以在 Amazon SAM 模板中指定这一点。

### 在之外构建一些函数资源 Amazon SAM
<a name="building-applications-skip-some"></a>

要在使用时 Amazon SAM 跳过某个函数**sam build**，请在 Amazon SAM 模板中配置以下内容：

1. 向函数添加 `SkipBuild: True` 元数据属性。

1. 指定您构建的函数资源的路径。

以下是将 `TestFunction` 配置为跳过的示例。它的构建资源位于 `built-resources/TestFunction.zip`。

```
TestFunction:
  Type: AWS::Serverless::Function
  Properties:
    CodeUri: built-resources/TestFunction.zip
    Handler: TimeHandler::handleRequest
    Runtime: java11
  Metadata:
    SkipBuild: True
```

现在，当你跑步时**sam build**， Amazon SAM 将执行以下操作：

1. Amazon SAM 将跳过配置的函数`SkipBuild: True`。

1. Amazon SAM 将构建所有其他函数资源并将其缓存在`.aws-sam`构建目录中。

1. 对于跳过的函数，它们在 `.aws-sam` 构建目录中的模板将自动更新，以引用您构建的函数资源的指定路径。

   以下是 `.aws-sam` 构建目录中 `TestFunction` 的缓存模板的示例：

   ```
   TestFunction:
     Type: AWS::Serverless::Function
     Properties:
       CodeUri: ../../built-resources/TestFunction.zip
       Handler: TimeHandler::handleRequest
       Runtime: java11
     Metadata:
       SkipBuild: True
   ```