

# .zip ファイルアーカイブを使用して、トランスパイルされた TypeScript コードを Lambda にデプロイする
<a name="typescript-package"></a>

TypeScript コードを AWS Lambda にデプロイする前に、JavaScript にトランスパイルする必要があります。このページでは、.zip ファイルアーカイブを使用して TypeScript コードを構築し、Lambda にデプロイする 3 つの方法を説明します。
+ [AWS Serverless Application Model の使用 (AWS SAM)](#aws-sam-ts)
+ [ の使用AWS Cloud Development Kit (AWS CDK)](#aws-cdk-ts)
+ [AWS Command Line Interface (AWS CLI) および esbuild の使用](#aws-cli-ts)

AWS SAM と AWS CDK が、TypeScript 関数のビルドとデプロイを簡素化します。[AWS SAM テンプレート仕様](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification.html)は、サーバーレスアプリケーションを構成する Lambda 関数、API、アクセス許可、設定、およびイベントを記述するためのシンプルで簡潔な構文を提供します。[AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/home.html) を使用すると、プログラミング言語の優れた表現力を活かして、信頼性が高く、スケーラブルで、コスト効率の高いアプリケーションをクラウドで構築できます。AWS CDK は、中級～上級レベルの AWS ユーザーを対象としています。AWS CDK と AWS SAM はどちらも、TypeScript コードの JavaScript へのトランスパイルに esbuild を使用しています。

## AWS SAM を使用して TypeScript コードを Lambda にデプロイする
<a name="aws-sam-ts"></a>

AWS SAM を使用して、Hello World TypeScript サンプルアプリケーションをダウンロード、ビルド、およびデプロイする場合は、以下の手順に従ってください。このアプリケーションは、基本的な API バックエンドを実装し、Amazon API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数が呼び出されます。関数は `hello world` のメッセージを返します。

**注記**  
AWS SAM は esbuild を使用して、TypeScript コードから Node.js Lambda 関数を作成します。esbuild のサポートは、現在パブリックプレビュー中です。パブリックプレビュー中は、esbuild のサポートは、下位互換性のない変更の対象となる場合があります。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM CLI バージョン 1.75 以降](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)
+ Node.js

**AWS SAM サンプルアプリケーションをデプロイする**

1. Hello World TypeScript テンプレートを使用して、アプリケーションを初期化します。

   ```
   sam init --app-template hello-world-typescript --name sam-app --package-type Zip --runtime nodejs24.x
   ```

1. (オプション) サンプルアプリケーションには、コードの linting 用の [ESLint](https://eslint.org/) やユニットテスト用の [Jest](https://jestjs.io/) など、一般的に使用されるツールの設定が含まれています。lint コマンドとテストコマンドを実行するには、次のコードを使用します。

   ```
   cd sam-app/hello-world
   npm install
   npm run lint
   npm run test
   ```

1. アプリケーションを構築します。

   ```
   cd sam-app
   sam build
   ```

1. アプリケーションをデプロイします。

   ```
   sam deploy --guided
   ```

1. 画面に表示されるプロンプトに従ってください。インタラクティブな形式で提供されるデフォルトオプションを受け入れるには、`Enter` を押して応答します。

1. REST API のエンドポイントが出力に表示されます。ブラウザでエンドポイントを開き、関数をテストします。次のレスポンスが表示されます。

   ```
   {"message":"hello world"}
   ```

1. これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することをお勧めします。

   ```
   sam delete
   ```

## AWS CDK を使用して TypeScript コードを Lambda にデプロイする
<a name="aws-cdk-ts"></a>

AWS CDK を使用して TypeScript サンプルアプリケーションをビルドおよびデプロイする場合は、以下の手順に従ってください。このアプリケーションは、基本的な API バックエンドを実装し、API Gateway エンドポイントと Lambda 関数で構成されています。API Gateway エンドポイントに GET リクエストを送信すると、Lambda 関数が呼び出されます。関数は `hello world` のメッセージを返します。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS CDK バージョン 2](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_prerequisites)
+ Node.js
+ [Docker](https://www.docker.com/get-started/) または [esbuild](https://esbuild.github.io/) のどちらか

**AWS CDK サンプルアプリケーションをデプロイする**

1. 新しいアプリケーション用のプロジェクトディレクトリを作成します。

   ```
   mkdir hello-world
   cd hello-world
   ```

1. アプリケーションを初期化します。

   ```
   cdk init app --language typescript
   ```

1. 開発環境の依存関係として [@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) パッケージを追加します。このパッケージには Lambda の型定義が含まれています。

   ```
   npm install -D @types/aws-lambda
   ```

1. **lib** ディレクトリを開きます。**hello-world-stack.ts** という名前のファイルが表示されます。このディレクトリに **hello-world.function.ts** と **hello-world.ts** の 2 つの新しいファイルを作成します。

1. **hello-world.function.ts** を開き、次のコードをファイルに追加します。これは Lambda 関数のコードです。
**注記**  
`import` ステートメントは、[@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) から型定義をインポートします。`aws-lambda` NPM パッケージはインポートされません。これは関連性のないサードパーティーのツールです。詳細については、「DefinitelyTyped GitHub リポジトリ」の「[aws-lambda](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/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',
           }),
       };
   };
   ```

1. **hello-world.ts** を開き、次のコードをファイルに追加します。これには、Lambda 関数を作成する [NodeJsFunction コンストラクト](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs-readme.html)と、REST API を作成する [LambdaRestApi コンストラクト](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway.LambdaRestApi.html)が含まれています。

   ```
   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` と呼ばれます。
   + 関数コードを含む .ts ファイル (**hello-world.function.ts**) は、コンストラクトを含む .ts ファイル (**hello-world.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 リファレンス」の「[Configuring esbuild](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs-readme.html#configuring-esbuild)」(esbuild の設定) を参照してください。

1. **hello-world-stack.ts** を開きます。これは、[AWS CDK スタック](https://docs.aws.amazon.com/cdk/v2/guide/stacks.html)を定義するコードです。このコードを、次のコードで置き換えます。

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

1. `cdk.json` ファイルが含まれる `hello-world` ディレクトリから、アプリケーションをデプロイします。

   ```
   cdk deploy
   ```

1. AWS CDK は、esbuild を使用して Lambda 関数をビルドおよびパッケージ化し、その関数を Lambda ランタイムにデプロイします。REST API のエンドポイントが出力に表示されます。ブラウザでエンドポイントを開き、関数をテストします。次のレスポンスが表示されます。

   ```
   {"message":"hello world"}
   ```

   これは、インターネット経由でアクセス可能なパブリック API エンドポイントです。テスト後にエンドポイントを削除することをお勧めします。

## AWS CLI および esbuild を使用して、TypeScript コードを Lambda にデプロイする
<a name="aws-cli-ts"></a>

次の例は、esbuild および AWS CLI を使用して TypeScript コードをトランスパイルし、Lambda にデプロイする方法を示しています。esbuild は、すべての依存関係を含む 1 つの JavaScript ファイルを生成します。これは、.zip アーカイブに追加する必要がある唯一のファイルです。

**前提条件**

このセクションの手順を完了するには、以下が必要です。
+ [AWS CLI バージョン 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ Node.js
+ Lambda 関数の[実行ロール](lambda-intro-execution-role.md)
+ Windows ユーザーの場合は、[7zip](https://www.7-zip.org/download.html) などの zip ファイルユーティリティ。

**サンプル関数をデプロイする**

1. ローカルマシンで、新しい関数のプロジェクトディレクトリを作成します。

1. npm または任意のパッケージマネージャーを使用して、新しい Node.js プロジェクトを作成します。

   ```
   npm init
   ```

1. [@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) および [esbuild](https://esbuild.github.io/) のパッケージを開発環境の依存関係として追加します。`@types/aws-lambda` パッケージには Lambda の型定義が含まれています。

   ```
   npm install -D @types/aws-lambda esbuild
   ```

1. **index.ts** という名前の新しいファイルを作成します。次のコードを新しいファイルに追加します。これは Lambda 関数のコードです。関数は `hello world` のメッセージを返します。関数は、API Gateway リソースを作成しません。
**注記**  
`import` ステートメントは、[@types/aws-lambda](https://www.npmjs.com/package/@types/aws-lambda) から型定義をインポートします。`aws-lambda` NPM パッケージはインポートされません。これは関連性のないサードパーティーのツールです。詳細については、「DefinitelyTyped GitHub リポジトリ」の「[aws-lambda](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/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',
         }),
      };
   };
   ```

1. ビルドスクリプトを **package.json** ファイルに追加します。これにより、esbuild が.zip デプロイパッケージを自動的に作成するように設定されます。詳細については、esbuild ドキュメントの「[Build scripts](https://esbuild.github.io/getting-started/#build-scripts)」(ビルドスクリプト) を参照してください。

------
#### [ 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](https://www.7-zip.org/download.html) ユーティリティを使用して .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*"
   },
   ```

------

1. パッケージをビルドします。

   ```
   npm run build
   ```

1. .zip デプロイパッケージを使用して Lambda 関数を作成します。ハイライト表示されたテキストを、[実行ロール](lambda-intro-execution-role.md)の Amazon リソースネーム (ARN) で置き換えます。

   ```
   aws lambda create-function --function-name hello-world --runtime "nodejs24.x" --role arn:aws:iam::123456789012:role/lambda-ex --zip-file "fileb://dist/index.zip" --handler index.handler
   ```

1. [テストイベントを実行して](testing-functions.md)、関数が次のレスポンスを返すことを確認します。API Gateway を使用してこの関数を呼び出す場合は、[REST API を作成および設定してください](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html)。

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