はじめに
本ブログは、2025/02/21(金)に開催された「JAWS-UG CDK支部#19 クラスメソッドコラボ回」における私のLT「CDKでカスタムランタイムを作成して、Lambdaをnode.js23+TypeScriptで動かしてみた」の詳細資料になります。
https://jawsug-cdk.connpass.com/event/343974/jawsug-cdk.connpass.com
LTの発表資料は、下記で公開しています。(上記Connpassページにもリンクがあります)
なお今回は下記の構成で、何回かに分けて投稿します。
- カスタムランタイム作成 ※前回の記事
- AWS CDKでの実装&TypeScriptで動作させる ※今回はこれ
- AWSリソースにアクセスする(AWS SDK for JavaScript v3を使う)
AWS CDKでLambdaレイヤーを作成する
前回、Node.js ver23.6.0のカスタムランタイムをLambdaレイヤーで作成しましたが、まずはこのLambdaレイヤーをAWS CDK(以下「CDK」)作成する必要があります。
ただAWS CDKは LayerVersion コンストラクタでLambdaレイヤー作成できるので、下記の定義を行うだけでOKです。*1
// コンストラクタ変数は後で使います // 「runtime-tutorial」フォルダは、前回使用したフォルダ(詳細は前回を参照) // compatibleArchitecturesやcompatibleRuntimesも指定する const node23RuntimeLayer = new lambda.LayerVersion(this, 'Node23SampleLayer', { code: lambda.Code.fromAsset(<runtime-tutorialフォルダのパス>), layerVersionName: 'runtime-node23-jawsug-cdk-event-19', removalPolicy: cdk.RemovalPolicy.RETAIN_ON_UPDATE_OR_DELETE, });
Lambda関数を作成する
次にLambda関数(TypeScript)です。
なお今回Lambda関数をTypeScriptで作成しますが、使うコンストラクタは「Function」になりますので注意で
す。
(「NodejsFunction」だとデプロイ時にJavaScriptへのトランスパイルが行われてしまうので)
あとはruntime に runtime: lambda.Runtime.PROVIDED_AL2023 (Amazon Linux 2023)を選択すればOKです。(その他の項目は以下参照)
もちろん layers に先ほど作成したLambdaレイヤーを指定するのを忘れないでください。
const node23SampleFunction = new lambda.Function(this, "Node23SampleFunction", { functionName: 'Node23SampleFunction', runtime: lambda.Runtime.PROVIDED_AL2023, // Amazon Linux 2023を指定 layers: [node23RuntimeLayer], // ここで上記のLambdaレイヤーを指定 handler: "index.handler", code: lambda.Code.fromAsset(path.join(__dirname, '../lambda')), // Lambdaソースファイルのパス });
なおLambdaソースは、前回の「使用しているNode.jsのバージョンを返す」をTypeScriptで書いただけのものです。(1行目の import については後で触れます)
import type { LambdaFunctionURLEvent, LambdaFunctionURLResult } from 'aws-lambda/trigger/lambda-function-url' const handler = async function (event: LambdaFunctionURLEvent) { console.log(event); const result: LambdaFunctionURLResult = { statusCode: 200, body: JSON.stringify({ message: `node version is ${process.version}` }), }; return result; }; module.exports = { handler }
runtime.js を変更する
そしてもう一つ、前回作成したruntime.js も更新が必要です。
現時点でruntime.jsの内容はJavaScript(*.js)にのみ対応しているので(Node.jsなので)、TypeScriptに対応するように変更する必要があります。
これはruntime.jsの148行目あたりにある下記ソースを、以下の通りに変更すればOKです。*2
# 末尾に「.ts」を追加し、TypeScriptファイルを読めるようにする - const app = require(LAMBDA_TASK_ROOT + '/' + modulePath); + const app = require(LAMBDA_TASK_ROOT + '/' + modulePath + ".ts");
「型除去(Type Stripping)」について
1行目のimport文ですが、import type という見慣れない記載になっています。
これはnode.jsでTypeScriptを動かす際の独自の仕様である「型除去(Type Stripping)」に関わるものです。
「型除去(Type Stripping)」とは、TypeScriptファイルを 「型だけ削除して実行」するためのもの で、以前はオプションでしたが、v23.6.0からデフォルトで有効になっています。*3
ただし「型」ということを明示的に示すために、型定義のインポート/エクスポート時はtype という言葉を明示的に記載する必要があります。(これを忘れると「型」と認識されないため型除去は行われず、エラーになることがあります)
またこの型除去がデフォルトになったことで、tsconfig.json の下記項目もチェックする必要があります。(今回のLambdaの挙動には影響しません)
| 設定値 | 説明 | デフォルト値 |
|---|---|---|
| allowImportingTsExtensions | *.tsファイルからのインポートを可能にする | rewriteRelativeImportExtensionsが有効な場合はtrue,そうでない場合はfalse |
| rewriteRelativeImportExtensions | 相対インポートパス内の .ts、.tsx、.mts、および .cts ファイル拡張子を、出力ファイル内の対応する JavaScript に書き換える | 未記載 |
| verbatimModuleSyntax | 型のimport/export時に「type」が未記載の場合、エラーとする | 未記載 |
実行する
ここまで来たら、あとはcdk deploy でデプロイして、前回同様AWSコンソールからLambda関数の「テスト」で実施するだけです。
問題なければ、前回同様「node version is v23.6.0」という結果が返ってくるはずです。
まとめ
というわけで、ここまでで「AWS CDKでの実装&TypeScriptで動作させる」部分まで完了しました。
次回は最終回として「AWS SDK for JavaScript v3を使ってAWSリソースにアクセスする」ことを実施しようと思います。
告知
5/23(金)~5/24(土)に東京・ベルサール神田で実施される「TS Kaigi 2025」にて、「AWS LambdaをTypeScriptで動かして分かった、Node.jsのTypeScriptサポートの利点と課題」登壇させていただくこととなりました。(日時は5/23(金) 15:50 ~ 16:20 の予定です)
ちょうどこのブログで扱っている「【AWS CDK】LambdaをTypeScriptで動かす環境を構築する」で分かったNode.jsのTypeScriptサポートを触ってみてわかったことをお話しさせていただきますので、当日はよろしくお願いいたします。
それでは、今回はこの辺で。
*1:発表資料にも書きましたが、AWS CDKでカスタムランタイムを作成すること自体は、全く難しくないです。作成することと自体は、ですが...
*2:ただし下記の変更だと、今度はJavaScriptファイルが読めないので、柔軟に対応するにはもっと細かい変更が必要です。
*3:ただしにコマンドラインで実行する場合、--disable-warning=ExperimentalWarning フラグを使用して警告を非表示にしないと「ExperimentalWarning: Type Stripping is an experimental feature and might change at any time」という警告が出ますので注意が必要です