

# 使用 .zip 文件归档部署 Node.js Lambda 函数
<a name="nodejs-package"></a>

 AWS Lambda 函数的代码包含一个 .js 或 .mjs 文件，其中包含函数的处理程序代码，以及代码所依赖的任何其他包和模块。要将此函数部署到 Lambda，您可以使用*部署包*。此包可以是 .zip 文件归档或容器映像。有关在 Node.js 中使用容器映像的更多信息，请参阅[使用容器映像部署 Node.js Lambda 函数](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-image.html)。

 要创建 .zip 文件归档格式的部署包，可以使用命令行工具内置的 .zip 文件归档实用工具或任何其他 .zip 文件实用工具（例如 [7zip](https://www.7-zip.org/download.html)）。以下各部分中显示的示例假设您在 Linux 或 macOS 环境中使用命令行 `zip` 工具。要在 Windows 中使用相同命令，您可以安装 [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10)，以获取 Windows 集成版本的 Ubuntu 和 Bash。

 请注意，Lambda 使用 POSIX 文件权限，因此在创建 .zip 文件归档之前，您可能需要[为部署包文件夹设置权限](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-deployment-package-errors/)。

**Topics**
+ [Node.js 中的运行时系统依赖项](#nodejs-package-dependencies)
+ [创建不含依赖项的 .zip 部署包](#nodejs-package-create-no-dependencies)
+ [创建含依赖项的 .zip 部署包](#nodejs-package-create-dependencies)
+ [为依赖项创建 Node.js 层](#nodejs-package-dependencies-layers)
+ [依赖项搜索路径和包含运行时系统的库](#nodejs-package-searchpath)
+ [使用 .zip 文件创建和更新 Node.js Lambda 函数](#nodejs-package-create-update)

## Node.js 中的运行时系统依赖项
<a name="nodejs-package-dependencies"></a>

 对于使用 Node.js 运行时系统的 Lambda 函数，依赖项可以是任何 Node.js 模块。Node.js 运行时系统包括许多常用库以及一个 适用于 JavaScript 的 AWS SDK 版本。所有[支持的 Node.js 运行时](lambda-nodejs.md#nodejs-supported-runtimes)都包含 SDK 版本 3。要使用 SDK 版本 2，您必须将 SDK 添加到 .zip 文件部署包中。要查找您正在使用的运行时中包含的 SDK 的具体版本，请参阅[包含运行时的 SDK 版本](lambda-nodejs.md#nodejs-sdk-included)。

 Lambda 会定期更新 Node.js 运行时系统中的开发工具包库，以包含最新更新和安全补丁。Lambda 还会对运行时系统中包含的其他库应用安全补丁和更新。要完全控制包中的依赖项，您可以将任何包含运行时系统依赖项的首选版本添加到部署包中。例如，如果您想使用适用于 JavaScript 的开发工具包的特定版本，则可以将其作为依赖项包含在.zip 文件中。有关向.zip 文件添加包含运行时系统的依赖项的更多信息，请参阅 [依赖项搜索路径和包含运行时系统的库](#nodejs-package-searchpath)。

 在 [AWS 责任共担模式](lambda-runtimes.md#runtimes-shared-responsibility)下，您负责管理函数部署包中的所有依赖项。这包括应用更新和安全补丁。要更新函数部署包中的依赖项，请先创建一个新的 .zip 文件，然后将其上传到 Lambda 中。有关更多信息，请参阅 [创建含依赖项的 .zip 部署包](#nodejs-package-create-dependencies) 和 [使用 .zip 文件创建和更新 Node.js Lambda 函数](#nodejs-package-create-update)。

## 创建不含依赖项的 .zip 部署包
<a name="nodejs-package-create-no-dependencies"></a>

 如果除了包含在 Lamba 运行时系统中的库外，您的函数代码没有其他依赖项，则 .zip 文件仅包含带有函数处理程序代码的 `index.js` 或 `index.mjs` 文件。使用您的首选 zip 实用工具创建一个 .zip 文件，并将 `index.js` 或 `index.mjs` 文件置于根目录中。如果包含您处理程序代码的文件不在 .zip 文件的根目录中，Lambda 将无法运行代码。

 要了解如何部署 .zip 文件以创建新的 Lambda 函数或更新现有函数，请参阅 [使用 .zip 文件创建和更新 Node.js Lambda 函数](#nodejs-package-create-update)。

## 创建含依赖项的 .zip 部署包
<a name="nodejs-package-create-dependencies"></a>

如果函数代码依赖未包含在 Lamba Node.js 运行时系统中的程序包或模块，您可以使用函数代码将这些依赖项添加到 .zip 文件中，也可以使用 [Lambda 层](chapter-layers.md)。本部分中的说明向您展示了如何将依赖项包含在 .zip 部署包中。有关如何将依赖项包含在层中的说明，请参阅 [为依赖项创建 Node.js 层](#nodejs-package-dependencies-layers)。

以下示例 CLI 命令将创建名为 `my_deployment_package.zip` 的 .zip 文件，其中包含 `index.js` 或 `index.mjs` 文件，以及您的函数处理程序代码及其依赖项。在示例中，您要使用 npm 程序包管理器来安装依赖项。

**创建部署包**

1. 导航到包含 `index.js` 或 `index.mjs` 源代码文件的项目目录。在此示例中，该目录名为 `my_function`。

   ```
   cd my_function
   ```

1. 使用 `npm install` 命令在 `node_modules` 目录中安装函数所需的库。在此示例中，您要安装 AWS X-Ray SDK for Node.js。

   ```
   npm install aws-xray-sdk
   ```

   这将创建一个类似于下面的文件夹结构：

   ```
   ~/my_function
   ├── index.mjs
   └── node_modules
       ├── async
       ├── async-listener
       ├── atomic-batcher
       ├── aws-sdk
       ├── aws-xray-sdk
       ├── aws-xray-sdk-core
   ```

   您还可以将自己创建的自定义模块添加到部署包中。在 `node_modules` 下创建一个以模块命名的目录，然后将自定义编写程序包保存在此处。

1. 在根目录下创建一个包含您的项目文件夹内容的 .zip 文件。使用 `r` （递归）选项来确保 zip 压缩子文件夹。

   ```
   zip -r my_deployment_package.zip .
   ```

## 为依赖项创建 Node.js 层
<a name="nodejs-package-dependencies-layers"></a>

本部分中的说明旨在向您展示如何将依赖项包含在层中。有关如何将依赖项包含在部署包中的说明，请参阅 [创建含依赖项的 .zip 部署包](#nodejs-package-create-dependencies)。

当您向函数添加层时，Lambda 会将层内容加载到该执行环境的 `/opt` 目录中。对于每个 Lambda 运行时系统，`PATH` 变量都包括 `/opt` 目录中的特定文件夹路径。为确保 Lambda 能够获取层内容，层 .zip 文件应在以下任何一个文件夹路径中具有依赖项：
+ `nodejs/node_modules`
+ `nodejs/node18/node_modules (NODE_PATH)`
+ `nodejs/node20/node_modules (NODE_PATH)`
+ `nodejs/node22/node_modules (NODE_PATH)`

例如，层.zip 文件结构可能如下所示：

```
xray-sdk.zip
└ nodejs/node_modules/aws-xray-sdk
```

此外，Lambda 会自动检测 `/opt/lib` 目录中的任何库，以及 `/opt/bin` 目录中的任何二进制文件。为确保 Lambda 正确获取层内容，还可以创建包含以下结构的层：

```
custom-layer.zip
└ lib
    | lib_1
    | lib_2
└ bin
    | bin_1
    | bin_2
```

打包层后，请参阅 [在 Lambda 中创建和删除层](creating-deleting-layers.md) 和 [向函数添加层](adding-layers.md) 以完成层设置。

## 依赖项搜索路径和包含运行时系统的库
<a name="nodejs-package-searchpath"></a>

Node.js 运行时系统包括许多常用库以及一个 适用于 JavaScript 的 AWS SDK 版本。如果您想使用包含运行时系统的库的不同版本，可以通过将其与自己的函数捆绑或将其作为依赖项添加到部署包中来实现。例如，您可以通过将开发工具包添加到 .zip 部署包中来使用其他版本的开发工具包。您也可以将其包含在函数的 [Lambda 层](chapter-layers.md)中。

在代码中使用 `import` 或 `require` 语句时，Node.js 运行时系统会搜索 `NODE_PATH` 路径中的目录，直到找到相应模块。默认情况下，运行时系统搜索的第一个位置是解压缩并安装 .zip 部署包的目录 (`/var/task`)。如果在部署包中包含运行时系统的库的某个版本，则此版本将优先于运行时系统中包含的版本。部署包中的依赖项也优先于层中的依赖项。

向层添加依赖项时，Lambda 会将其提取到 `/opt/nodejs/nodexx/node_modules` 中，其中 `nodexx` 表示正在使用的运行时系统版本。在搜索路径中，此目录优先于包含运行时系统的库的目录 (`/var/lang/lib/node_modules`)。因此，函数层中的库优先于运行时系统中包含的版本。

通过添加以下代码行，您可以查看 Lambda 函数的完整搜索路径。

```
console.log(process.env.NODE_PATH)
```

您还可以在 .zip 程序包内的单独文件夹中添加依赖项。例如，您可以将自定义模块添加到 .zip 程序包中名为 `common` 的文件夹中。解压缩并安装 .zip 程序包后，此文件夹将放置在 `/var/task` 目录中。要在代码中使用 .zip 部署包中某个文件夹的依赖项，请使用 `import { } from` 或 `const { } = require()` 语句，具体取决于您使用的是 CJS 还是 ESM 模块解析。例如：

```
import { myModule } from './common'
```

如果您将代码与 `esbuild`、`rollup` 或类似内容捆绑在一起，则函数使用的依赖项将捆绑在一个或多个文件中。我们建议尽量使用此方法来提供依赖项。与向部署包添加依赖项相比，由于减少了 I/O 操作，捆绑代码可以提高性能。

## 使用 .zip 文件创建和更新 Node.js Lambda 函数
<a name="nodejs-package-create-update"></a>

 创建 .zip 部署包后，您可以用其创建新的 Lambda 函数或更新现有的 Lambda 函数。您可以使用 Lambda 控制台、AWS Command Line Interface 和 Lambda API 部署 .zip 程序包。您也可以使用 AWS Serverless Application Model（AWS SAM）和 CloudFormation 创建和更新 Lambda 函数。

Lambda 的 .zip 部署包的最大大小为 250MB（已解压缩）。请注意，此限制适用于您上传的所有文件（包括任何 Lambda 层）的组合大小。

Lambda 运行时需要权限才能读取部署包中的文件。在 Linux 权限八进制表示法中，Lambda 对于不可执行文件（rw-r--r--）需要 644 个权限，对于目录和可执行文件需要 755 个权限（rwxr-xr-x）。

在 Linux 和 MacOS 中，使用 `chmod` 命令更改部署包中文件和目录的文件权限。例如，要为不可执行文件提供正确的权限，请运行以下命令。

```
chmod 644 <filepath>
```

要在 Windows 中更改文件权限，请参阅 Microsoft Windows 文档中的 [Set, View, Change, or Remove Permissions on an Object](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc731667(v=ws.10))。

**注意**  
如果您不向 Lambda 授予访问部署包中目录所需的权限，Lambda 会将这些目录的权限设置为 755（rwxr-xr-x）。

### 使用控制台通过 .zip 文件创建和更新函数
<a name="nodejs-package-create-console"></a>

 要创建新函数，必须先在控制台中创建该函数，然后上传您的 .zip 归档。要更新现有函数，请打开函数页面，然后按照相同的步骤添加更新的 .zip 文件。

 如果您的 .zip 文件小于 50MB，则可以通过直接从本地计算机上传该文件来创建或更新函数。对于大于 50MB 的 .zip 文件，必须首先将您的程序包上传到 Amazon S3 存储桶。有关如何使用 AWS 管理控制台 将文件上传到 Amazon S3 存储桶的说明，请参阅 [Amazon S3 入门](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html)。要使用 AWS CLI 上传文件，请参阅《AWS CLI 用户指南**》中的[移动对象](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

**注意**  
您无法更改现有函数的[部署包类型](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-PackageType)（.zip 或容器映像）。例如，您无法将容器映像函数转换为使用 .zip 文件归档。您必须创建新函数。

**创建新函数（控制台）**

1. 打开 Lambda 控制台的[“函数”页面](https://console.aws.amazon.com/lambda/home#/functions)，然后选择**创建函数**。

1. 选择**从头开始创作**。

1. 在**基本信息**中，执行以下操作：

   1. 对于**函数名称**，输入函数的名称。

   1. 对于**运行时系统**，选择要使用的运行时系统。

   1. （可选）对于**架构**，选择要用于函数的指令集架构。默认架构为 x86\$164。确保您的函数的 .zip 部署包与您选择的指令集架构兼容。

1. （可选）在 **Permissions**（权限）下，展开 **Change default execution role**（更改默认执行角色）。您可以创建新的**执行角色**，也可以使用现有角色。

1. 选择**创建函数**。Lambda 使用您选择的运行时系统创建基本“Hello world”函数。

**从本地计算机上传 .zip 归档（控制台）**

1. 在 Lambda 控制台的[“函数”页面](https://console.aws.amazon.com/lambda/home#/functions)中，选择要为其上传 .zip 文件的函数。

1. 选择**代码**选项卡。

1. 在**代码源**窗格中，选择**上传自**。

1. 选择 **.zip 文件**。

1. 要上传 .zip 文件，请执行以下操作：

   1. 选择**上传**，然后在文件选择器中选择您的 .zip 文件。

   1. 选择**打开**。

   1. 选择**保存**。

**从 Amazon S3 存储桶上传 .zip 归档（控制台）**

1. 在 Lambda 控制台的[“函数”页面](https://console.aws.amazon.com/lambda/home#/functions)中，选择要为其上传新 .zip 文件的函数。

1. 选择**代码**选项卡。

1. 在**代码源**窗格中，选择**上传自**。

1. 选择 **Amazon S3 位置**。

1. 粘贴 .zip 文件的 Amazon S3 链接 URL，然后选择**保存**。

### 使用控制台代码编辑器更新 .zip 文件函数
<a name="nodejs-package-console-edit"></a>

 对于某些带有 .zip 部署包的函数，您可以使用 Lambda 控制台的内置代码编辑器直接更新函数代码。要使用此功能，函数必须满足以下条件：
+ 函数必须使用一种解释性语言运行时系统（Python、Node.js 或 Ruby）
+ 函数的部署包必须小于 50 MB（未压缩状态）。

带有容器映像部署包的函数的代码不能直接在控制台中编辑。

**要使用控制台代码编辑器更新函数代码。**

1. 打开 Lambda 控制台的[“函数”页面](https://console.aws.amazon.com/lambda/home#/functions)，然后选择函数。

1. 选择**代码**选项卡。

1. 在**代码源**窗格中，选择源代码文件并在集成的代码编辑器中对其进行编辑。

1. 在**部署**部分，选择**部署**以更新函数的代码：  
![\[\]](http://docs.aws.amazon.com/zh_cn/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

### 使用 AWS CLI 通过 .zip 文件创建和更新函数
<a name="nodejs-package-create-cli"></a>

 您可以使用 [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) 创建新函数或使用 .zip 文件更新现有函数。使用 [create-function](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) 和 [update-function-code](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) 命令部署 .zip 程序包。如果您的 .zip 文件小于 50MB，则可以从本地生成计算机上的文件位置上传 .zip 程序包。对于较大的文件，必须从 Amazon S3 存储桶上传 .zip 程序包。有关如何使用 AWS CLI 将文件上传到 Amazon S3 存储桶的说明，请参阅《AWS CLI 用户指南**》中的[移动对象](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

**注意**  
如果您使用 AWS CLI 从 Amazon S3 存储桶上传 .zip 文件，则该存储桶必须与您的函数位于同一个 AWS 区域 中。

 要通过 AWS CLI 使用 .zip 文件创建新函数，则必须指定以下内容：
+ 函数的名称 (`--function-name`)
+ 函数的运行时系统 (`--runtime`)
+ 函数的[执行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html) (`--role`) 的 Amazon 资源名称（ARN）
+ 函数代码 (`--handler`) 中处理程序方法的名称

 还必须指定 .zip 文件的位置。如果 .zip 文件位于本地生成计算机上的文件夹中，请使用 `--zip-file` 选项指定文件路径，如以下示例命令所示。

```
aws lambda create-function --function-name myFunction \
--runtime nodejs24.x --handler index.handler \
--role arn:aws:iam::111122223333:role/service-role/my-lambda-role \
--zip-file fileb://myFunction.zip
```

 要指定 .zip 文件在 Amazon S3 存储桶中的位置，请使用 `--code` 选项，如以下示例命令所示。您只需对版本控制对象使用 `S3ObjectVersion` 参数。

```
aws lambda create-function --function-name myFunction \
--runtime nodejs24.x --handler index.handler \
--role arn:aws:iam::111122223333:role/service-role/my-lambda-role \
--code S3Bucket=amzn-s3-demo-bucket,S3Key=myFileName.zip,S3ObjectVersion=myObjectVersion
```

 要使用 CLI 更新现有函数，请使用 `--function-name` 参数指定函数的名称。您还必须指定要用于更新函数代码的 .zip 文件的位置。如果 .zip 文件位于本地生成计算机上的文件夹中，请使用 `--zip-file` 选项指定文件路径，如以下示例命令所示。

```
aws lambda update-function-code --function-name myFunction \
--zip-file fileb://myFunction.zip
```

 要指定 .zip 文件在 Amazon S3 存储桶中的位置，请使用 `--s3-bucket` 和 `--s3-key` 选项，如以下示例命令所示。您只需对版本控制对象使用 `--s3-object-version` 参数。

```
aws lambda update-function-code --function-name myFunction \
--s3-bucket amzn-s3-demo-bucket --s3-key myFileName.zip --s3-object-version myObject Version
```

### 使用 Lambda API 通过 .zip 文件创建和更新函数
<a name="nodejs-package-create-api"></a>

 要使用 .zip 文件归档创建和更新函数，请使用以下 API 操作：
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)
+ [UpdateFunctionCode](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionCode.html)

### 使用 AWS SAM 通过 .zip 文件创建和更新函数
<a name="nodejs-package-create-sam"></a>

 AWS Serverless Application Model（AWS SAM）是一个工具包，可帮助简化在 AWS 上构建和运行无服务器应用程序的过程。您可以在 YAML 或 JSON 模板中为应用程序定义资源，并使用 AWS SAM 命令行界面（AWS SAM CLI）构建、打包和部署应用程序。当您通过 AWS SAM 模板构建 Lambda 函数时，AWS SAM 会使用您的函数代码和您指定的任何依赖项自动创建 .zip 部署包或容器映像。要了解有关使用 AWS SAM 构建和部署 Lambda 函数的更多信息，请参阅《AWS Serverless Application Model 开发人员指南**》中的 [AWS SAM 入门](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html)。

您可以使用 AWS SAM 创建使用现有 .zip 文件归档的 Lambda 函数。要使用 AWS SAM 创建 Lambda 函数，您可以将 .zip 文件保存在 Amazon S3 存储桶或生成计算机上的本地文件夹中。有关如何使用 AWS CLI 将文件上传到 Amazon S3 存储桶的说明，请参阅《AWS CLI 用户指南**》中的[移动对象](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

 在 AWS SAM 模板中，`AWS::Serverless::Function` 资源将指定 Lambda 函数。在此资源中，设置以下属性以创建使用 .zip 文件归档的函数：
+ `PackageType` – 设置为 `Zip`
+ `CodeUri` – 设置为函数代码的 Amazon S3 URI、本地文件夹的路径或 [FunctionCode](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-functioncode.html) 对象
+ `Runtime` – 设置为您选择的运行时系统

 使用 AWS SAM，如果 .zip 文件大于 50MB，则不需要先将其上传到 Amazon S3 存储桶。AWS SAM 可以从本地生成计算机上的某个位置上传最大允许大小为 250MB（已解压缩）的 .zip 程序包。

 要了解有关在 AWS SAM 中使用 .zip 文件部署函数的更多信息，请参阅《AWS SAM 开发人员指南**》中的 [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)。

### 使用 CloudFormation 通过 .zip 文件创建和更新函数
<a name="nodejs-package-create-cfn"></a>

 您可以使用 CloudFormation 创建使用 .zip 文件归档的 Lambda 函数。要从 .zip 文件创建 Lambda 函数，必须先将您的文件上传到 Amazon S3 存储桶。有关如何使用 AWS CLI 将文件上传到 Amazon S3 存储桶的说明，请参阅《AWS CLI 用户指南**》中的[移动对象](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

在 CloudFormation 模板中，`AWS::Lambda::Function` 资源将指定 Lambda 函数。在此资源中，设置以下属性以创建使用 .zip 文件归档的函数：
+ `PackageType` – 设置为 `Zip`
+ `Code` – 在 `S3Bucket` 和 `S3Key` 字段中输入 Amazon S3 存储桶名称和 .zip 文件名。
+ `Runtime` – 设置为您选择的运行时系统

 CloudFormation 生成的 .zip 文件不能超过 4MB。要了解有关在 CloudFormation 中使用 .zip 文件部署函数的更多信息，请参阅《CloudFormation 用户指南**》中的 [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)。