

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

# 使用 Node.js 建置 Lambda 函數
<a name="lambda-nodejs"></a>

您可以在 AWS Lambda中執行具有 Node.js 的 JavaScript 程式碼。Lambda 提供用於執行程式碼來處理事件的 Node.js [執行期](lambda-runtimes.md)。您的程式碼會在包含 的環境中執行 適用於 JavaScript 的 AWS SDK，其中包含您管理之 AWS Identity and Access Management (IAM) 角色的登入資料。若要進一步了解 Node.js 執行時期隨附的 SDK 版本，請參閱 [包含執行時期的 SDK 版本](#nodejs-sdk-included)。

Lambda 支援以下 Node.js 執行期。<a name="nodejs-supported-runtimes"></a>


| Name | 識別符 | 作業系統 | 取代日期 | 封鎖函數建立 | 封鎖函數更新 | 
| --- | --- | --- | --- | --- | --- | 
|  Node.js 24  |  `nodejs24.x`  |  Amazon Linux 2023  |   2028 年 4 月 30 日   |   2028 年 6 月 1 日   |   2028 年 7 月 1 日   | 
|  Node.js 22  |  `nodejs22.x`  |  Amazon Linux 2023  |   2027 年 4 月 30 日   |   2027 年 6 月 1 日   |   2027 年 7 月 1 日   | 
|  Node.js 20  |  `nodejs20.x`  |  Amazon Linux 2023  |   2026 年 4 月 30 日   |   2026 年 8 月 31 日   |   2026 年 9 月 30 日   | 

**若要建立 Node.js 函數**

1. 開啟 [Lambda 主控台](https://console.aws.amazon.com/lambda)。

1. 選擇**建立函數**。

1. 進行下列設定：
   + **函數名稱**：輸入函數名稱。
   + **執行時間**：選擇 **Node.js 24.x。**

1. 選擇**建立函數**。

主控台將建立一個 Lambda 函數，其具有名為 `index.mjs` 的單一來源檔案。您可以使用內建的程式碼編輯器編輯該檔案並加入更多檔案。在 **DEPLOY** 區段中，選擇**部署**以更新函數的程式碼。然後，若要執行程式碼，請在**測試事件**區段中選擇**建立測試事件**。

`index.mjs` 檔案匯出名為 `handler` 的函數，它接受事件物件與內容物件。這就是在叫用函數時，Lambda 呼叫的[處理常式函數](nodejs-handler.md)。Node.js 函數執行期會從 Lambda 中取得調用事件並將它們傳遞至處理常式。在函式組態中，處理常式值為 `index.handler`。

當您儲存函數程式碼時，Lambda 主控台會建立 .zip 封存檔部署套件。當您在主控台之外開發函數程式碼 (使用 IDE) 時，您需要[建立部署套件](nodejs-package.md)將您的程式碼上傳到 Lambda 函數。

除了傳遞調用事件外，函式執行期還會傳遞內容物件至處理常式。[內容物件](nodejs-context.md)包含了有關調用、函式以及執行環境的額外資訊。更多詳細資訊將另由環境變數提供。

Lambda 函數隨附有 CloudWatch Logs 記錄群組。函數執行期會將每次調用的詳細資訊傳送至 CloudWatch Logs。它在調用期間會轉送[您的函數輸出的任何記錄](nodejs-logging.md)。如果您的函數傳回錯誤，Lambda 會對該錯誤進行格式化之後傳回給調用端。

**Topics**
+ [

## 包含執行時期的 SDK 版本
](#nodejs-sdk-included)
+ [

## 使用保持連線保持 TCP 連線
](#nodejs-keep-alive)
+ [

## CA 憑證載入
](#nodejs-certificate-loading)
+ [

## 實驗 Node.js 功能
](#nodejs-experimental-features)
+ [

# 在 Node.js 中定義 Lambda 函數處理常式
](nodejs-handler.md)
+ [

# 使用 .zip 封存檔部署 Node.js Lambda 函數
](nodejs-package.md)
+ [

# 使用容器映像部署 Node.js Lambda 函數
](nodejs-image.md)
+ [

# 對 Node.js Lambda 函數使用層
](nodejs-layers.md)
+ [

# 使用 Lambda 內容物件擷取 Node.js 函數資訊
](nodejs-context.md)
+ [

# 記錄和監控 Node.js Lambda 函數
](nodejs-logging.md)
+ [

# 在 中檢測 Node.js 程式碼 AWS Lambda
](nodejs-tracing.md)

## 包含執行時期的 SDK 版本
<a name="nodejs-sdk-included"></a>

所有[支援的 Lambda Node.js 執行時間](#nodejs-supported-runtimes)都包含 適用於 JavaScript 的 AWS SDK v3 的特定次要版本，而非[最新版本](https://github.com/aws/aws-sdk-js-v3/releases)。執行時期中包含的特定次要版本取決於執行時期版本和您的 AWS 區域。若要查詢您目前所用執行時期中包含的 SDK 特定版本，請建立一個包含以下程式碼的 Lambda 函式。

**Example index.mjs**  

```
import packageJson from '@aws-sdk/client-s3/package.json' with { type: 'json' };

export const handler = async () => ({ version: packageJson.version });
```
這會傳回下列格式的回應：  

```
{
  "version": "3.632.0"
}
```

如需詳細資訊，請參閱[在處理常式中使用適用於 JavaScript v3 的 SDK](nodejs-handler.md#nodejs-example-sdk-usage)。

## 使用保持連線保持 TCP 連線
<a name="nodejs-keep-alive"></a>

預設 Node.js HTTP/HTTPS 代理程式會為每個新的請求建立新的 TCP 連線。為避免建立新連線所產生的成本，所有[支援的 Node.js 執行時期](#nodejs-supported-runtimes)均預設啟用保持連線功能。保持連線可以減少使用 SDK 進行多次 API 呼叫的 Lambda 函數的請求次數。

若要停用保持連線，請參閱*《AWS  SDK for JavaScript 3.x 版本開發人員指南》*中的[在 Node.js 中透過保持連線重複使用連線](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html)。如需使用保持連線的詳細資訊，請參閱《 AWS 開發人員工具部落格[》上的適用於 JavaScript 的模組化 AWS SDK 中的 HTTP 保持連線預設為開啟](https://aws.amazon.com/blogs/developer/http-keep-alive-is-on-by-default-in-modular-aws-sdk-for-javascript/)。

## CA 憑證載入
<a name="nodejs-certificate-loading"></a>

對於 Node.js 18 以下的 Node.js 執行時期版本，Lambda 會自動載入 Amazon 專屬的 CA (憑證授權單位) 憑證，讓您更輕鬆地建立與其他 AWS 服務互動的函數。例如，Lambda 包含在 Amazon RDS 資料庫上安裝的驗證[伺服器身分憑證](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html)所需的 Amazon RDS 憑證。此行為可能會在冷啟動期間產生效能影響。

從 Node.js 20 開始，在預設情況下，Lambda 不再載入額外的 CA 憑證。Node.js 20 執行期包含一個憑證檔案，其中包含所有 Amazon CA 憑證位於 `/var/runtime/ca-cert.pem`。若要從 Node.js 18 及更早版本的執行期還原相同的行為，請將 `NODE_EXTRA_CA_CERTS`[環境變數](configuration-envvars.md)設定為 `/var/runtime/ca-cert.pem`。

為了獲得最佳效能，我們建議您只將需要的憑證與部署套件搭配，並透過 `NODE_EXTRA_CA_CERTS` 環境變數載入憑證。憑證檔案應包含一或多個 PEM 格式的受信任根憑證或中繼 CA 憑證。例如，對於 RDS，請在程式碼旁包含所需的憑證做為 `certificates/rds.pem`。然後，藉由將 `NODE_EXTRA_CA_CERTS` 設定為 `/var/task/certificates/rds.pem` 載入憑證。

## 實驗 Node.js 功能
<a name="nodejs-experimental-features"></a>

上游 Node.js 語言版本預設啟用部分實驗性功能。為確保執行時期穩定性與效能一致性，Lambda 會停用這些功能。下表列出了 Lambda 停用的實驗性功能。


| 實驗性功能 | 支援的 Node.js 版本 | Lambda 套用的 Node.js 旗標 | 要重新啟用的 Lambda 旗標 | 
| --- | --- | --- | --- | 
|  支援在 ES 模組中使用 require 匯入模組  |  Node.js 20、Node.js 22  |  `--no-experimental-require-module`  |  `--experimental-require-module`  | 
|  支援自動偵測 ES 模組與 CommonJS 模組的功能  |  Node.js 22  |  `--no-experimental-detect-module`  |  `--experimental-detect-module`  | 

若要啟用已停用的實驗性功能，請在 `NODE_OPTIONS` 環境變數中設定重新啟用旗標。例如，若要啟用 ES 模組的 require 支援功能，請將 `NODE_OPTIONS` 設定為 `--experimental-require-module`。Lambda 偵測到此覆寫並移除了對應的停用旗標。

**重要**  
 使用實驗性功能可能會導致不穩定性與效能問題。這些功能可能會在未來的 Node.js 版本中變更或移除。使用實驗性功能的函式不符合 Lambda 服務水準協議 (SLA) 或 AWS 支援的資格。

# 在 Node.js 中定義 Lambda 函數處理常式
<a name="nodejs-handler"></a>

Lambda 函數*處理常式*是您的函數程式碼中處理事件的方法。當有人呼叫您的函數時，Lambda 會執行處理常式方法。函數會執行，直到處理常式傳回回應、結束或逾時為止。

本頁介紹了如何在 Node.js 中使用 Lambda 函式處理常式，包括專案設定選項、命名慣例及最佳實務。本頁還提供了一個 Node.js Lambda 函式範例，該函式會取得訂單的相關資訊、產生文字檔案收據，並將該檔案放入 Amazon Simple Storage Service (Amazon S3) 儲存貯體。如需編寫函數後如何部署函數的詳細資訊，請參閱[使用 .zip 封存檔部署 Node.js Lambda 函數](nodejs-package.md)或[使用容器映像部署 Node.js Lambda 函數](nodejs-image.md)。

**Topics**
+ [

## 設定 Node.js 處理常式專案
](#nodejs-handler-setup)
+ [

## Node.js Lambda 函式程式碼範例
](#nodejs-example-code)
+ [

## CommonJS 和 ES 模組
](#nodejs-commonjs-es-modules)
+ [

## Node.js 初始化
](#nodejs-initialization)
+ [

## 處理常式命名慣例
](#nodejs-handler-naming)
+ [

## 定義和存取輸入事件物件
](#nodejs-example-input)
+ [

## Node.js 函式的有效處理常式模式
](#nodejs-handler-signatures)
+ [

## 在處理常式中使用適用於 JavaScript v3 的 SDK
](#nodejs-example-sdk-usage)
+ [

## 存取環境變數
](#nodejs-example-envvars)
+ [

## 使用全域狀態
](#nodejs-handler-state)
+ [

## Node.js Lambda 函數的程式碼最佳實務
](#nodejs-best-practices)

## 設定 Node.js 處理常式專案
<a name="nodejs-handler-setup"></a>

初始化 Node.js Lambda 專案的方法有多種。例如，您可以使用 `npm` 建立標準的 Node.js 專案，建立 [AWS SAM 應用程式](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-init.html#using-sam-cli-init-new)，或建立 [AWS CDK 應用程式](lambda-cdk-tutorial.md#lambda-cdk-step-1)。

使用 `npm` 建立專案：

```
npm init
```

此命令會初始化專案，並產生管理專案中繼資料和相依項的 `package.json` 檔案。

您的函式程式碼位於 `.js` 或 `.mjs` JavaScript 檔案中。在下列範例中，此檔案使用 ES 模組處理常式，因此我們將其命名為 `index.mjs`。Lambda 同時支援 ES 模組與 CommonJS 處理常式。如需詳細資訊，請參閱[CommonJS 和 ES 模組](#nodejs-commonjs-es-modules)。

一個典型的 Node.js Lambda 函式專案遵循以下一般結構：

```
/project-root
  ├── index.mjs — Contains main handler
  ├── package.json — Project metadata and dependencies
  ├── package-lock.json — Dependency lock file
  └── node_modules/ — Installed dependencies
```

## Node.js Lambda 函式程式碼範例
<a name="nodejs-example-code"></a>

以下 Lambda 函式程式碼範例會取得訂單的相關資訊、產生文字檔案收據，並將該檔案放入 Amazon S3 儲存貯體。

**Example index.mjs Lambda 函式**  

```
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

// Initialize the S3 client outside the handler for reuse
const s3Client = new S3Client();

/**
 * Lambda handler for processing orders and storing receipts in S3.
 * @param {Object} event - Input event containing order details
 * @param {string} event.order_id - The unique identifier for the order
 * @param {number} event.amount - The order amount
 * @param {string} event.item - The item purchased
 * @returns {Promise<string>} Success message
 */
export const handler = async(event) => {
    try {
        // Access environment variables
        const bucketName = process.env.RECEIPT_BUCKET;
        if (!bucketName) {
            throw new Error('RECEIPT_BUCKET environment variable is not set');
        }

        // Create the receipt content and key destination
        const receiptContent = `OrderID: ${event.order_id}\nAmount: $${event.amount.toFixed(2)}\nItem: ${event.item}`;
        const key = `receipts/${event.order_id}.txt`;

        // Upload the receipt to S3
        await uploadReceiptToS3(bucketName, key, receiptContent);

        console.log(`Successfully processed order ${event.order_id} and stored receipt in S3 bucket ${bucketName}`);
        return 'Success';
    } catch (error) {
        console.error(`Failed to process order: ${error.message}`);
        throw error;
    }
};

/**
 * Helper function to upload receipt to S3
 * @param {string} bucketName - The S3 bucket name
 * @param {string} key - The S3 object key
 * @param {string} receiptContent - The content to upload
 * @returns {Promise<void>}
 */
async function uploadReceiptToS3(bucketName, key, receiptContent) {
    try {
        const command = new PutObjectCommand({
            Bucket: bucketName,
            Key: key,
            Body: receiptContent
        });

        await s3Client.send(command);
    } catch (error) {
        throw new Error(`Failed to upload receipt to S3: ${error.message}`);
    }
}
```

此 `index.mjs` 檔案包含以下程式碼區段：
+ `import` 區塊：此區塊用於納入 Lambda 函式所需的程式碼，例如 [AWS SDK 用戶端](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/the-request-object.html)。
+ `const s3Client` 宣告：此宣告會在處理常式函式外部初始化 [Amazon S3 用戶端](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/)。Lambda 會於[初始化階段](lambda-runtime-environment.md#runtimes-lifecycle-ib)執行此程式碼，並且該用戶端會被保留下，在[多次調用中重複使用](lambda-runtime-environment.md#execution-environment-reuse)。
+ JSDoc 註解區塊：透過 [JSDoc 註釋](https://jsdoc.app/about-getting-started)定義處理常式的輸入與輸出類型。
+ `export const handler`：此為 Lambda 調用的主要處理常式函式。部署函式時，請為[處理常式](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-Handler)屬性指定 `index.handler`。`Handler` 屬性的值由檔案名稱與匯出的處理常式方法名稱組成，兩者以點號分隔。
+ `uploadReceiptToS3` 函式：此為主要處理常式函式所參照的輔助函式。

若要讓此函式正常運作，其[執行角色](lambda-intro-execution-role.md)必須允許 `s3:PutObject` 動作。此外，請確保定義 `RECEIPT_BUCKET` 環境變數。成功調用後，Amazon S3 儲存貯體應包含收據檔案。

## CommonJS 和 ES 模組
<a name="nodejs-commonjs-es-modules"></a>

Node.js 支援兩個模組系統：CommonJS 和 ECMAScript 模組 (ES 模組）。Lambda 建議使用 ES 模組，因為它支援頂層等待，這可在[執行環境初始化](#nodejs-initialization)期間完成非同步任務。

Node.js 會將副檔名為 `.cjs` CommonJS 的檔案視為 CommonJS 模組，副`.mjs`檔名則表示 ES 模組。根據預設，Node.js 會將副檔名為 `.js` 的檔案視為 CommonJS 模組。您可以將 Node.js 設定為將`.js`檔案視為 ES 模組，方法是`module`在函數的 `package.json` 檔案中指定`type`為 。您可以在 Lambda 中設定 Node.js，透過將 `—experimental-detect-module`旗標新增至`NODE_OPTIONS`環境變數，自動偵測`.js`檔案是否應視為 CommonJS 或 ES 模組。如需詳細資訊，請參閱[實驗 Node.js 功能](lambda-nodejs.md#nodejs-experimental-features)。

下列範例顯示使用 ES 模組和 CommonJS 模組編寫的函數處理常式。本頁面上的其餘範例都使用 ES 模組。

------
#### [ ES module example ]

**Example – ES 模組處理常式**  

```
const url = "https://aws.amazon.com/";

export const handler = async(event) => {
    try {
        const res = await fetch(url);
        console.info("status", res.status);
        return res.status;
    }
    catch (e) {
        console.error(e);
        return 500;
    }
};
```

------
#### [ CommonJS module example ]

**Example – CommonJS 模組處理常式**  

```
const https = require("https");
let url = "https://aws.amazon.com/";

exports.handler = async function (event) {
  let statusCode;
  await new Promise(function (resolve, reject) {
    https.get(url, (res) => {
        statusCode = res.statusCode;
        resolve(statusCode);
      }).on("error", (e) => {
        reject(Error(e));
      });
  });
  console.log(statusCode);
  return statusCode;
};
```

------

## Node.js 初始化
<a name="nodejs-initialization"></a>

Node.js 使用非封鎖 I/O 模型，支援使用事件迴圈的高效率非同步操作。例如，如果 Node.js 進行網路呼叫，函數會繼續處理其他操作，而不會封鎖網路回應。收到網路回應時，會將其置於回呼佇列中。佇列中的任務會在目前任務完成時處理。

Lambda 建議使用頂層等待，以便在初始化期間完成執行環境初始化期間啟動的非同步任務。初始化期間未完成的非同步任務通常會在第一個函數叫用期間執行。這可能會導致非預期的行為或錯誤。例如，您的函數初始化可能會進行網路呼叫，從參數存放區擷取 AWS 參數。如果此任務未在初始化期間完成，則值在調用期間可能為 null。初始化和調用之間也可能有延遲，這可能會在時間敏感的操作中觸發錯誤。特別是，如果在初始化階段未完成呼叫， AWS 服務呼叫可能會依賴時間敏感的請求簽章，導致服務呼叫失敗。在初始化期間完成任務通常會改善冷啟動效能，並在使用佈建並行時先調用效能。如需詳細資訊，請參閱我們的部落格文章[使用 Node.js ES 模組和頂層等待。 AWS Lambda](https://aws.amazon.com/blogs/compute/using-node-js-es-modules-and-top-level-await-in-aws-lambda)

## 處理常式命名慣例
<a name="nodejs-handler-naming"></a>

設定函式時，[處理常式](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-Handler)的設定值由檔案名稱與匯出的處理常式方法名稱組成，二者以點號分隔。主控台中建立的函數以及本指南中的範例，預設值都是 `index.handler`。這表示 `handler` 方法是透過 `index.js` 或 `index.mjs` 檔案匯出的。

如果要在主控台中使用不同檔案名稱或函數處理常式名稱建立函數，您必須編輯預設處理常式名稱。

**變更函數處理常式名稱的方式 (主控台)**

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

1. 選擇 **程式碼** 索引標籤。

1. 向下捲動至**執行時間設定**窗格，並選擇**編輯**。

1. 在**處理常式**中，輸入函數處理常式的新名稱。

1. 選擇**儲存**。

## 定義和存取輸入事件物件
<a name="nodejs-example-input"></a>

JSON 是 Lambda 函數最常見的標準輸入格式。在此範例中，函數預期輸入類似以下內容：

```
{
    "order_id": "12345",
    "amount": 199.99,
    "item": "Wireless Headphones"
}
```

在 Node.js 中開發 Lambda 函式時，可透過 JSDoc 註釋定義輸入事件的預期結構。在此範例中，我們在處理常式的 JSDoc 註解中定義輸入結構：

```
/**
 * Lambda handler for processing orders and storing receipts in S3.
 * @param {Object} event - Input event containing order details
 * @param {string} event.order_id - The unique identifier for the order
 * @param {number} event.amount - The order amount
 * @param {string} event.item - The item purchased
 * @returns {Promise<string>} Success message
 */
```

在 JSDoc 註解內定義這些類型之後，即可直接在程式碼中存取事件物件的欄位。例如，使用 `order_id` 可以從原始輸入擷取 `event.order_id` 的值。

## Node.js 函式的有效處理常式模式
<a name="nodejs-handler-signatures"></a>

建議您使用 [async/await](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/using-async-await.html) 來宣告函式處理常式，而不是使用 [callback](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/using-a-callback-function.html)。async/await 能以簡潔且易讀的方式編寫非同步程式碼，無需使用巢狀回呼或串連承諾。您可以透過非同步/等待模式撰寫讀起來像同步程式碼的程式碼，同時仍維持非同步和非封鎖的特性。

### 非同步函數處理常式 （建議）
<a name="nodejs-handler-async"></a>

`async` 關鍵字會將函數標記為非同步，且 `await` 關鍵字會暫停函數的執行，直到 `Promise` 獲得解決為止。處理常式接受下列引數：
+ `event`：包含傳遞至函式的輸入資料。
+ `context`：包含有關調用、函式以及執行環境的資訊。如需詳細資訊，請參閱[使用 Lambda 內容物件擷取 Node.js 函數資訊](nodejs-context.md)。

以下所示為 async/await 模式的有效簽章：

```
export const handler = async (event) => { };
```

```
export const handler = async (event, context) => { };
```

### 同步函數處理常式
<a name="nodejs-handler-synchronous"></a>

如果您的函數不執行任何非同步任務，您可以使用同步函數處理常式，使用以下其中一個函數簽章：

```
export const handler = (event) => { };
```

```
export const handler = (event, context) => { };
```

### 回應串流函數處理常式
<a name="nodejs-handler-response-streaming"></a>

Lambda 支援使用 Node.js 進行回應串流。回應串流函數處理常式使用`awslambda.streamifyResponse()`裝飾項目，並採用 3 個參數：`responseStream`、 `event`和 `context`。函數簽章為：

```
export const handler = awslambda.streamifyResponse(async (event, responseStream, context) => { });
```

如需詳細資訊，請參閱[Lambda 函數的回應串流](configuration-response-streaming.md)。

### 以回呼為基礎的函數處理常式
<a name="nodejs-handler-callback"></a>

**注意**  
以回呼為基礎的函數處理常式最多僅支援 Node.js 22。從 Node.js 24 開始，應使用非同步函數處理常式實作非同步任務。

以回呼為基礎的函數處理常式必須使用事件、內容和回呼引數。範例：

```
export const handler = (event, context, callback) => { };
```

回呼函式預期會接收一個 `Error` 與一個回應物件，其中回應物件必須可進行 JSON 序列化。該函式會一直執行，直至[事件迴圈](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/)清空或函式逾時為止。直到完成所有的事件迴圈任務，回應才會傳送到叫用端。如果函式逾時，便會傳回錯誤。您可以透過設定 [context.callbackWaitsForEmptyEventLoop](nodejs-context.md) 為「false (失敗)」來設定執行時間立即傳回回應。

**Example - 具有 callback 的 HTTP 請求**  
以下範例函式檢查 URL 及傳回狀態碼給叫用端。  

```
import https from "https";
let url = "https://aws.amazon.com/";

export const handler = (event, context, callback) => {
  https.get(url, (res) => {
    callback(null, res.statusCode);
  }).on("error", (e) => {
    callback(Error(e));
  });
};
```

## 在處理常式中使用適用於 JavaScript v3 的 SDK
<a name="nodejs-example-sdk-usage"></a>

通常，您將使用 Lambda 函數與其他 AWS 資源互動或進行更新。與這些資源互動的最簡單方法便是使用 適用於 JavaScript 的 AWS SDK。所有[支援的 Lambda Node.js 執行時期](lambda-nodejs.md#nodejs-supported-runtimes)都包含[適用於 JavaScript 第 3 版的 SDK](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/introduction/)。不過，我們強烈建議您在部署套件中包含所需的 AWS SDK 用戶端。此舉能在日後 Lambda 執行時期更新時，最大限度實現[回溯相容性](runtimes-update.md#runtime-update-compatibility)。只有在您無法包含其他套件時 （例如，在 AWS CloudFormation 範本中使用 Lambda 主控台程式碼編輯器或內嵌程式碼時），才依賴執行時間提供的 SDK。

若要將 SDK 相依項新增至函數，請針對您需要的特定 SDK 用戶端使用 `npm install` 命令。在範例程式碼中，我們使用的是 [Amazon S3 用戶端](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/)。透過在包含 `package.json` 檔案的目錄中執行下列命令，即可新增這些相依項：

```
npm install @aws-sdk/client-s3
```

在函式程式碼中匯入所需的用戶端與命令，如範例函式所示：

```
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
```

然後，初始化 [Amazon S3 用戶端](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/)：

```
const s3Client = new S3Client();
```

在此範例中，我們在主要處理常式函式外部初始化 Amazon S3 用戶端，以免每次調用函式時都必須初始化該用戶端。初始化 SDK 用戶端之後，您就可以使用它來對該 AWS 服務進行 API 呼叫。此範例程式碼會呼叫 Amazon S3 [PutObject](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/command/PutObjectCommand/) API，如下所示：

```
const command = new PutObjectCommand({
    Bucket: bucketName,
    Key: key,
    Body: receiptContent
});
```

## 存取環境變數
<a name="nodejs-example-envvars"></a>

在處理常式程式碼中，您可以使用 `process.env` 來引用任意[環境變數](configuration-envvars.md)。在此範例中，我們使用下列程式碼行來引用定義的 `RECEIPT_BUCKET` 環境變數：

```
// Access environment variables
const bucketName = process.env.RECEIPT_BUCKET;
if (!bucketName) {
    throw new Error('RECEIPT_BUCKET environment variable is not set');
}
```

## 使用全域狀態
<a name="nodejs-handler-state"></a>

在首次調用函式之前，Lambda 會在[初始化階段](lambda-runtime-environment.md#runtimes-lifecycle-ib)執行靜態程式碼。在初始化期間建立的資源會在調用間隔期間保留在記憶體中，無需您在每次調用函式時都建立這些資源。

在範例程式碼中，S3 用戶端初始化程式碼位於主要處理常式外部。執行時期會在函式處理第一個事件之前初始化用戶端，且用戶端在所有調用中均可供重複使用。

## Node.js Lambda 函數的程式碼最佳實務
<a name="nodejs-best-practices"></a>

建置 Lambda 函式時，請遵循下列準則：
+ **區隔 Lambda 處理常式與您的核心邏輯。**能允許您製作更多可測單位的函式。
+ **控制函數部署套件內的相依性。** AWS Lambda 執行環境包含許多程式庫。對於 Node.js 和 Python 執行期，這些包括 AWS SDKs。若要啟用最新的一組功能與安全更新，Lambda 會定期更新這些程式庫。這些更新可能會為您的 Lambda 函數行為帶來細微的變更。若要完全掌控您函式所使用的相依性，請利用部署套件封裝您的所有相依性。
+ **最小化依存項目的複雜性。**偏好更簡易的框架，其可快速在[執行環境](lambda-runtime-environment.md)啟動時載入。
+ **將部署套件最小化至執行時間所必要的套件大小。**這能減少您的部署套件被下載與呼叫前解壓縮的時間。

**請利用執行環境重新使用來改看函式的效能。**在函式處理常式之外初始化 SDK 用戶端和資料庫連線，並在本機快取 `/tmp` 目錄中的靜態資產。由您函式的相同執行個體處理的後續叫用可以重複使用這些資源。這可藉由減少函數執行時間來節省成本。

若要避免叫用間洩漏潛在資料，請不要使用執行環境來儲存使用者資料、事件，或其他牽涉安全性的資訊。如果您的函式依賴無法存放在處理常式內記憶體中的可變狀態，請考慮為每個使用者建立個別函式或個別函式版本。

**使用 Keep-Alive 指令維持持續連線的狀態。**Lambda 會隨著時間的推移清除閒置連線。叫用函數時嘗試重複使用閒置連線將導致連線錯誤。若要維護持續連線，請使用與執行階段相關聯的 keep-alive (保持啟用) 指令。如需範例，請參閱[在 Node.js 中重複使用 Keep-Alive 的連線](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html)。

**使用[環境變數](configuration-envvars.md)將操作參數傳遞給您的函數。**例如，如果您正在寫入到 Amazon S3 儲存貯體，而非對您正在寫入的儲存貯體名稱進行硬式編碼，請將儲存貯體名稱設定為環境變數。

**避免在 Lambda 函數中使用遞迴調用**，其中函數會調用自己或啟動可能再次調用函數的程序。這會導致意外的函式呼叫量與升高的成本。若您看到意外的調用數量，當更新程式碼時，請立刻將函數的預留並行設為 `0`，以調節對函數的所有調用。

**請勿在您的 Lambda 函數程式碼中使用未記錄的非公有 API**。對於 AWS Lambda 受管執行期，Lambda 會定期將安全性和功能更新套用至 Lambda 的內部 APIs。這些內部 API 更新可能是向後不相容的，這會導致意外結果，例如若您的函數依賴於這些非公有 API，則叫用失敗。請參閱 [API 參考](https://docs.aws.amazon.com/lambda/latest/api/welcome.html)查看公開可用 API 的清單。

**撰寫等冪程式碼。**為函數撰寫等冪程式碼可確保採用相同方式來處理重複事件。程式碼應正確驗證事件並正常處理重複的事件。如需詳細資訊，請參閱 [How do I make my Lambda function idempotent?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/) (如何讓 Lambda 函數等冪？)。

# 使用 .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 中使用相同命令，您可以[安裝適用於 Linux 的 Windows 子系統](https://docs.microsoft.com/en-us/windows/wsl/install-win10)，以取得 Ubuntu 和 Bash 的 Windows 整合版本。

 請注意，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)皆包含第 3 版 SDK。若要使用第 2 版 SDK，須將該版 SDK 新增至 .zip 檔部署套件。若要查詢所用執行時期內含 SDK 的具體版本，請參閱[包含執行時期的 SDK 版本](lambda-nodejs.md#nodejs-sdk-included)。

 Lambda 會定期更新 Node.js 執行期中的 SDK 程式庫，以納入最新功能和安全升級。Lambda 也會將安全修補程式和更新套用至執行期中包含的其他程式庫。若要完全控制套件中的相依項，可以將任何包含執行期之相依項的偏好版本新增至部署套件。例如，如果想要針對 JavaScript 使用特定版本的 SDK，可以將其作為相依項包含在 .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>

 如果除了 Lambda 執行期中包含的程式庫之外，函數程式碼沒有其他相依項，則 .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>

如果函數程式碼相依於 Lambda 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` 目錄中。在此範例中，將安裝 適用於 Node.js 的 AWS X-Ray SDK。

   ```
   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 部署套件，來使用不同版本的 SDK。也可以將其包含在函數的 [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 套件內的個別資料夾中新增相依項。例如，可以將自訂模組新增至名為 `common` 的 .zip 套件中的資料夾。解壓縮並掛載您的 .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 主控台、 AWS Command Line Interface和 Lambda API 部署 .zip 套件。您也可以使用 AWS Serverless Application Model  (AWS SAM) 和  CloudFormation 建立並更新 Lambda 函數。

Lambda 的 .zip 部署套件大小上限為 250 MB (解壓縮)。請注意，此限制適用於您上傳的所有檔案 (包括任何 Lambda 層) 的大小總和。

Lambda 執行時間需有許可才能讀取部署套裝服務中的檔案。在 Linux 許可八進位標記法中，Lambda 需要 644 個許可 (rw-r--r--) 用於非可執行檔，以及 755 個許可 (rwxr-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 檔案小於 50 MB，您可以透過直接從本機電腦上傳檔案來建立或更新函數。若 .zip 檔案大於 50 MB，您必須先將套件上傳至 Amazon S3 儲存貯體。如需如何使用 將檔案上傳至 Amazon S3 儲存貯體的說明 AWS 管理主控台，請參閱 [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. 選擇 **Author from scratch** (從頭開始撰寫)。

1. 在**基本資訊**下，請執行下列動作：

   1. 在**函數名稱**中輸入函數名稱。

   1. 在**執行期**中選取要使用的執行期。

   1. (選用) 在**架構**中選擇要用於函數的指令集架構。預設架構值為 x86\$164。請確定函數的 .zip 部署套件與您選取的指令集架構相容。

1. (選用) 在**許可**下，展開**變更預設執行角色**。您可建立新的**執行角色**，或使用現有的角色。

1. 選擇 **Create function (建立函數)**。Lambda 會使用您選擇的執行期建立一個基本的「Hello world」函數。

**若要從本機電腦上傳 .zip 封存檔 (主控台)**

1. 在 Lambda 主控台的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)中選擇要上傳 .zip 檔案的函數。

1. 選取**程式碼**索引標籤。

1. 在**程式碼來源**窗格中選擇**上傳來源**。

1. 選擇 **.zip 檔案**。

1. 若要上傳 .zip 檔案，請執行下列操作：

   1. 選擇**上傳**，然後在檔案選擇器中選取您的 .zip 檔案。

   1. 選擇 **Open** (開啟)。

   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. 在 **DEPLOY** 區段中，選擇**部署**以更新函數的程式碼：  
![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

### 使用 建立和更新具有 .zip 檔案的函數 AWS CLI
<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 檔案小於 50 MB，則可以從本機建置電腦的檔案位置上傳 .zip 套件。若檔案較大，則必須先從 Amazon S3 儲存貯體上傳 .zip 套件。如需如何使用 將檔案上傳至 Amazon S3 儲存貯體的說明 AWS CLI，請參閱*AWS CLI 《 使用者指南*》中的[移動物件](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

**注意**  
如果您使用 從 Amazon S3 儲存貯體上傳 .zip 檔案 AWS CLI，儲存貯體必須與 AWS 區域 函數位於相同的 中。

 若要搭配 使用 .zip 檔案建立新的函數 AWS CLI，您必須指定下列項目：
+ 函數名稱 (`--function-name`)
+ 函數的執行期 (`--runtime`)
+ 函數[執行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)的 Amazon Resource Name (ARN) (`--role`)
+ 函數程式碼中處理常式方法的名稱 (`--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
```

 若要在 Amazon S3 儲存貯體中指定 .zip 檔案的位置，請使用如下列範例命令所示的 `--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
```

 若要在 Amazon S3 儲存貯體中指定 .zip 檔案的位置，請使用如下列範例命令所示的 `--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)

### 使用 建立和更新具有 .zip 檔案的函數 AWS SAM
<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 函數。若要使用 建立 Lambda 函數 AWS SAM，您可以將 .zip 檔案儲存在 Amazon S3 儲存貯體或建置機器的本機資料夾中。如需如何使用 將檔案上傳至 Amazon S3 儲存貯體的指示 AWS CLI，請參閱*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 套件。

 若要進一步了解如何在 中使用 .zip 檔案部署函數 AWS SAM，請參閱《 *AWS SAM 開發人員指南*》中的 [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)。

### 使用 建立和更新具有 .zip 檔案的函數 CloudFormation
<a name="nodejs-package-create-cfn"></a>

 您可以使用 CloudFormation 建立使用 .zip 檔案封存的 Lambda 函數。若要使用 .zip 檔案建立 Lambda 函數，您必須先將檔案上傳至 Amazon S3 儲存貯體。如需如何使用 將檔案上傳至 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 *

在您的 CloudFormation 範本中，`AWS::Lambda::Function`資源會指定您的 Lambda 函數。在本資源中設定下列屬性，以使用 .zip 封存檔建立函數：
+ `PackageType`：設定為 `Zip`
+ `Code`：在 `S3Bucket` 和 `S3Key` 欄位中輸入 Amazon S3 儲存貯體名稱和 .zip 檔案名稱。
+ `Runtime`：設定為所選執行期

 CloudFormation 產生的 .zip 檔案不能超過 4MB。若要進一步了解如何在 中使用 .zip 檔案部署函數 CloudFormation，請參閱*CloudFormation 《 使用者指南*》中的 [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)。

# 使用容器映像部署 Node.js Lambda 函數
<a name="nodejs-image"></a>

您可以透過三種方式為 Node.js Lambda 函數建置容器映像：
+ [使用 Node.js AWS 的基礎映像](#nodejs-image-instructions)

  [AWS  基礎映像](images-create.md#runtimes-images-lp)會預先載入語言執行期、用來管理 Lambda 與函數程式碼之間互動的執行期界面用戶端，以及用於本機測試的執行期界面模擬器。
+ [使用僅限 AWS 作業系統的基礎映像](images-create.md#runtimes-images-provided)

  [AWS 僅限作業系統的基礎映像](https://gallery.ecr.aws/lambda/provided)包含 Amazon Linux 發行版本和[執行時間界面模擬器](https://github.com/aws/aws-lambda-runtime-interface-emulator/)。這些映像常用於為編譯語言 (如 [Go](go-image.md#go-image-provided) 和 [Rust](lambda-rust.md)) 和 Lambda 不提供基礎映像的語言或語言版本 (如 Node.js 19) 建置容器映像。您還可以使用僅限作業系統的基礎映像來實作[自訂執行期](runtimes-custom.md)。若要使映像與 Lambda 相容，您必須在映像中加入[適用於 Node.js 的執行期介面用戶端](#nodejs-image-clients)。
+ [使用非AWS 基礎映像](#nodejs-image-clients)

  您可以使用其他容器登錄檔中的替代基礎映像 (例如 Alpine Linux 或 Debian)。您也可以使用組織建立的自訂映像。若要使映像與 Lambda 相容，您必須在映像中加入[適用於 Node.js 的執行期介面用戶端](#nodejs-image-clients)。

**提示**  
若要縮短 Lambda 容器函數變成作用中狀態所需的時間，請參閱 Docker 文件中的[使用多階段建置](https://docs.docker.com/build/building/multi-stage/)。若要建置有效率的容器映像，請遵循[撰寫 Dockerfiles 的最佳實務](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)。

本頁面會說明如何為 Lambda 建置、測試和部署容器映像。

**Topics**
+ [

## AWS Node.js 的基礎映像
](#nodejs-image-base)
+ [

## 使用 Node.js AWS 的基礎映像
](#nodejs-image-instructions)
+ [

## 透過執行期介面用戶端使用替代基礎映像
](#nodejs-image-clients)

## AWS Node.js 的基礎映像
<a name="nodejs-image-base"></a>

AWS 為 Node.js 提供下列基礎映像：


| Tags (標籤) | 執行期 | 作業系統 | Dockerfile | 棄用 | 
| --- | --- | --- | --- | --- | 
| 24 | Node.js 24 | Amazon Linux 2023 | [GitHub 上 Node.js 24 的 Dockerfile](https://github.com/aws/aws-lambda-base-images/blob/nodejs24.x/Dockerfile.nodejs24.x) |   2028 年 4 月 30 日   | 
| 22 | Node.js 22 | Amazon Linux 2023 | [Dockerfile for Node.js 22 on GitHub](https://github.com/aws/aws-lambda-base-images/blob/nodejs22.x/Dockerfile.nodejs22.x) |   2027 年 4 月 30 日   | 
| 20 | Node.js 20 | Amazon Linux 2023 | [Dockerfile for Node.js 20 on GitHub](https://github.com/aws/aws-lambda-base-images/blob/nodejs20.x/Dockerfile.nodejs20.x) |   2026 年 4 月 30 日   | 

Amazon ECR 儲存庫：[gallery.ecr.aws/lambda/nodejs](https://gallery.ecr.aws/lambda/nodejs)

Node.js 20 和更新版本的基礎映像是以 [Amazon Linux 2023 最小容器映像](https://docs.aws.amazon.com/linux/al2023/ug/minimal-container.html)為基礎。舊版基礎映像使用 Amazon Linux 2。與 Amazon Linux 2 相比，AL2023 具有多項優點，包括更小的部署足跡和更新版本的程式庫，如 `glibc`。

以 AL2023 為基礎的映像使用 `microdnf` (符號連結為 `dnf`) 而不是 `yum` 作為套件管理工具，後者是 Amazon Linux 2 中的預設套件管理工具。`microdnf` 是 `dnf` 的獨立實作。對於以 AL2023 為基礎的映像中包含的套件清單，請參閱 [Comparing packages installed on Amazon Linux 2023 Container Images](https://docs.aws.amazon.com/linux/al2023/ug/al2023-container-image-types.html) 中的 **Minimal Container** 欄。如需 AL2023 和 Amazon Linux 2 之間差異的詳細資訊，請參閱 AWS 運算部落格上的 [Introducing the Amazon Linux 2023 runtime for AWS Lambda](https://aws.amazon.com/blogs/compute/introducing-the-amazon-linux-2023-runtime-for-aws-lambda/)。

**注意**  
若要在本機執行AL2023-based映像，包括搭配 AWS Serverless Application Model (AWS SAM)，您必須使用 Docker 20.10.10 版或更新版本。

## 使用 Node.js AWS 的基礎映像
<a name="nodejs-image-instructions"></a>

### 先決條件
<a name="nodejs-image-prerequisites"></a>

若要完成本節中的步驟，您必須執行下列各項：
+ [AWS CLI 第 2 版](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (最低版本 25.0.0)
+ Docker [buildx 外掛程式](https://github.com/docker/buildx/blob/master/README.md)。
+ Node.js

### 從基礎映像建立映像
<a name="nodejs-image-create"></a>

**從 Node.js AWS 的基礎映像建立容器映像**

1. 建立專案的目錄，然後切換至該目錄。

   ```
   mkdir example
   cd example
   ```

1. 使用 `npm` 建立新 Node.js 專案。若要接受互動體驗中提供的預設選項，請按下 `Enter`。

   ```
   npm init
   ```

1. 建立稱為 `index.js` 的新檔案。您可以將下列範例函數程式碼新增至檔案進行測試，或使用您自己的函數程式碼。  
**Example CommonJS 處理常式**  

   ```
   exports.handler = async (event) => {
       const response = {
           statusCode: 200,
           body: JSON.stringify('Hello from Lambda!'),
       };
       return response;
   };
   ```

1. 如果您的函數依賴 以外的程式庫 適用於 JavaScript 的 AWS SDK，請使用 [npm](https://www.npmjs.com/) 將它們新增至您的套件。

1. 建立包含下列組態的新 Dockerfile。
   + 將 `FROM` 屬性設定為[基礎映像的 URI](https://gallery.ecr.aws/lambda/nodejs)。
   + 使用 COPY 命令將函數程式碼和執行時期相依項複製到 `{LAMBDA_TASK_ROOT}`，一個 [Lambda 定義的環境變數](configuration-envvars.md#configuration-envvars-runtime)。
   + 將 `CMD` 引數設定為 Lambda 函數處理常式。

   請注意，範例 Dockerfile 不包含 [USER 指令](https://docs.docker.com/reference/dockerfile/#user)。當您將容器映像部署到 Lambda 時，Lambda 會自動定義一個具有最低權限許可的預設 Linux 使用者。這與標準 Docker 行為不同，後者會在未提供 `USER` 指令時預設為 `root` 使用者。  
**Example Dockerfile**  

   ```
   FROM public.ecr.aws/lambda/nodejs:22
   
   # Copy function code
   COPY index.js ${LAMBDA_TASK_ROOT}
     
   # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
   CMD [ "index.handler" ]
   ```

1. 使用 [docker build](https://docs.docker.com/engine/reference/commandline/build/) 命令建立 Docker 映像檔。以下範例將映像命名為 `docker-image` 並為其提供 `test` [標籤](https://docs.docker.com/engine/reference/commandline/build/#tag)。若要使映像與 Lambda 相容，必須使用 `--provenance=false` 選項。

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**注意**  
此命令會指定 `--platform linux/amd64` 選項，確保無論建置機器的架構為何，您的容器都與 Lambda 執行環境相容。如果您打算使用 ARM64 指令集架構建立 Lambda 函數，務必將命令變更為改用 `--platform linux/arm64` 選項。

### (選用) 在本機測試映像
<a name="nodejs-image-test"></a>

1. 使用 **docker run** 命令啟動 Docker 影像。在此範例中，`docker-image` 為映像名稱，`test` 為標籤。

   ```
   docker run --platform linux/amd64 -p 9000:8080 docker-image:test
   ```

   此命令將映像作為容器執行，並在 `localhost:9000/2015-03-31/functions/function/invocations` 建立本機端點。
**注意**  
如果您為 ARM64 指令集架構建立 Docker 映像檔，請務必將`--platform linux/arm64`選項改用選項。`--platform linux/amd64`

1. 從新的終端機視窗，將事件張貼至本機端點。

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

   在 Linux 或 macOS 中，執行下列 `curl` 命令：

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
   ```

   此命令會透過空白事件調用函數，並傳回一個回應。如果您使用自己的函數程式碼而不是範例函數程式碼，則可能需要使用 JSON 承載調用該函數。範例：

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
   ```

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

   在 PowerShell 中，執行下列 `Invoke-WebRequest` 命令：

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
   ```

   此命令會透過空白事件調用函數，並傳回一個回應。如果您使用自己的函數程式碼而不是範例函數程式碼，則可能需要使用 JSON 承載調用該函數。範例：

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
   ```

------

1. 取得容器 ID。

   ```
   docker ps
   ```

1. 使用 [docker kill](https://docs.docker.com/engine/reference/commandline/kill/) 命令停止容器。在此命令中，將 `3766c4ab331c` 替換為上一步驟中的容器 ID。

   ```
   docker kill 3766c4ab331c
   ```

### 部署映像
<a name="nodejs-image-deploy"></a>

**若要將映像上傳至 Amazon ECR 並建立 Lambda 函數**

1. 使用 [get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html) 命令，向 Amazon ECR 登錄檔驗證 Docker CLI。
   + 將 `--region`值設定為您要 AWS 區域 在其中建立 Amazon ECR 儲存庫的 。
   + `111122223333` 以您的 AWS 帳戶 ID 取代 。

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. 使用 [create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html) 命令在 Amazon ECR 中建立儲存庫。

   ```
   aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
   ```
**注意**  
Amazon ECR 儲存庫必須與 Lambda 函數位於相同的 AWS 區域 中。

   如果成功，您將會看到以下回應：

   ```
   {
       "repository": {
           "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
           "registryId": "111122223333",
           "repositoryName": "hello-world",
           "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
           "createdAt": "2023-03-09T10:39:01+00:00",
           "imageTagMutability": "MUTABLE",
           "imageScanningConfiguration": {
               "scanOnPush": true
           },
           "encryptionConfiguration": {
               "encryptionType": "AES256"
           }
       }
   }
   ```

1. 從上一步驟的輸出中複製 `repositoryUri`。

1. 執行 [docker tag](https://docs.docker.com/engine/reference/commandline/tag/) 命令，將 Amazon ECR 儲存庫中的本機映像標記為最新版本。在此命令中：
   + `docker-image:test` 為 Docker 映像檔的名稱和[標籤](https://docs.docker.com/engine/reference/commandline/build/#tag)。這是您在 `docker build` 命令中指定的映像名稱和標籤。
   + 將 `<ECRrepositoryUri>` 替換為複製的 `repositoryUri`。確保在 URI 的末尾包含 `:latest`。

   ```
   docker tag docker-image:test <ECRrepositoryUri>:latest
   ```

   範例：

   ```
   docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. 執行 [docker push](https://docs.docker.com/engine/reference/commandline/push/) 命令，將本機映像部署至 Amazon ECR 儲存庫。確保在儲存庫 URI 的末尾包含 `:latest`。

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. [建立函數的執行角色](lambda-intro-execution-role.md#permissions-executionrole-api) (若您還沒有的話)。在下一個步驟中您需要角色的 Amazon Resource Name (ARN)。

1. 建立 Lambda 函數。對於 `ImageUri`，從之前的設定中指定儲存庫 URI。確保在 URI 的末尾包含 `:latest`。

   ```
   aws lambda create-function \
     --function-name hello-world \
     --package-type Image \
     --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**注意**  
只要映像與 Lambda 函數位於相同的區域，您就可以使用不同 AWS 帳戶中的映像來建立函數。如需詳細資訊，請參閱[Amazon ECR 跨帳戶許可](images-create.md#configuration-images-xaccount-permissions)。

1. 調用函數。

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   您應該看到如下回應：

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. 若要查看函數的輸出，請檢查 `response.json` 檔案。

若要更新函數程式碼，您必須再次建置映像、將新映像上傳到 Amazon ECR 存放庫，然後使用 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 命令將映像部署到 Lambda 函數。

Lambda 會將映像標籤解析為特定映像摘要。這表示如果您將用來部署函數的映像標籤指向 Amazon ECR 中的新映像，Lambda 不會自動更新函數以使用新映像。

若要將新映像部署至相同的 Lambda 函數，必須使用 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 命令，即使 Amazon ECR 中的映像標籤保持不變亦如此。在以下範例中，`--publish` 選項會使用更新的容器映像來建立新的函數版本。

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

## 透過執行期介面用戶端使用替代基礎映像
<a name="nodejs-image-clients"></a>

如果您使用[僅限作業系統的基礎映像](images-create.md#runtimes-images-provided)或替代的基礎映像，則必須在映像中加入執行期介面用戶端。執行期介面用戶端會讓您擴充 [Runtime API](runtimes-api.md)，管理 Lambda 與函數程式碼之間的互動。

使用 npm 套件管理員安裝 [Node.js 執行期界面用戶端](https://www.npmjs.com/package/aws-lambda-ric)：

```
npm install aws-lambda-ric
```

您還可以從 GitHub 下載 [Node.js 執行時間界面用戶端](https://github.com/aws/aws-lambda-nodejs-runtime-interface-client)。

下列範例示範如何使用非AWS 基礎映像建置 Node.js 的容器映像。範例 Dockerfile 使用 `bookworm` 基礎映像。Dockerfile 包含執行期界面用戶端。

### 先決條件
<a name="nodejs-alt-prerequisites"></a>

若要完成本節中的步驟，您必須執行下列各項：
+ [AWS CLI 第 2 版](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (最低版本 25.0.0)
+ Docker [buildx 外掛程式](https://github.com/docker/buildx/blob/master/README.md)。
+ Node.js

### 使用替代基礎映像建立映像
<a name="nodejs-alt-create"></a>

**從非AWS 基礎映像建立容器映像**

1. 建立專案的目錄，然後切換至該目錄。

   ```
   mkdir example
   cd example
   ```

1. 使用 `npm` 建立新 Node.js 專案。若要接受互動體驗中提供的預設選項，請按下 `Enter`。

   ```
   npm init
   ```

1. 建立稱為 `index.js` 的新檔案。您可以將下列範例函數程式碼新增至檔案進行測試，或使用您自己的函數程式碼。  
**Example CommonJS 處理常式**  

   ```
   exports.handler = async (event) => {
       const response = {
           statusCode: 200,
           body: JSON.stringify('Hello from Lambda!'),
       };
       return response;
   };
   ```

1. 建立新的 Dockerfile。下列 Dockerfile 使用 `bookworm` 基礎映像，而非 [AWS  基礎映像](images-create.md#runtimes-images-lp)。Dockerfile 包含[執行期介面用戶端](https://www.npmjs.com/package/aws-lambda-ric)，可讓映像與 Lambda 相容。Dockerfile 使用[多階段建置](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#use-multi-stage-builds)。第一階段會建立組建映像，這是安裝函數相依項的標準 Node.js 環境。第二階段會建立更細微的映像，包含函數程式碼及其相依項。這會減少最終映像的大小。
   + 將 `FROM` 屬性設為基礎映像識別符。
   + 使用 `COPY` 命令複製函數程式碼和執行期相依項。
   + 將 `ENTRYPOINT` 設為您希望 Docker 容器在啟動時執行的模組。在此案例中，模組是執行期界面用戶端。
   + 將 `CMD` 引數設定為 Lambda 函數處理常式。

   請注意，範例 Dockerfile 不包含 [USER 指令](https://docs.docker.com/reference/dockerfile/#user)。當您將容器映像部署到 Lambda 時，Lambda 會自動定義一個具有最低權限許可的預設 Linux 使用者。這與標準 Docker 行為不同，後者會在未提供 `USER` 指令時預設為 `root` 使用者。  
**Example Dockerfile**  

   ```
   # Define custom function directory
   ARG FUNCTION_DIR="/function"
   
   FROM node:20-bookworm as build-image
   
   # Include global arg in this stage of the build
   ARG FUNCTION_DIR
   
   # Install build dependencies
   RUN apt-get update && \
       apt-get install -y \
       g++ \
       make \
       cmake \
       unzip \
       libcurl4-openssl-dev
   
   # Copy function code
   RUN mkdir -p ${FUNCTION_DIR}
   COPY . ${FUNCTION_DIR}
   
   WORKDIR ${FUNCTION_DIR}
   
   # Install Node.js dependencies
   RUN npm install
   
   # Install the runtime interface client
   RUN npm install aws-lambda-ric
   
   # Grab a fresh slim copy of the image to reduce the final size
   FROM node:20-bookworm-slim
   
   # Required for Node runtimes which use npm@8.6.0+ because
   # by default npm writes logs under /home/.npm and Lambda fs is read-only
   ENV NPM_CONFIG_CACHE=/tmp/.npm
   
   # Include global arg in this stage of the build
   ARG FUNCTION_DIR
   
   # Set working directory to function root directory
   WORKDIR ${FUNCTION_DIR}
   
   # Copy in the built dependencies
   COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}
   
   # Set runtime interface client as default command for the container runtime
   ENTRYPOINT ["/usr/local/bin/npx", "aws-lambda-ric"]
   # Pass the name of the function handler as an argument to the runtime
   CMD ["index.handler"]
   ```

1. 使用 [docker build](https://docs.docker.com/engine/reference/commandline/build/) 命令建立 Docker 映像檔。以下範例將映像命名為 `docker-image` 並為其提供 `test` [標籤](https://docs.docker.com/engine/reference/commandline/build/#tag)。若要使映像與 Lambda 相容，必須使用 `--provenance=false` 選項。

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**注意**  
此命令會指定 `--platform linux/amd64` 選項，確保無論建置機器的架構為何，您的容器都與 Lambda 執行環境相容。如果您打算使用 ARM64 指令集架構建立 Lambda 函數，務必將命令變更為改用 `--platform linux/arm64` 選項。

### (選用) 在本機測試映像
<a name="nodejs-alt-test"></a>

使用 [執行期界面模擬器](https://github.com/aws/aws-lambda-runtime-interface-emulator/) 以在本機測試映像。您可以[將模擬器建置到映像中](https://github.com/aws/aws-lambda-runtime-interface-emulator/?tab=readme-ov-file#build-rie-into-your-base-image)，也可以使用以下步驟，將其安裝在本機電腦。

**若要在本機電腦上安裝並執行執行期介面模擬器**

1. 在您的專案目錄中執行以下命令，從 GitHub 下載執行期介面模擬器 (x86-64 架構)，並安裝在本機電腦上。

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

   ```
   mkdir -p ~/.aws-lambda-rie && \
       curl -Lo ~/.aws-lambda-rie/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \
       chmod +x ~/.aws-lambda-rie/aws-lambda-rie
   ```

   若要安裝 arm64 模擬器，請將上一個命令中的 GitHub 儲存庫 URL 替換為以下內容：

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

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

   ```
   $dirPath = "$HOME\.aws-lambda-rie"
   if (-not (Test-Path $dirPath)) {
       New-Item -Path $dirPath -ItemType Directory
   }
         
   $downloadLink = "https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie"
   $destinationPath = "$HOME\.aws-lambda-rie\aws-lambda-rie"
   Invoke-WebRequest -Uri $downloadLink -OutFile $destinationPath
   ```

   若要安裝 arm64 模擬器，請將 `$downloadLink` 更換為下列項目：

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

------

1. 使用 **docker run** 命令啟動 Docker 影像。注意下列事項：
   + `docker-image` 是映像名稱，而 `test` 是標籤。
   + `/usr/local/bin/npx aws-lambda-ric index.handler` 是 Dockerfile 中的 `ENTRYPOINT`，後面接著 `CMD`。

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

   ```
   docker run --platform linux/amd64 -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \
       --entrypoint /aws-lambda/aws-lambda-rie \
       docker-image:test \
           /usr/local/bin/npx aws-lambda-ric index.handler
   ```

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

   ```
   docker run --platform linux/amd64 -d -v "$HOME\.aws-lambda-rie:/aws-lambda" -p 9000:8080 `
   --entrypoint /aws-lambda/aws-lambda-rie `
   docker-image:test `
       /usr/local/bin/npx aws-lambda-ric index.handler
   ```

------

   此命令將映像作為容器執行，並在 `localhost:9000/2015-03-31/functions/function/invocations` 建立本機端點。
**注意**  
如果您為 ARM64 指令集架構建立 Docker 映像檔，請務必將`--platform linux/arm64`選項改用選項。`--platform linux/amd64`

1. 將事件張貼至本機端點。

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

   在 Linux 或 macOS 中，執行下列 `curl` 命令：

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
   ```

   此命令會透過空白事件調用函數，並傳回一個回應。如果您使用自己的函數程式碼而不是範例函數程式碼，則可能需要使用 JSON 承載調用該函數。範例：

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
   ```

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

   在 PowerShell 中，執行下列 `Invoke-WebRequest` 命令：

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
   ```

   此命令會透過空白事件調用函數，並傳回一個回應。如果您使用自己的函數程式碼而不是範例函數程式碼，則可能需要使用 JSON 承載調用該函數。範例：

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
   ```

------

1. 取得容器 ID。

   ```
   docker ps
   ```

1. 使用 [docker kill](https://docs.docker.com/engine/reference/commandline/kill/) 命令停止容器。在此命令中，將 `3766c4ab331c` 替換為上一步驟中的容器 ID。

   ```
   docker kill 3766c4ab331c
   ```

### 部署映像
<a name="nodejs-alt-deploy"></a>

**若要將映像上傳至 Amazon ECR 並建立 Lambda 函數**

1. 使用 [get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html) 命令，向 Amazon ECR 登錄檔驗證 Docker CLI。
   + 將 `--region`值設定為您要 AWS 區域 在其中建立 Amazon ECR 儲存庫的 。
   + `111122223333` 以您的 AWS 帳戶 ID 取代 。

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. 使用 [create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html) 命令在 Amazon ECR 中建立儲存庫。

   ```
   aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
   ```
**注意**  
Amazon ECR 儲存庫必須與 Lambda 函數位於相同的 AWS 區域 中。

   如果成功，您將會看到以下回應：

   ```
   {
       "repository": {
           "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
           "registryId": "111122223333",
           "repositoryName": "hello-world",
           "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
           "createdAt": "2023-03-09T10:39:01+00:00",
           "imageTagMutability": "MUTABLE",
           "imageScanningConfiguration": {
               "scanOnPush": true
           },
           "encryptionConfiguration": {
               "encryptionType": "AES256"
           }
       }
   }
   ```

1. 從上一步驟的輸出中複製 `repositoryUri`。

1. 執行 [docker tag](https://docs.docker.com/engine/reference/commandline/tag/) 命令，將 Amazon ECR 儲存庫中的本機映像標記為最新版本。在此命令中：
   + `docker-image:test` 為 Docker 映像檔的名稱和[標籤](https://docs.docker.com/engine/reference/commandline/build/#tag)。這是您在 `docker build` 命令中指定的映像名稱和標籤。
   + 將 `<ECRrepositoryUri>` 替換為複製的 `repositoryUri`。確保在 URI 的末尾包含 `:latest`。

   ```
   docker tag docker-image:test <ECRrepositoryUri>:latest
   ```

   範例：

   ```
   docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. 執行 [docker push](https://docs.docker.com/engine/reference/commandline/push/) 命令，將本機映像部署至 Amazon ECR 儲存庫。確保在儲存庫 URI 的末尾包含 `:latest`。

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. [建立函數的執行角色](lambda-intro-execution-role.md#permissions-executionrole-api) (若您還沒有的話)。在下一個步驟中您需要角色的 Amazon Resource Name (ARN)。

1. 建立 Lambda 函數。對於 `ImageUri`，從之前的設定中指定儲存庫 URI。確保在 URI 的末尾包含 `:latest`。

   ```
   aws lambda create-function \
     --function-name hello-world \
     --package-type Image \
     --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**注意**  
只要映像與 Lambda 函數位於相同的區域，您就可以使用不同 AWS 帳戶中的映像來建立函數。如需詳細資訊，請參閱[Amazon ECR 跨帳戶許可](images-create.md#configuration-images-xaccount-permissions)。

1. 調用函數。

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   您應該看到如下回應：

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. 若要查看函數的輸出，請檢查 `response.json` 檔案。

若要更新函數程式碼，您必須再次建置映像、將新映像上傳到 Amazon ECR 存放庫，然後使用 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 命令將映像部署到 Lambda 函數。

Lambda 會將映像標籤解析為特定映像摘要。這表示如果您將用來部署函數的映像標籤指向 Amazon ECR 中的新映像，Lambda 不會自動更新函數以使用新映像。

若要將新映像部署至相同的 Lambda 函數，必須使用 [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) 命令，即使 Amazon ECR 中的映像標籤保持不變亦如此。在以下範例中，`--publish` 選項會使用更新的容器映像來建立新的函數版本。

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

# 對 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) 程式庫的層。建立層之後，您可以部署並調用相應的函式，驗證層是否如預期那樣運作。

# 使用 Lambda 內容物件擷取 Node.js 函數資訊
<a name="nodejs-context"></a>

當 Lambda 執行您的函數時，它會將內容物件傳遞至[處理常式](nodejs-handler.md)。此物件提供的方法和各項屬性提供了有關調用、函式以及執行環境的資訊。

**內容方法**
+ `getRemainingTimeInMillis()` - 傳回執行逾時前剩餘的毫秒數。

**內容屬性**
+ `functionName` – Lambda 函數的名稱。
+ `functionVersion` – 函數的[版本](configuration-versions.md)。
+ `invokedFunctionArn` - 用於調用此函數的 Amazon Resource Name (ARN)。指出調用者是否指定版本號或別名。
+ `memoryLimitInMB` - 分配給函數的記憶體數量。
+ `awsRequestId` - 調用請求的識別符。
+ `logGroupName` - 函數的日誌群組。
+ `logStreamName` - 函數執行個體的記錄串流。
+ `identity` - (行動應用程式) 已授權請求的 Amazon Cognito 身分的相關資訊。
  + `cognitoIdentityId` - 已驗證的 Amazon Cognito 身分。
  + `cognitoIdentityPoolId` - 授權調用的 Amazon Cognito 身分集區。
+ `clientContext` - (行動應用程式) 用戶端應用程式提供給 Lambda 的用戶端內容。
  + `client.installation_id`
  + `client.app_title`
  + `client.app_version_name`
  + `client.app_version_code`
  + `client.app_package_name`
  + `env.platform_version`
  + `env.platform`
  + `env.make`
  + `env.model`
  + `env.locale`
  + `custom` - 用戶端應用程式所設定的自訂值。
+ `callbackWaitsForEmptyEventLoop` – 根據預設 (`true`)，在使用回呼型函數處理常式時，Lambda 會在回呼執行後等待事件迴圈為空，再結束函數叫用。將 設定為 `false`以傳送回應，並在回呼執行後立即結束調用，而不是等待事件迴圈為空。未處理的事件會在下次調用期間繼續執行。請注意，Lambda 僅支援 Node.js 22 和更早執行時間的回呼式函數處理常式。

以下範例函式紀錄內文資訊和傳回日誌的位置。

**Example index.js 檔案**  

```
exports.handler = async function(event, context) {
  console.log('Remaining time: ', context.getRemainingTimeInMillis())
  console.log('Function name: ', context.functionName)
  return context.logStreamName
}
```

# 記錄和監控 Node.js Lambda 函數
<a name="nodejs-logging"></a>

AWS Lambda 會自動代表您監控 Lambda 函數，並將日誌傳送至 Amazon CloudWatch。您的 Lambda 函數隨附有 CloudWatch Logs 日誌群組，且函數的每一執行個體各有一個日誌串流。Lambda 執行期環境會將每次調用的詳細資訊傳送至日誌串流，並且轉傳來自函數程式碼的日誌及其他輸出。如需詳細資訊，請參閱[將 Lambda 函式日誌傳送至 CloudWatch Logs](monitoring-cloudwatchlogs.md)。

此頁面說明如何從 Lambda 函數的程式碼產生日誌輸出，並使用 AWS Command Line Interface、Lambda 主控台或 CloudWatch 主控台存取日誌。

**Topics**
+ [

## 建立傳回日誌的函數
](#node-logging-output)
+ [

## 搭配 Node.js 使用 Lambda 進階日誌控制項
](#node-js-logging-advanced)
+ [

## 在 Lambda 主控台檢視日誌
](#nodejs-logging-console)
+ [

## 在 CloudWatch 主控台中檢視 記錄
](#nodejs-logging-cwconsole)
+ [

## 使用 AWS Command Line Interface (AWS CLI) 檢視日誌
](#nodejs-logging-cli)
+ [

## 刪除日誌
](#nodejs-logging-delete)

## 建立傳回日誌的函數
<a name="node-logging-output"></a>

若要由您的函式程式碼輸出日誌，您可以在[主控台物件](https://developer.mozilla.org/en-US/docs/Web/API/Console)上使用方法，或任何能寫入 `stdout` 或 `stderr` 的記錄程式庫。下列範例會記錄環境變數和事件物件的值。

**注意**  
我們建議您在記錄輸入時使用輸入驗證和輸出編碼等技術。如果您直接記錄輸入資料，攻擊者可能會使用您的程式碼來使竄改難以被偵測、偽造日誌項目或繞過日誌監控。如需詳細資訊，請參閱*常見弱點列舉*中的 [Improper Output Neutralization for Logs](https://cwe.mitre.org/data/definitions/117.html)。

**Example index.js 檔案 - 記錄**  

```
exports.handler = async function(event, context) {
  console.log("ENVIRONMENT VARIABLES\n" + JSON.stringify(process.env, null, 2))
  console.info("EVENT\n" + JSON.stringify(event, null, 2))
  console.warn("Event not processed.")
  return context.logStreamName
}
```

**Example 記錄格式**  

```
START RequestId: c793869b-ee49-115b-a5b6-4fd21e8dedac Version: $LATEST
2019-06-07T19:11:20.562Z	c793869b-ee49-115b-a5b6-4fd21e8dedac	INFO	ENVIRONMENT VARIABLES
{
  "AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
  "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/my-function",
  "AWS_LAMBDA_LOG_STREAM_NAME": "2019/06/07/[$LATEST]e6f4a0c4241adcd70c262d34c0bbc85c",
  "AWS_EXECUTION_ENV": "AWS_Lambda_nodejs12.x",
  "AWS_LAMBDA_FUNCTION_NAME": "my-function",
  "PATH": "/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin",
  "NODE_PATH": "/opt/nodejs/node10/node_modules:/opt/nodejs/node_modules:/var/runtime/node_modules",
  ...
}
2019-06-07T19:11:20.563Z	c793869b-ee49-115b-a5b6-4fd21e8dedac	INFO	EVENT
{
  "key": "value"
}
2019-06-07T19:11:20.564Z	c793869b-ee49-115b-a5b6-4fd21e8dedac	WARN	Event not processed.
END RequestId: c793869b-ee49-115b-a5b6-4fd21e8dedac
REPORT RequestId: c793869b-ee49-115b-a5b6-4fd21e8dedac	Duration: 128.83 ms	Billed Duration: 296 ms	Memory Size: 128 MB	Max Memory Used: 74 MB	Init Duration: 166.62 ms	XRAY TraceId: 1-5d9d007f-0a8c7fd02xmpl480aed55ef0	SegmentId: 3d752xmpl1bbe37e	Sampled: true
```

Node.js 執行時間會記錄每次呼叫的 `START`、`END` 和 `REPORT` 行。它會將時間戳記、請求 ID 和日誌層級新增到函式所記錄的每個項目。報告明細行提供下列詳細資訊。

**REPORT 行資料欄位**
+ **RequestId** - 進行調用的唯一請求 ID。
+ **持續時間** - 函數的處理常式方法處理事件所花費的時間量。
+ **計費持續時間** - 調用的計費時間量。
+ **記憶體大小** - 分配給函數的記憶體數量。
+ **使用的記憶體上限** - 函數所使用的記憶體數量。當調用共用執行環境時，Lambda 會報告所有調用使用的記憶體上限。此行為可能會導致報告值高於預期值。
+ **初始化持續時間** - 對於第一個提供的請求，這是執行期載入函數並在處理常式方法之外執行程式碼所花費的時間量。
+ **XRAY TraceId** - 對於追蹤的請求，這是 [AWS X-Ray 追蹤 ID](services-xray.md)。
+ **SegmentId** - 對於追蹤的請求，這是 X-Ray 區段 ID。
+ **已取樣** - 對於追蹤的請求，這是取樣結果。

您可以在 Lambda 主控台、CloudWatch Logs 主控台或命令列中檢視日誌。

## 搭配 Node.js 使用 Lambda 進階日誌控制項
<a name="node-js-logging-advanced"></a>

為了讓您更妥善地控制擷取、處理和使用函數日誌的方式，您可以針對支援的 Node.js 執行期設定下列記錄選項：
+ **日誌格式** - 在純文字和結構化 JSON 格式之間為您的日誌進行選擇
+ **日誌層級** - 對於 JSON 格式的日誌，請選擇 Lambda 傳送到 Amazon CloudWatch 的日誌之詳細等級，例如 ERROR、DEBUG 或 INFO
+ **日誌群組** - 選擇您的函數將日誌傳送到的 CloudWatch 日誌群組

如需這些日誌選項的詳細資訊，以及如何設定函數以使用這些選項的說明，請參閱 [設定 Lambda 函數的進階日誌記錄控制項](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)。

若要使用日誌格式和日誌層級選項與 Node.js Lambda 函數搭配使用，請參閱以下各章節中的指引。

### 搭配 Node.js 使用結構化的 JSON 日誌
<a name="nodejs-logging-advanced-JSON"></a>

如果您為函數的日誌格式選取 JSON，Lambda 會使用 `console.trace`、`console.debug`、`console.log`、`console.info`、`console.error` 和 `console.warn` 的主控台方法，將日誌輸出以結構化 JSON 形式傳送至 CloudWatch。每個 JSON 日誌物件都包含至少四個鍵值對，其中包含下列索引鍵：
+ `"timestamp"` - 產生日誌訊息的時間
+ `"level"` - 指派給訊息的日誌層級
+ `"message"` - 日誌訊息的內容
+ `"requestId"` - 進行調用的唯一請求 ID。

依據您的函數使用的記錄方法，此 JSON 物件還可能包含其他鍵值對。例如，如果您的函數使用 `console` 方法來記錄使用多個引數的錯誤物件，JSON 物件將包含具有索引鍵 `errorMessage`、`errorType` 和 `stackTrace` 的額外鍵值對。

如果您的程式碼已使用 Powertools 等其他日誌程式庫 AWS Lambda來產生 JSON 結構化日誌，則不需要進行任何變更。Lambda 不會對任何已經進行 JSON 編碼的日誌進行雙重編碼，因此您函數的應用程式日誌將繼續像以前一樣被擷取。

如需使用 Powertools AWS Lambda 記錄套件在 Node.js 執行時間中建立 JSON 結構化日誌的詳細資訊，請參閱 [記錄和監控 TypeScript Lambda 函數](typescript-logging.md)。

#### JSON 格式日誌輸出範例
<a name="nodejs-logging-examples"></a>

下列範例顯示當您將函數的日誌格式設為 JSON 時，如何在 CloudWatch Logs 擷取使用單個和多個引數的 `console` 方法產生的各種日誌輸出。

第一個範例使用 `console.error` 方法輸出簡單字串。

**Example Node.js 日誌程式碼**  

```
export const handler = async (event) => {
  console.error("This is a warning message");
  ...
}
```

**Example JSON 日誌記錄**  

```
{
    "timestamp":"2025-11-01T00:21:51.358Z",
    "level":"ERROR",
    "message":"This is a warning message",
    "requestId":"93f25699-2cbf-4976-8f94-336a0aa98c6f"
}
```

您還可以透過 `console` 方法使用單個或多個引數輸出結構更複雜的日誌訊息。在下一個範例中，您將使用 `console.log` 與單個引數輸出兩個鍵值對。請注意，在 Lambda 傳送至 CloudWatch Logs 的 JSON 物件中，`"message"` 欄位未被字串化。

**Example Node.js 日誌程式碼**  

```
export const handler = async (event) => {
  console.log({data: 12.3, flag: false});
  ...
}
```

**Example JSON 日誌記錄**  

```
{
    "timestamp": "2025-12-08T23:21:04.664Z",
    "level": "INFO",
    "requestId": "405a4537-9226-4216-ac59-64381ec8654a",
    "message": {
        "data": 12.3,
        "flag": false
    }
}
```

在下一個範例中，您要再次使用 `console.log` 方法建立日誌輸出。這一次，該方法使用兩個引數、一個包含兩個鍵值對的映射和一個識別字串。請注意，在這種情況下，由於您提供了兩個引數，Lambda 會對 `"message"` 欄位進行字串化。

**Example Node.js 日誌程式碼**  

```
export const handler = async (event) => {
  console.log('Some object - ', {data: 12.3, flag: false});
  ...
}
```

**Example JSON 日誌記錄**  

```
{
    "timestamp": "2025-12-08T23:21:04.664Z",
    "level": "INFO",
    "requestId": "405a4537-9226-4216-ac59-64381ec8654a",
    "message": "Some object -  { data: 12.3, flag: false }"
}
```

Lambda 會指派使用 `console.log` 日誌層級 INFO 產生的輸出。

最後一個範例顯示如何使用 `console` 方法將錯誤物件輸出至 CloudWatch Logs。請注意，當您使用多個引數記錄錯誤物件時，Lambda 會新增 `errorMessage`、`errorType` 和 `stackTrace` 欄位至日誌輸出。

**Example Node.js 日誌程式碼**  

```
export const handler = async (event) => {
  let e1 = new ReferenceError("some reference error");
  let e2 = new SyntaxError("some syntax error");
  console.log(e1);
  console.log("errors logged - ", e1, e2);
};
```

**Example JSON 日誌記錄**  

```
{
    "timestamp": "2025-12-08T23:21:04.632Z",
    "level": "INFO",
    "requestId": "405a4537-9226-4216-ac59-64381ec8654a",
    "message": {
        "errorType": "ReferenceError",
        "errorMessage": "some reference error",
        "stackTrace": [
            "ReferenceError: some reference error",
            "    at Runtime.handler (file:///var/task/index.mjs:3:12)",
            "    at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1173:29)"
        ]
    }
}

{
    "timestamp": "2025-12-08T23:21:04.646Z",
    "level": "INFO",
    "requestId": "405a4537-9226-4216-ac59-64381ec8654a",
    "message": "errors logged -  ReferenceError: some reference error\n    at Runtime.handler (file:///var/task/index.mjs:3:12)\n    at Runtime.handleOnceNonStreaming 
    (file:///var/runtime/index.mjs:1173:29) SyntaxError: some syntax error\n    at Runtime.handler (file:///var/task/index.mjs:4:12)\n    at Runtime.handleOnceNonStreaming 
    (file:///var/runtime/index.mjs:1173:29)",
    "errorType": "ReferenceError",
    "errorMessage": "some reference error",
    "stackTrace": [
        "ReferenceError: some reference error",
        "    at Runtime.handler (file:///var/task/index.mjs:3:12)",
        "    at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1173:29)"
    ]
}
```

記錄多個錯誤類型時，會從提供給 `console` 方法的第一個錯誤類型中擷取額外欄位 `errorMessage`、`errorType` 和 `stackTrace`。

### 搭配結構化 JSON 日誌使用內嵌指標格式 (EMF) 用戶端程式庫
<a name="nodejs-logging-advanced-emf"></a>

AWS 提供 Node.js 的開放原始碼用戶端程式庫，可用來建立[內嵌指標格式 ](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Libraries.html)(EMF) 日誌。如果您有使用這些程式庫的現有函數，並將函數的記錄格式變更為 JSON0，那麼CloudWatch 可能無法再識別程式碼所發出的指標。

如果您的程式碼目前直接使用 `console.log`或使用 Powertools for AWS Lambda (TypeScript) 發出 EMF 日誌，則如果您將函數的日誌格式變更為 JSON，CloudWatch 也無法剖析這些日誌。

**重要**  
為了確保 CloudWatch 能夠繼續正確剖析函數的 EMF 日誌檔，請將您的 [EMF](https://www.npmjs.com/package/aws-embedded-metrics) 和 [Powertools for AWS Lambda](https://github.com/aws-powertools/powertools-lambda-typescript) 程式庫更新為最新版本。如果切換到 JSON 日誌格式，我們也建議您進行測試，以確保與函數的內嵌指標相容。如果您的程式碼直接使用 `console.log` 發出 EMF 記錄，請變更您的程式碼以將這些指標直接輸出至 `stdout`，如下列程式碼範例所示。

**Example 發出內嵌指標至 `stdout` 的程式碼**  

```
process.stdout.write(JSON.stringify(
    {
        "_aws": {
            "Timestamp": Date.now(),
            "CloudWatchMetrics": [{
                "Namespace": "lambda-function-metrics",
                "Dimensions": [["functionVersion"]],
                "Metrics": [{
                    "Name": "time",
                    "Unit": "Milliseconds",
                    "StorageResolution": 60
                }]
            }]
        },
        "functionVersion": "$LATEST",
        "time": 100,
        "requestId": context.awsRequestId
    }
) + "\n")
```

### 搭配 Node.js 使用日誌層級篩選
<a name="nodejs-logging-advanced-level"></a>

若要 AWS Lambda 讓 根據應用程式日誌層級篩選您的應用程式日誌，您的函數必須使用 JSON 格式的日誌。您可以透過兩種方式達成此操作：
+ 使用標準主控台方法建立日誌輸出，並將函數設定為使用 JSON 日誌格式。 AWS Lambda 然後， 會使用中所述的 JSON 物件中的「層級」鍵值對來篩選日誌輸出[搭配 Node.js 使用結構化的 JSON 日誌](#nodejs-logging-advanced-JSON)。若要瞭解如何設定函數的日誌格式，請參閱 [設定 Lambda 函數的進階日誌記錄控制項](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)。
+ 使用其他日誌程式庫或方法，在您的程式碼中建立 JSON 結構化日誌，其中包含定義日誌輸出層級的「層級」索引鍵值組。例如，您可以使用 Powertools for AWS Lambda 從程式碼產生 JSON 結構化日誌輸出。請參閱 [記錄和監控 TypeScript Lambda 函數](typescript-logging.md) 以瞭解有關在 Node.js 執行期使用 Powertools 的更多資訊。

  若要讓 Lambda 篩選函數的日誌，您還必須在 JSON 日誌輸出中包含 `"timestamp"` 索引鍵值組。必須以有效的 [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) 時間戳記格式指定時間。如果您沒有提供有效的時間戳記，Lambda 會為日誌指派層級 INFO，並為您新增時間戳記。

當您將函數設定為使用日誌層級篩選時，請從下列選項中選取 AWS Lambda 您要傳送至 CloudWatch Logs 的日誌層級：


| 日誌層級 | 標準用量 | 
| --- | --- | 
| TRACE (大多數詳細資訊) | 用於追蹤程式碼執行路徑的最精細資訊 | 
| DEBUG | 系統偵錯的詳細資訊 | 
| INFO | 記錄函數正常操作的訊息 | 
| WARN | 有關可能導致未解決意外行為的潛在錯誤的消息 | 
| ERROR | 有關阻止程式碼按預期執行的問題的訊息 | 
| FATAL (最少詳細資訊) | 有關導致應用程式停止運作的嚴重錯誤訊息 | 

Lambda 會在選取的層級 (含) 和更低層級傳送日誌給 CloudWatch。例如，如果您設定 WARN 的日誌層級，Lambda 會傳送相對應於 WARN、ERROR 和 FATAL 層級的日誌檔。

## 在 Lambda 主控台檢視日誌
<a name="nodejs-logging-console"></a>

您可以在調用 Lambda 函數之後，使用 Lambda 主控台來檢視日誌輸出。

如果可以從內嵌**程式碼**編輯器測試您的程式碼，您會在**執行結果**中找到日誌。使用主控台測試功能以調用函數時，您會在**詳細資訊**區段找到**日誌輸出**。

## 在 CloudWatch 主控台中檢視 記錄
<a name="nodejs-logging-cwconsole"></a>

您可以使用 Amazon CloudWatch 主控台來檢視所有 Lambda 函數調用的日誌。

**若要在 CloudWatch 主控台上檢視日誌**

1. 在 CloudWatch 主控台上開啟[日誌群組頁面](https://console.aws.amazon.com/cloudwatch/home?#logs:)。

1. 選擇您的函數的日誌群組 (**/aws/lambda/*your-function-name***)。

1. 選擇日誌串流

每個日誌串流都會對應至[函式的執行個體](lambda-runtime-environment.md)。當您更新 Lambda 函數時，以及建立其他執行個體來處理並行調用時，就會顯示日誌串流。若要尋找特定調用的日誌，建議您使用 檢測函數 AWS X-Ray。X-Ray 會在追蹤內記錄有關請求和日誌串流的詳細資訊。

## 使用 AWS Command Line Interface (AWS CLI) 檢視日誌
<a name="nodejs-logging-cli"></a>

 AWS CLI 是一種開放原始碼工具，可讓您使用命令列 Shell 中的 命令與 AWS 服務互動。若要完成本節中的步驟，您必須擁有 [AWS CLI 版本 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

您可以透過 [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)，使用 `--log-type` 命令選項來擷取要調用的日誌。其回應將包含 `LogResult` 欄位，內含該次調用的 base64 編碼日誌 (最大達 4 KB)。

**Example 擷取日誌 ID**  
下列範例顯示如何從名稱為 `my-function` 的函數的 `LogResult` 欄位來擷取*日誌 ID*。  

```
aws lambda invoke --function-name my-function out --log-type Tail
```
您應該會看到下列輸出：  

```
{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...",
    "ExecutedVersion": "$LATEST"
}
```

**Example 解碼日誌**  
在相同的命令提示中，使用 `base64` 公用程式來解碼日誌。下列範例顯示如何擷取 `my-function` 的 base64 編碼日誌。  

```
aws lambda invoke --function-name my-function out --log-type Tail \
--query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode
```
如果您使用的是第 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)。  
您應該會看到下列輸出：  

```
START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
"AWS_SESSION_TOKEN": "AgoJb3JpZ2luX2VjELj...", "_X_AMZN_TRACE_ID": "Root=1-5d02e5ca-f5792818b6fe8368e5b51d50;Parent=191db58857df8395;Sampled=0"",ask/lib:/opt/lib",
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8  Duration: 79.67 ms      Billed Duration: 80 ms         Memory Size: 128 MB     Max Memory Used: 73 MB
```
該 `base64` 公用程式可在 Linux、macOS 和 [Ubuntu on Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10) 上使用。macOS 使用者可能需要使用 `base64 -D`。

**Example get-logs.sh 指令碼**  
在相同的命令提示中，使用下列指令碼下載最後五個日誌事件。該指令碼使用 `sed` 以從輸出檔案移除引述，並休眠 15 秒以使日誌可供使用。輸出包括來自 Lambda 的回應以及來自 `get-log-events` 命令的輸出。  
複製下列程式碼範例的內容，並將您的 Lambda 專案目錄儲存為 `get-logs.sh`。  
如果您使用的是第 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)。  

```
#!/bin/bash
aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"key": "value"}' out
sed -i'' -e 's/"//g' out
sleep 15
aws logs get-log-events --log-group-name /aws/lambda/my-function --log-stream-name stream1 --limit 5
```

**Example macOS 和 Linux (僅限)**  
在相同的命令提示中，macOS 和 Linux 使用者可能需要執行下列命令，以確保指令碼可執行。  

```
chmod -R 755 get-logs.sh
```

**Example 擷取最後五個記錄事件**  
在相同的命令提示中，執行下列指令碼以取得最後五個日誌事件。  

```
./get-logs.sh
```
您應該會看到下列輸出：  

```
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
{
    "events": [
        {
            "timestamp": 1559763003171,
            "message": "START RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf Version: $LATEST\n",
            "ingestionTime": 1559763003309
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tENVIRONMENT VARIABLES\r{\r  \"AWS_LAMBDA_FUNCTION_VERSION\": \"$LATEST\",\r ...",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tEVENT\r{\r  \"key\": \"value\"\r}\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "END RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "REPORT RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\tDuration: 26.73 ms\tBilled Duration: 27 ms \tMemory Size: 128 MB\tMax Memory Used: 75 MB\t\n",
            "ingestionTime": 1559763018353
        }
    ],
    "nextForwardToken": "f/34783877304859518393868359594929986069206639495374241795",
    "nextBackwardToken": "b/34783877303811383369537420289090800615709599058929582080"
}
```

## 刪除日誌
<a name="nodejs-logging-delete"></a>

當您刪除函數時，不會自動刪除日誌群組。若要避免無限期地儲存日誌，請刪除日誌群組，或[設定保留期間](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention)，系統會在該時間之後自動刪除日誌。

# 在 中檢測 Node.js 程式碼 AWS Lambda
<a name="nodejs-tracing"></a>

Lambda 與 整合 AWS X-Ray ，以協助您追蹤、偵錯和最佳化 Lambda 應用程式。您可以使用 X-Ray 來追蹤請求，因為它會周遊您應用程式中的資源，其中可能包含 Lambda 函數和其他 AWS 服務。

若要將追蹤資料傳送至 X-Ray，您可以使用以下兩個 SDK 庫之一：
+ [AWS Distro for OpenTelemetry (ADOT)](https://aws.amazon.com/otel) – OpenTelemetry (OTel) SDK 的安全、生產就緒、 AWS支援的分發。
+ [適用於 Node.js 的 AWS X-Ray SDK](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs.html) – 用於生成追蹤資料並將其傳送至 X-Ray 的 SDK。

每個 SDK 均提供將遙測資料傳送至 X-Ray 服務的方法。然後，您可以使用 X-Ray 來檢視、篩選應用程式的效能指標並獲得洞察，從而識別問題和進行最佳化的機會。

**重要**  
X-Ray 和 Powertools AWS Lambda SDKs是 提供的緊密整合檢測解決方案的一部分 AWS。ADOT Lambda Layers 是用於追蹤檢測之業界通用標準的一部分，這類檢測一般會收集更多資料，但可能不適用於所有使用案例。您可以使用任一解決方案在 X-Ray 中實作端對端追蹤。若要深入了解如何在兩者之間做選擇，請參閱[在 AWS Distro for OpenTelemetry 和 X-Ray SDK 之間進行選擇](https://docs.aws.amazon.com/xray/latest/devguide/xray-instrumenting-your-app.html#xray-instrumenting-choosing)。

**Topics**
+ [

## 使用 ADOT 來檢測您的 Node.js 函數
](#nodejs-adot)
+ [

## 使用 X-Ray SDK 來檢測 Node.js 函數
](#nodejs-xray-sdk)
+ [

## 透過 Lambda 主控台來啟用追蹤
](#nodejs-tracing-console)
+ [

## 透過 Lambda API 啟用追蹤
](#nodejs-tracing-api)
+ [

## 使用 啟用追蹤 CloudFormation
](#nodejs-tracing-cloudformation)
+ [

## 解讀 X-Ray 追蹤
](#nodejs-tracing-interpretation)
+ [

## 將執行時間相依項存放存在層中 (X-Ray SDK)
](#nodejs-tracing-layers)

## 使用 ADOT 來檢測您的 Node.js 函數
<a name="nodejs-adot"></a>

ADOT 提供全受管 Lambda [層](chapter-layers.md)，包含使用 OTel SDK 收集遙測資料所需的一切內容。透過取用此層，您可以檢測 Lambda 函數，而無需修改任何函數程式碼。您還可以將層設定為對 OTel 進行自訂初始化。如需詳細資訊，請參閱 ADOT 文件中的[針對 Lambda 上的 ADOT 收集器進行自訂組態設定](https://aws-otel.github.io/docs/getting-started/lambda#custom-configuration-for-the-adot-collector-on-lambda)。

針對 Python 執行階段，您可以新增**適用於 ADOT Javascript 的AWS 受管 Lambda 層**來自動檢測您的函數。如需有關如何新增此層的詳細資訊，請參閱 ADOT 文件中的 [適用於 JavaScript 的AWS Distro for OpenTelemetry Lambda 支援](https://aws-otel.github.io/docs/getting-started/lambda/lambda-js)。

## 使用 X-Ray SDK 來檢測 Node.js 函數
<a name="nodejs-xray-sdk"></a>

若要記錄 Lambda 函數對應用程式中其他資源所進行之呼叫的詳細資料，您也可以使用 適用於 Node.js 的 AWS X-Ray SDK。若要取得開發套件，請將 `aws-xray-sdk-core` 套件新增至應用程式的相依性。

**Example [blank-nodejs/package.json](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs/package.json)**  

```
{
  "name": "blank-nodejs",
  "version": "1.0.0",
  "private": true,
  "devDependencies": {
    "jest": "29.7.0"
  },
  "dependencies": {
    "@aws-sdk/client-lambda": "3.345.0",
    "aws-xray-sdk-core": "3.5.3"
  },
  "scripts": {
    "test": "jest"
  }
}
```

若要在 [適用於 JavaScript 的 AWS SDK v3](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/welcome.html) 中檢測 AWS SDK 用戶端，請使用 `captureAWSv3Client`方法包裝用戶端執行個體。

**Example [blank-nodejs/function/index.js](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs/function/index.js) – 追蹤 AWS SDK 用戶端**  

```
const AWSXRay = require('aws-xray-sdk-core');
const { LambdaClient, GetAccountSettingsCommand } = require('@aws-sdk/client-lambda');

// Create client outside of handler to reuse
const lambda = AWSXRay.captureAWSv3Client(new LambdaClient());

// Handler
exports.handler = async function(event, context) {
    event.Records.forEach(record => {
  ...
```

Lambda 執行階段會設定一些環境變數，以配置 X-Ray SDK。例如，Lambda 會將 `AWS_XRAY_CONTEXT_MISSING` 設定為 `LOG_ERROR`，以避免從 X-Ray SDK 中擲回執行階段錯誤。若要設置自訂內容遺失策略，請覆寫函式組態中的環境變數以使其不要有值，然後您可以透過程式設計方式設置內容遺失策略。

**Example 初始化程式碼範例**  

```
const AWSXRay = require('aws-xray-sdk-core');

// Configure the context missing strategy to do nothing
AWSXRay.setContextMissingStrategy(() => {});
```

如需詳細資訊，請參閱[使用 Lambda 環境變數](configuration-envvars.md)。

新增正確的相依項並完成必要的程式碼變更後，請透過 Lambda 主控台或 API 在函數組態中啟用追蹤功能。

## 透過 Lambda 主控台來啟用追蹤
<a name="nodejs-tracing-console"></a>

若要使用控制台在 Lambda 函數上切換主動追蹤，請按照下列步驟操作：

**開啟主動追蹤**

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

1. 選擇一個函數。

1. 選擇**組態**，然後選擇**監控和操作工具**。

1. 在**其他監控工具**欄位中，選擇**編輯**。

1. 在 **CloudWatch Application Signals 和 AWS X-Ray** 下，選擇**啟用** **Lambda 服務追蹤**。

1. 選擇**儲存**。

## 透過 Lambda API 啟用追蹤
<a name="nodejs-tracing-api"></a>

使用 AWS CLI 或 AWS SDK 在 Lambda 函數上設定追蹤，請使用下列 API 操作：
+ [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html)
+ [GetFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html)
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)

下列範例 AWS CLI 命令會在名為 **my-function** 的函數上啟用主動追蹤。

```
aws lambda update-function-configuration --function-name my-function \
--tracing-config Mode=Active
```

追蹤模式是您發布函數版本時版本特定組態的一部分。您無法變更已發佈版本上的追蹤模式。

## 使用 啟用追蹤 CloudFormation
<a name="nodejs-tracing-cloudformation"></a>

若要在 CloudFormation 範本中的 `AWS::Lambda::Function` 資源上啟用追蹤，請使用 `TracingConfig` 屬性。

**Example [function-inline.yml](https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/templates/function-inline.yml) - 追蹤組態**  

```
Resources:
  function:
    Type: [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)
    Properties:
      TracingConfig:
        Mode: Active
      ...
```

對於 AWS Serverless Application Model (AWS SAM) `AWS::Serverless::Function` 資源，請使用 `Tracing` 屬性。

**Example [template.yml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs/template.yml) - 追蹤組態**  

```
Resources:
  function:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      Tracing: Active
      ...
```

## 解讀 X-Ray 追蹤
<a name="nodejs-tracing-interpretation"></a>

您的函數需要將追蹤資料上傳至 X-Ray 的許可。當您在 Lambda 主控台中啟用追蹤時，Lambda 會將必要的許可新增至函數的[執行角色](lambda-intro-execution-role.md)。否則，請將 [AWSXRayDaemonWriteAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess) 政策新增至執行角色。

設定主動追蹤之後，您可以透過應用程式來觀察特定請求。[X-Ray 服務圖](https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html#xray-concepts-servicegraph)顯示了有關應用程式及其所有元件的資訊。下列範例顯示了一個具有兩個函數的應用程式。主要函式會處理事件，有時會傳回錯誤。頂端的第二個函數會處理出現在第一個日誌群組中的錯誤，並使用 AWS SDK 呼叫 X-Ray、Amazon Simple Storage Service (Amazon S3) 和 Amazon CloudWatch Logs。

![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/sample-errorprocessor-servicemap.png)


X-Ray 無法追蹤應用程式的所有請求。X-Ray 會套用取樣演算法以確保追蹤的效率，同時仍提供所有請求的代表範本。取樣率為每秒 1 次請求和 5% 的額外請求。不能針對函數設定 X-Ray 取樣率。

在 X-Ray 中，*追蹤*會記錄一或多個*服務*所處理之要求的相關資訊。Lambda 會在每個追蹤上記錄 2 個區段，這會在服務圖表上建立兩個節點。下圖反白顯示了這兩個節點：

![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/xray-servicemap-function.png)


左側第一個節點代表接收調用請求的 Lambda 服務。第二個節點代表您特定的 Lambda 函數。下列範例顯示了具有這 2 個區段的追蹤。兩者都被命名為 **my-function**，但其中之一的來源為 `AWS::Lambda`，而另一個的來源為 `AWS::Lambda::Function`。如果 `AWS::Lambda` 區段顯示錯誤，Lambda 服務就會出現問題。如果 `AWS::Lambda::Function` 區段顯示錯誤，表示您的函數出現了問題。

![\[\]](http://docs.aws.amazon.com/zh_tw/lambda/latest/dg/images/V2_sandbox_images/my-function-2-v1.png)


此範例會展開 `AWS::Lambda::Function` 區段以顯示其三個子區段：

**注意**  
AWS 目前正在對 Lambda 服務實作變更。由於這些變更，您可能會看到系統日誌訊息的結構和內容，與 AWS 帳戶中不同 Lambda 函數發出的追蹤區段之間存在細微差異。  
此處顯示的追蹤範例說明了舊式函數區段。下列段落說明了舊式和新式區段之間的差異。  
這些變化將在未來幾週內實作，除中國和 GovCloud 區域以外，所有 AWS 區域 中的所有函數都會轉換至使用新格式的日誌訊息和追蹤區段。

舊式函數區段包含下列子區段：
+ **初始化** - 表示載入函數和執行[初始化程式碼](foundation-progmodel.md)所花費的時間。只有函數的每個執行個體所處理的第一個事件會顯示此子區段。
+ **調用** – 表示執行處理常式程式碼所花費的時間。
+ **額外負荷** - 表示 Lambda 執行期為做好準備以處理下一個事件所花費的時間。

新式函數區段不包含 `Invocation` 子區段。相反地，客戶子區段會直接連接至函數區段。如需舊式和新式函數區段結構的詳細資訊，請參閱[了解 X-Ray 追蹤](services-xray.md#services-xray-traces)。

您也可以檢測 HTTP 用戶端、記錄 SQL 查詢，以及建立具有註釋和中繼資料的自訂子區段。如需詳細資訊，請參閱《*AWS X-Ray 開發人員指南*》中的 [適用於 Node.js 的 AWS X-Ray SDK](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs.html) 許可。

**定價**  
您可以在每月免費使用 X-Ray 追蹤，最高可達特定限制，作為 AWS 免費方案的一部分。達到閾值後，X-Ray 會收取追蹤儲存及擷取的費用。如需詳細資訊，請參閱 [AWS X-Ray 定價](https://aws.amazon.com/xray/pricing/)。

## 將執行時間相依項存放存在層中 (X-Ray SDK)
<a name="nodejs-tracing-layers"></a>

如果您使用 X-Ray 開發套件來檢測函數程式碼的 AWS SDK 用戶端，您的部署套件可能會變得相當大。為了避免每次更新函數程式碼時上傳執行時間相依性，請將 X-Ray SDK 封裝在一個 [Lambda 層](chapter-layers.md)中。

以下範例會顯示存放 適用於 Node.js 的 AWS X-Ray SDK的 `AWS::Serverless::LayerVersion` 資源。

**Example [template.yml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs/template.yml) - 相依性層**  

```
Resources:
  function:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      CodeUri: function/.
      Tracing: Active
      Layers:
        - !Ref libs
      ...
  libs:
    Type: [AWS::Serverless::LayerVersion](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-layerversion.html)
    Properties:
      LayerName: blank-nodejs-lib
      Description: Dependencies for the blank sample app.
      ContentUri: lib/.
      CompatibleRuntimes:
        - nodejs24.x
```

透過此組態，您只有在變更執行時間相依性時才會更新程式庫層。由於函數部署套件僅含有您的程式碼，因此有助於減少上傳時間。

為相依性建立圖層需要建置變更，才能在部署之前產生圖層封存。如需工作範例，請參閱 [blank-nodejs](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs) 範例應用程式。