使用 .zip 檔案封存,在 Lambda 中部署轉換的 TypeScript 程式碼 - AWS Lambda

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

使用 .zip 檔案封存,在 Lambda 中部署轉換的 TypeScript 程式碼

在可以將 TypeScript 程式碼部署至 AWS Lambda 之前,您需要將其轉換為 JavaScript。本頁介紹了建置 TypeScript 程式碼,並透過 .zip 封存檔將其部署至 Lambda 的三種方法︰

AWS SAM 和 AWS CDK 簡化了 TypeScript 函數的建置和部署。AWS SAM 範本規範提供了一個簡單而清晰的語法,來描述構成無伺服器應用程式的 Lambda 函數、API、許可、組態和事件。藉助 AWS CDK,您可以在雲端建置可靠、可擴展且經濟高效的應用程式,並具有程式設計語言的強大表達能力。AWS CDK 適用於有一定經驗到經驗豐富的 AWS 使用者。AWS CDK 與 AWS SAM 均使用 esbuild 將 TypeScript 程式碼轉換為 JavaScript。

使用 AWS SAM 將 TypeScript 程式碼部署至 Lambda

請遵循以下步驟,使用 AWS SAM 下載、建置和部署範例 Hello World TypeScript 應用程式。此應用程式實作一個基本的 API 後端。其包含 Amazon API Gateway 端點和 Lambda 函數。當您將 GET 請求傳送至 API Gateway 端點時,會叫用 Lambda 函數。該函數會傳回 hello world 訊息。

注意

AWS SAM 會使用 esbuild 透過 TypeScript 程式碼建立 Node.js Lambda 函數。esbuild 支援目前為公開預覽版。在公開預覽期間,esbuild 支援可能面臨向後相容變更。

必要條件

若要完成本節中的步驟,您必須執行下列各項:

部署範例 AWS SAM 應用程式
  1. 使用 Hello World TypeScript 範本來初始化應用程式。

    sam init --app-template hello-world-typescript --name sam-app --package-type Zip --runtime nodejs18.x
  2. (選用) 範例應用程式包含常用工具的組態,如用於程式碼檢查的 ESLlint 和用於單元測試的 Jest。執行檢查和測試命令︰

    cd sam-app/hello-world npm install npm run lint npm run test
  3. 建置應用程式。

    cd sam-app sam build
  4. 部署應用程式。

    sam deploy --guided
  5. 依照螢幕上的提示操作。若要接受互動體驗中提供的預設選項,請以 Enter 回應。

  6. 輸出會顯示 REST API 的端點。在瀏覽器中開啟端點以測試函數。您應看到此回應︰

    {"message":"hello world"}
  7. 這是可透過網際網路存取的公有 API 端點。建議您在測試後刪除端點。

    sam delete

使用 AWS CDK 將 TypeScript 程式碼部署至 Lambda

請遵循以下步驟,使用 AWS CDK 建置和部署範例 TypeScript 應用程式。此應用程式實作一個基本的 API 後端。其包含 API Gateway 端點和 Lambda 函數。當您將 GET 請求傳送至 API Gateway 端點時,會叫用 Lambda 函數。該函數會傳回 hello world 訊息。

必要條件

若要完成本節中的步驟,您必須執行下列各項:

部署範例 AWS CDK 應用程式
  1. 為您的新應用程式建立專案目錄。

    mkdir hello-world cd hello-world
  2. 初始化應用程式。

    cdk init app --language typescript
  3. 新增 @types/aws-lambda 套件作為開發相依項。此套件包含 Lambda 的類型定義。

    npm install -D @types/aws-lambda
  4. 開啟 lib 目錄。您應看到名稱為 hello-world-stack.ts 的檔案。在此目錄中建立兩個新檔案:hello-world.function.tshello-world.ts

  5. 開啟 hello-world.function.ts,並將下列程式碼新增至檔案。這是 Lambda 函數的程式碼。

    注意

    import 陳述式會從 @types/aws-lambda 中匯入類型定義。不會匯入 aws-lambda NPM 套件,這是不相關的第三方工具。如需詳細資訊,請參閱 DefinitelyTyped GitHub 儲存庫中的 aws-lambda

    import { Context, APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda'; export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => { console.log(`Event: ${JSON.stringify(event, null, 2)}`); console.log(`Context: ${JSON.stringify(context, null, 2)}`); return { statusCode: 200, body: JSON.stringify({ message: 'hello world', }), }; };
  6. 開啟 hello-world.ts,然後將下列程式碼新增至檔案。這包含可建立 Lambda 函數的 NodejsFunction 建構,以及可建立 REST API 的 LambdaRestApi 建構

    import { Construct } from 'constructs'; import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs'; import { LambdaRestApi } from 'aws-cdk-lib/aws-apigateway'; export class HelloWorld extends Construct { constructor(scope: Construct, id: string) { super(scope, id); const helloFunction = new NodejsFunction(this, 'function'); new LambdaRestApi(this, 'apigw', { handler: helloFunction, }); } }

    NodejsFunction 建構預設會假設以下內容︰

    • 您的函數處理常式被稱為 handler

    • 包含函數程式碼 (hello-world.function.ts) 的 .ts 檔案,與包含建構 (hello-world.ts) 的 .ts 檔案位於同一目錄中。該建構使用建構 ID ("hello-world") 和 Lambda 處理常式檔案的名稱 ("function") 來尋找函數程式碼。例如,如果您的函數程式碼位於名稱為 hello-world.my-function.ts 檔案,則 hello-world.ts 檔案必須引用如下所示函數程式碼︰

      const helloFunction = new NodejsFunction(this, 'my-function');

    您可以變更此行為並設定其他 esbuild 參數。如需詳細資訊,請參閱 AWS CDK API 參考中的設定 esbuild

  7. 開啟 hello-world-stack.ts。這是定義 AWS CDK 堆疊的程式碼。將程式碼取代為以下內容:

    import { Stack, StackProps } from 'aws-cdk-lib'; import { Construct } from 'constructs'; import { HelloWorld } from './hello-world'; export class HelloWorldStack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); new HelloWorld(this, 'hello-world'); } }
  8. 在包含 cdk.json 檔案的 hello-world 目錄中部署您的應用程式。

    cdk deploy
  9. AWS CDK 使用 esbuild 建置並封裝 Lambda 函數,然後將該函數部署至 Lambda 執行時間。輸出會顯示 REST API 的端點。在瀏覽器中開啟端點以測試函數。您應看到此回應︰

    {"message":"hello world"}

    這是可透過網際網路存取的公有 API 端點。建議您在測試後刪除端點。

使用 AWS CLI 和 esbuild 將 TypeScript 程式碼部署至 Lambda

以下範例示範了如何使用 esbuild 和 AWS CLI 將 TypeScript 程式碼轉換並部署至 Lambda。esbuild 會產生一個包含所有相依項的 JavaScript 檔案。這是您需要新增至 .zip 封存的唯一檔案。

必要條件

若要完成本節中的步驟,您必須執行下列各項:

部署範例函數
  1. 在您的本機電腦上,為新函數建立專案目錄。

  2. 建立具有 npm 的新 Node.js 專案,或您選擇的套件管理器。

    npm init
  3. 新增 @types/aws-lambdaesbuild 套件作為開發相依項。@types/aws-lambda 套件包含 Lambda 的類型定義。

    npm install -D @types/aws-lambda esbuild
  4. 建立名稱為 index.ts 的新檔案。將下列程式碼新增至新檔案︰ 這是 Lambda 函數的程式碼。該函數會傳回 hello world 訊息。函數不會建立任何 API Gateway 資源。

    注意

    import 陳述式會從 @types/aws-lambda 中匯入類型定義。不會匯入 aws-lambda NPM 套件,這是不相關的第三方工具。如需詳細資訊,請參閱 DefinitelyTyped GitHub 儲存庫中的 aws-lambda

    import { Context, APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda'; export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => { console.log(`Event: ${JSON.stringify(event, null, 2)}`); console.log(`Context: ${JSON.stringify(context, null, 2)}`); return { statusCode: 200, body: JSON.stringify({ message: 'hello world', }), }; };
  5. 將建置指令碼新增至 package.json 檔案。這會將 esbuild 設定為自動建立 .zip 部署套件。如需詳細資訊,請參閱 esbuild 文件中的建置指令碼

    Linux and MacOS
    "scripts": { "prebuild": "rm -rf dist", "build": "esbuild index.ts --bundle --minify --sourcemap --platform=node --target=es2020 --outfile=dist/index.js", "postbuild": "cd dist && zip -r index.zip index.js*" },
    Windows

    在此範例中,"postbuild" 命令會使用 7zip 公用程式來建立 .zip 檔案。使用您偏好的 Windows zip 公用程式,並視需要修改命令。

    "scripts": { "prebuild": "del /q dist", "build": "esbuild index.ts --bundle --minify --sourcemap --platform=node --target=es2020 --outfile=dist/index.js", "postbuild": "cd dist && 7z a -tzip index.zip index.js*" },
  6. 建置套件。

    npm run build
  7. 使用 .zip 部署套件來建立 Lambda 函數。用執行角色的 Amazon Resource Name (ARN) 取代反白顯示的文字。

    aws lambda create-function --function-name hello-world --runtime "nodejs18.x" --role arn:aws:iam::123456789012:role/lambda-ex --zip-file "fileb://dist/index.zip" --handler index.handler
  8. 執行測試事件,以確認函數傳回下列回應。如果您想使用 API Gateway 叫用此函數,請建立並設定 REST API

    { "statusCode": 200, "body": "{\"message\":\"hello world\"}" }