

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 對 Node.js Lambda 函數使用層
<a name="nodejs-layers"></a>

使用 [Lambda 層](chapter-layers.md)封裝要在多個函式之間重複使用的程式碼與相依項。層通常具備程式庫相依性、[自訂執行期](runtimes-custom.md)或組態檔案。建立層包含三個一般步驟：

1. 封裝層內容。這表示建立 .zip 封存檔，其中包含您要在函數中使用的相依項。

1. 在 Lambda 中建立層。

1. 將層新增至函數中。

**Topics**
+ [封裝層內容](#nodejs-layers-package)
+ [在 Lambda 中建立層](#publishing-layer)
+ [將層新增至函式](#nodejs-layer-adding)
+ [應用程式範例](#nodejs-layer-sample-app)

## 封裝層內容
<a name="nodejs-layers-package"></a>

若要建立層，請將套件封裝成符合以下要求的 .zip 壓縮檔：
+ 使用計劃用於 Lambda 函式的同一個 Node.js 版本來建置層。例如，如果您使用 Node.js 24 建置 layer，請使用 Node.js 24 執行時間做為函數。
+ 層的 .zip 檔案必須使用下列任一目錄結構：
  + `nodejs/node_modules`
  + `nodejs/nodeX/node_modules` (其中 *X* 為 Node.js 版本，例如 `node22`)

  如需詳細資訊，請參閱[每個 Lambda 執行時間的層路徑](packaging-layers.md#packaging-layers-paths)。
+ 層中的套件必須與 Linux 相容。Lambda 函式會在 Amazon Linux 上執行。

您可以建立包含透過 `npm` 安裝的第三方 Node.js 程式庫 (如 `axios` 或 `lodash`) 的層，或您自訂的 JavaScript 模組的層。

### 第三方相依性
<a name="nodejs-layers-third-party-dependencies"></a>

**使用 npm 套件建立層**

1. 建立必要的目錄結構，並將套件直接安裝至其中：

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

   此命令會將套件直接安裝至 `nodejs/node_modules` 目錄，該目錄結構為 Lambda 所需的格式。
**注意**  
對於具有原生相依項或二進位元件 (例如 [sharp](https://www.npmjs.com/package/sharp) 或 [Bcrypt](https://www.npmjs.com/package/bcrypt)) 的套件，請確保其與 Lambda Linux 環境和函式的[架構](foundation-arch.md)相容。您可能需要使用 `--platform` 旗標：  

   ```
   npm install --prefix nodejs --platform=linux --arch=x64 sharp
   ```
對於更複雜的原生相依項，您可能需要在符合 Lambda 執行時期的 Linux 環境中進行編譯。在這種情況下，您可以使用 Docker。

1. 壓縮層內容：

------
#### [ 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 能順利找到並匯入套件。
npm 將 `nodejs/` 目錄中的 `package.json` 和 `package-lock.json` 檔案用於相依項管理，但 Lambda 實現層功能時並不需要這些檔案。每個已安裝的套件皆包含其自身的 `package.json` 檔案，該檔案定義了 Lambda 匯入套件的方式。

### 自訂 JavaScript 模組
<a name="custom-nodejs-modules"></a>

**使用自訂的程式碼建立層**

1. 建立層所需的目錄結構：

   ```
   mkdir -p nodejs/node_modules/validator
   cd nodejs/node_modules/validator
   ```

1. 為自訂模組建立 `package.json` 檔案，定義其匯入的方式：  
**Example nodejs/node\$1modules/validator/package.json**  

   ```
   {
     "name": "validator",
     "version": "1.0.0",
     "type": "module",
     "main": "index.mjs"
   }
   ```

1. 建立 JavaScript 模組檔案：  
**Example nodejs/node\$1modules/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)
     };
   }
   ```

1. 壓縮層內容：

------
#### [ Linux/macOS ]

   ```
   zip -r layer.zip nodejs/
   ```

------
#### [ PowerShell ]

   ```
   Compress-Archive -Path .\nodejs -DestinationPath .\layer.zip
   ```

------

   .zip 檔案的目錄結構應如下所示：

   ```
   nodejs/              
   └── node_modules/
       └── validator/
           ├── package.json
           └── index.mjs
   ```

1. 在您的函式中，匯入並使用模組。範例：

   ```
   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'
       });
     }
   };
   ```

   您可以使用下列[測試事件](testing-functions.md#invoke-with-event)來調用函式：

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

   預期回應：

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

## 在 Lambda 中建立層
<a name="publishing-layer"></a>

您可以使用 AWS CLI 或 Lambda 主控台發佈 layer。

------
#### [ AWS CLI ]

執行 [publish-layer-version](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/publish-layer-version.html) AWS CLI 命令來建立 Lambda layer：

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

[相容的執行時期](https://docs.aws.amazon.com/lambda/latest/api/API_PublishLayerVersion.html#lambda-PublishLayerVersion-request-CompatibleRuntimes)參數為選用參數。指定此參數後，Lambda 會據此在 Lambda 主控台中篩選層。

------
#### [ Console ]

**建立圖層 (主控台)**

1. 開啟 Lambda 主控台中的 [層頁面](https://console.aws.amazon.com/lambda/home#/layers)。

1. 選擇 **建立圖層**。

1. 選擇**上傳 .zip 檔案**，然後上傳先前建立的 .zip 壓縮檔。

1. (選用) 在**相容的執行時期**欄位中，選擇與用於建置層的 Node.js 版本相對應的 Node.js 執行時期。

1. 選擇**建立**。

------

## 將層新增至函式
<a name="nodejs-layer-adding"></a>

------
#### [ AWS CLI ]

若要將 layer 連接至函數，請執行 [update-function-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-configuration.html) AWS CLI 命令。對於 `--layers` 參數，請使用層 ARN。ARN 必須指定版本 (例如 `arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1`)。如需詳細資訊，請參閱[層和層的版本](chapter-layers.md#lambda-layer-versions)。

```
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"
```

如果您使用的是第 2 AWS CLI 版，則需要 **cli-binary-format**選項。若要讓此成為預設的設定，請執行 `aws configure set cli-binary-format raw-in-base64-out`。若要取得更多資訊，請參閱*《AWS Command Line Interface 使用者指南第 2 版》*中 [AWS CLI 支援的全域命令列選項](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list)。

------
#### [ Console ]

**將層新增至函式**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇函式。

1. 向下捲動至**層**區段，然後選擇**新增層**。

1. 在**選擇層**欄位中，選取**自訂層**，然後選擇要使用的層。
**注意**  
如果未在建立層時新增[相容的執行時期](https://docs.aws.amazon.com/lambda/latest/api/API_PublishLayerVersion.html#lambda-PublishLayerVersion-request-CompatibleRuntimes)，此處不會列出層。您可以改為指定層 ARN。

1. 選擇**新增**。

------

## 應用程式範例
<a name="nodejs-layer-sample-app"></a>

如需如何使用 Lambda 層的更多範例，請參閱《 AWS Lambda 開發人員指南 GitHub 儲存庫》中的 [layer-nodejs](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/layer-nodejs) 範例應用程式。此應用程式包含一個內含 [lodash](https://www.npmjs.com/package/lodash) 程式庫的層。建立層之後，您可以部署並調用相應的函式，驗證層是否如預期那樣運作。