serverless-bundle로 Lambda 패키징하기

AWS Lambda 함수는 S3 버킷에 zip 파일로 저장됩니다. 함수가 호출될 때 컨테이너에 로드됩니다. 이 과정에 걸리는 시간을 콜드 스타트 시간이라고 합니다. 만약 함수가 최근에 호출되었다면, 컨테이너가 유지됩니다. 이 경우 함수가 훨씬 빠르게 호출되며, 이 지연 시간을 웜 스타트 시간이라고 합니다. 콜드 스타트에 영향을 미치는 요소 중 하나는 Lambda 함수 패키지의 크기입니다. 패키지가 클수록 Lambda 함수를 호출하는 데 더 오래 걸립니다.

Lambda 패키지 최적화

Serverless Framework은 Lambda 함수의 패키징과 배포를 모두 처리합니다. 기본적으로 이 프레임워크는 서비스당 하나의 패키지를 생성하고, 해당 서비스 내 모든 Lambda 함수에 이를 사용합니다. 이는 서비스 내 각 Lambda 함수가 다른 함수들도 사용하는 코드를 함께 로드한다는 의미입니다! 다행히도 이를 재정의할 수 있는 옵션이 있습니다.

# 각 함수에 대해 개별 패키지 생성
package:
  individually: true

위의 내용을 serverless.yml에 추가하면 Serverless Framework가 각 Lambda 함수에 대해 개별 패키지를 생성하도록 지시합니다. 이는 기본 동작이 아니며, 개별 패키징은 시간이 더 오래 걸립니다. 하지만 성능상의 이점으로 인해 이 방법은 충분히 가치가 있습니다.

개별 패키징은 좋은 시작이지만, Node.js 앱의 경우 Serverless Framework가 패키지에 node_modules/ 디렉토리를 포함시킵니다. 이는 Lambda 함수 패키지의 크기를 엄청나게 늘릴 수 있습니다. 이를 해결하기 위해 serverless-webpack 플러그인을 사용하여 Webpack의 트리 셰이킹 알고리즘을 적용해 Lambda 함수에 필요한 코드만 포함하도록 패키지를 더 최적화할 수 있습니다.

ES6와 TypeScript

AWS Lambda는 Node.js 10.x와 12.x를 지원합니다. 하지만 대부분의 모던 자바스크립트 프로젝트는 ES6 기능(예: import/export)과 TypeScript를 사용합니다. ES6와 TypeScript를 지원하려면 BabelTypeScript를 사용해 Lambda 함수를 트랜스파일할 수 있습니다.

하지만 Webpack과 Babel을 사용하려면 각각의 설정, 플러그인, NPM 패키지를 서버리스 앱에서 관리해야 합니다. 또한 함수가 패키징되기 전에 코드를 린트하고 싶을 수도 있습니다. 이는 첫 번째 코드를 작성하기도 전에 프로젝트에 많은 패키지와 설정 파일이 추가될 수 있다는 것을 의미합니다. 그리고 시간이 지나면서 이들을 업데이트해야 합니다. 여러 프로젝트에서 이를 관리하는 것은 매우 어려울 수 있습니다.

이러한 문제를 해결하기 위해 플러그인을 만들었습니다.

단 하나의 의존성

serverless-bundle을 소개합니다. 이 플러그인은 여러분이 Webpack, Babel, ESLint 설정을 관리할 필요 없이 ES6 또는 TypeScript Lambda 함수를 위한 최적화된 패키지를 생성해 줍니다!

-    "eslint"
-    "webpack"
-    "ts-loader"
-    "typescript"
-    "css-loader"
-    "graphql-tag"
-    "@babel/core"
-    "babel-eslint"
-    "babel-loader"
-    "eslint-loader"
-    "@babel/runtime"
-    "@babel/preset-env"
-    "serverless-webpack"
-    "source-map-support"
-    "webpack-node-externals"
-    "eslint-config-strongloop"
-    "tsconfig-paths-webpack-plugin"
-    "fork-ts-checker-webpack-plugin"
-    "@babel/plugin-transform-runtime"
-    "babel-plugin-source-map-support"

+    "serverless-bundle"

serverless-bundle은 다음과 같은 주요 장점을 가지고 있습니다:

  • 단 하나의 의존성만 필요
  • ES6와 TypeScript 지원
  • 최적화된 패키지 생성
  • ESLint를 사용한 Lambda 함수 린팅
  • babel-jest를 통한 단위 테스트 트랜스파일링 지원
  • 적절한 오류 메시지를 위한 소스 맵 지원

시작하기

serverless-bundle을 시작하려면 간단히 설치하면 됩니다:

$ npm install --save-dev serverless-bundle

그런 다음 serverless.yml에 추가합니다.

plugins:
  - serverless-bundle

플러그인에서 사용하는 동일한 Babel 설정으로 테스트를 실행하려면 package.json에 다음을 추가합니다:

"scripts": {
  "test": "serverless-bundle test"
}

더 많은 고급 옵션은 GitHub README에서 확인할 수 있습니다.

인기 있는 Serverless Node.js Starter가 이제 serverless-bundle 플러그인을 사용하도록 업데이트되었습니다. 또한 TypeScript 버전의 스타터도 있습니다 — Serverless TypeScript Starter