

# .zip 파일 아카이브를 사용하여 Lambda에 트랜스파일된 TypeScript 코드 배포
<a name="typescript-package"></a>

TypeScript 코드를 AWS Lambda에 배포하려면 먼저 JavaScript로 트랜스파일해야 합니다. 이 페이지에서는 .zip 파일 아카이브를 사용하여 TypeScript 코드를 빌드하고 Lambda에 배포하는 세 가지 방법을 설명합니다.
+ [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 둘 다 esbuild를 사용하여 TypeScript 코드를 JavaScript로 프랜스파일합니다.

## AWS SAM을 사용하여 Lambda에 TypeScript 코드 배포
<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. (선택 사항) 샘플 애플리케이션에는 코드 린팅을 위한 [ESLlint](https://eslint.org/) 및 단위 테스트를 위한 [Jest](https://jestjs.io/) 등의 일반적으로 사용되는 도구에 대한 구성이 포함되어 있습니다. lint 및 test 명령 실행

   ```
   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를 사용하여 Lambda에 TypeScript 코드 배포
<a name="aws-cdk-ts"></a>

다음 단계를 따라 AWS CDK를 사용하여 샘플 TypeScript 애플리케이션을 빌드 및 배포합니다. 이 애플리케이션은 기본적인 API 백엔드를 구현합니다. 이 구성에는 Amazon 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
+ [도커](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 참조의 [esbuild 구성](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs-readme.html#configuring-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를 사용하여 Lambda에 TypeScript 코드 배포
<a name="aws-cli-ts"></a>

다음 예에서는 esbuild 및 AWS CLI를 사용하여 TypeScript 코드를 트랜스파일하고 Lambda에 배포하는 방법을 보여줍니다. esbuild는 모든 종속성이 포함된 하나의 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** 파일에 추가합니다. 이렇게 하면 .zip 배포 패키지를 자동으로 생성하도록 esbuild가 구성됩니다. 자세한 내용은 esbuild 설명서의 [빌드 스크립트](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\"}"
   }
   ```