使用 Node.js Lambda 函数的层 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

使用 Node.js Lambda 函数的层

使用 Lambda 层来打包要在多个函数中重复使用的代码和依赖项。层通常包含库依赖项、自定义运行时系统或配置文件。创建层涉及三个常见步骤:

  1. 打包层内容。此步骤需要创建 .zip 文件存档,其中包含要在函数中使用的依赖项。

  2. 在 Lambda 中创建层。

  3. 将层添加到函数。

打包层内容

要创建层,请将您的包捆绑到满足以下要求的 .zip 文件存档中:

  • 使用计划用于 Lambda 函数的相同 Node.js 版本来构建层。例如,如果您使用 Node.js 22 来构建层,则您的函数应使用 Node.js 22 运行时。

  • 您层的 .zip 文件必须使用以下目录结构之一:

    • nodejs/node_modules

    • nodejs/nodeX/node_modules(例如,其中 X 是您的 Node.js 版本node22

    有关更多信息,请参阅 每个 Lambda 运行时的层路径

  • 您的层中的包必须与 Linux 兼容。Lambda 函数在 Amazon Linux 上运行。

您可以创建包含使用 npm 安装的第三方 Node.js 库(例如 axioslodash)或者您自己的 JavaScript 模块。

要使用 npm 包创建层
  1. 创建所需的目录结构,并将包直接安装到其中:

    mkdir -p nodejs npm install --prefix nodejs lodash axios

    此命令是将包直接安装到 nodejs/node_modules 目录中,这是 Lambda 所需的结构。

    注意

    对于具有原生依赖项或二进制组件(例如,sharpbcrypt)的包,请确保它们与 Lambda Linux 环境以及您的函数架构兼容。您可能需要使用 --platform 标志:

    npm install --prefix nodejs --platform=linux --arch=x64 sharp

    对于更复杂的原生依赖项,您可能需要在与 Lambda 运行时匹配的 Linux 环境中对其进行编译。您可以使用 Docker 来实现这一目的。

  2. 压缩层内容:

    Linux/macOS
    zip -r layer.zip nodejs/
    PowerShell
    Compress-Archive -Path .\nodejs -DestinationPath .\layer.zip

    您的 .zip 文件的目录结构应如下所示:

    nodejs/
    ├── package.json
    ├── package-lock.json
    └── node_modules/
        ├── lodash/
        ├── axios/
        └── (dependencies of the other packages)
    注意
    • 请确保您的 .zip 文件包含位于根级别下的 nodejs 目录,且该目录内包含 node_modules。此结构旨在确保 Lambda 可以找到并导入您的包。

    • nodejs/ 目录中的 package.jsonpackage-lock.json 文件供 npm 用于依赖项管理,但 Lambda 不需要使用这些文件来实现层功能。每个已安装的软件包中已经包含自己的 package.json 文件,其中定义了 Lambda 如何导入软件包。

使用您自己的代码创建层
  1. 为您的层创建所需的目录结构:

    mkdir -p nodejs/node_modules/validator cd nodejs/node_modules/validator
  2. 为您的自定义模块创建一个 package.json 文件,以定义其导入方式:

    例 nodejs/node_modules/validator/package.json
    { "name": "validator", "version": "1.0.0", "type": "module", "main": "index.mjs" }
  3. 创建您的 JavaScript 模块文件:

    例 nodejs/node_modules/validator/index.mjs
    export function validateOrder(orderData) { // Validates an order and returns formatted data const requiredFields = ['productId', 'quantity']; // Check required fields const missingFields = requiredFields.filter(field => !(field in orderData)); if (missingFields.length > 0) { throw new Error(`Missing required fields: ${missingFields.join(', ')}`); } // Validate quantity const quantity = orderData.quantity; if (!Number.isInteger(quantity) || quantity < 1) { throw new Error('Quantity must be a positive integer'); } // Format and return the validated data return { productId: String(orderData.productId), quantity: quantity, shippingPriority: orderData.priority || 'standard' }; } export function formatResponse(statusCode, body) { // Formats the API response return { statusCode: statusCode, body: JSON.stringify(body) }; }
  4. 压缩层内容:

    Linux/macOS
    zip -r layer.zip nodejs/
    PowerShell
    Compress-Archive -Path .\nodejs -DestinationPath .\layer.zip

    您的 .zip 文件的目录结构应如下所示:

    nodejs/              
    └── node_modules/
        └── validator/
            ├── package.json
            └── index.mjs
  5. 在您的函数中导入并使用这些模块。示例:

    import { validateOrder, formatResponse } from 'validator'; export const handler = async (event) => { try { // Parse the order data from the event body const orderData = JSON.parse(event.body || '{}'); // Validate and format the order const validatedOrder = validateOrder(orderData); return formatResponse(200, { message: 'Order validated successfully', order: validatedOrder }); } catch (error) { if (error instanceof Error && error.message.includes('Missing required fields')) { return formatResponse(400, { error: error.message }); } return formatResponse(500, { error: 'Internal server error' }); } };

    您可以使用以下测试事件调用函数:

    { "body": "{\"productId\": \"ABC123\", \"quantity\": 2, \"priority\": \"express\"}" }

    预期的回应:

    { "statusCode": 200, "body": "{\"message\":\"Order validated successfully\",\"order\":{\"productId\":\"ABC123\",\"quantity\":2,\"shippingPriority\":\"express\"}}" }

在 Lambda 中创建层

您可以使用 Amazon CLI 或 Lambda 控制台发布层。

Amazon CLI

运行 publish-layer-version Amazon CLI 命令以创建 Lambda 层:

aws lambda publish-layer-version --layer-name my-layer --zip-file fileb://layer.zip --compatible-runtimes nodejs22.x

兼容的运行时参数是可选的。指定后,Lambda 将使用此参数在 Lambda 控制台中筛选层。

Console
创建层(控制台)
  1. 打开 Lambda 控制台的 Layers page(层页面)。

  2. 选择 Create layer(创建层)。

  3. 选择上传 .zip 文件,然后上传您之前创建的 .zip 存档。

  4. (可选)对于兼容的运行时,请选择与您用于构建层的 Node.js 版本相对应的 Node.js 运行时。

  5. 选择创建

将层添加到函数

Amazon CLI

要将层附加到函数,请运行 update-function-configuration Amazon CLI 命令。对于 --layers 参数,使用层 ARN。ARN 必须指定版本(例如 arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1)。有关更多信息,请参阅 层和层版本

aws lambda update-function-configuration --function-name my-function --cli-binary-format raw-in-base64-out --layers "arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1"

如果使用 cli-binary-format 版本 2,则 Amazon CLI 选项是必需的。要将其设为默认设置,请运行 aws configure set cli-binary-format raw-in-base64-out。有关更多信息,请参阅版本 2 的 Amazon Command Line Interface 用户指南中的 Amazon CLI 支持的全局命令行选项

Console
向函数添加层
  1. 打开 Lamba 控制台的函数页面

  2. 选择函数。

  3. 向下滚动到部分,然后选择添加层

  4. 选择层下,选择自定义层,然后选择您的层。

    注意

    如果您在创建层时没有添加兼容的运行时,则您的层将不会在此处列出。您可以改为指定层 ARN。

  5. 选择添加

示例应用程序

有关如何使用 Lambda 层的更多示例,请参阅 Amazon Lambda Developer Guide GitHub 存储库中的 layer-nodejs 示例应用程序。此应用程序中有一个包含 lodash 库的层。创建层后,即可部署并调用相应的函数来确认层是否按预期运行。