AWS Lambda の関数を Node.js + TypeScriptで書くとき、どのような構成にすると便利かまとめたメモ。デプロイにはAWS SAMを使うことを想定。
ディレクトリ構造
src/ts/functions/(スタック名)/(関数名).ts をwebpackのエントリポイントとして、以下のようなディレクトリ構造にする。
src/
templates/ # CloudFormationテンプレート
ts/
functions/
(スタック名)/
(関数名).ts # エントリポイント
cli/
(関数).ts # コマンドラインでの動作確認
lib/ # 共通コード群(AWS Lambdaのランタイムに依存しない部分)
foo/
bar.ts
スタック名があるのは、デプロイパッケージ(zip)をスタック単位にすることを想定。デプロイツールの都合でここは調整したほうがいいかも。
コマンドラインで動作確認できるようにする
AWSのリソースを操作する系のLambda関数を実装する場合、その処理をコマンドラインで実行できるようにしておくと便利。
cli/にコードを配置し、ts-nodeを使ってpackage.jsonの"scripts"で呼び出せるようにしておく。
"scripts": {
"cli:my-operation": "ts-node src/ts/cli/my-operation.ts",
}
コードとしては、yargsでコマンドライン引数を解析して、関数に渡すだけのイメージ。
$ yarn cli:my-operation -a my-arg
webpack設定
node_modulesを持っていけば動くのだが、productionのみにしたりと面倒なので、webpackする。
例としては、こんな感じ。
ポイントは、externals: ["aws-sdk"]。標準のものやLambda Layerで提供しているものはここで除外する。ネイティブモジュールは、Lambda Layerで提供すると良いと思う。minimize: falseはコンソールで読む用。どっちでもいい。
tsconfig.json
Node v12のときはtarget: es2019。moduleはcommonjs。
source-map-supportを入れる
webpackするとスタックトレースが不便になるので、source-map-supportを入れる。
yarn add -D source-map-support @types/source-map-support
して、各エントリポイントファイルの先頭で
import "source-map-support/register";
する感じで。
必要に応じてnpm moduleにしてシェア
CloudFormation templateと、ビルドしたjsをnpm moduleにしてnpm registryにpublishしておくと、同一構成を作りやすくて便利。
0 件のコメント:
コメントを投稿