【Windows】AmplifyのLambda function(+Layer)をTypeScriptで書きたい
実現したいこと
AmplifyのLambdaランタイムで「NodeJS」を選択したときに生成されるテンプレートファイルはデフォルトでTypeScriptに対応していません(2022/04時点)
amplify push
時にTypeScriptをコンパイルする方法が公式で紹介されていますが、Lambda Layersを使用している場合の書き方やWindows環境に対応した書き方にするために設定をいじったので、備忘として手順を残しておきます。
環境
本記事では、以下の環境で実施しています。
- バージョン
- OS: Windows 11
- Node.js: v14.16.1
- npm: 6.14.12
- AWS CLI: 2.1.38
- Amplify CLI: 8.0.0
- Lambdaランタイム: nodejs14.X
- ネーミング
- Amplify Project Name:
app
- Lambda Layer Name:
layer
※識別用としてAmplify Project Name + Lambda Layer Nameのapplayer
になります - Lambda Function Name:
func
- Amplify Project Name:
- エディタ
- Visual Studio Code(以下、VSCode)
- ターミナル
- PowerShell
手順
Step1. Lambda Layerを作成する
amplify add function
で追加
1. $ amplify add function
? Select which capability you want to add: Lambda layer (shared code & resource used across functions)
? Provide a name for your Lambda layer: layer
? Choose the runtime that you want to use: NodeJS
? The current AWS account will always have access to this layer.
Optionally, configure who else can access this layer. (Hit <Enter> to skip) Specific AWS accounts
? Provide a list of comma-separated AWS account IDs: <AWSアカウントID>
✅ Lambda layer folders & files created:
amplify\backend\function\applayer
2. 共通利用するパッケージをインストール
次のフォルダーに移動
$ cd amplify\backend\function\applayer\lib\nodejs
今回は「date-fns」をインストールしてみます
$ npm install date-fns
ここまでのフォルダ構成
<プロジェクトルート>\amplify\backend\function\applayer\lib\nodejs
│ package-lock.json
│ package.json
│ README.txt
│
└─node_modules
└─date-fns
3. 共通利用する処理をTypeScriptで記述
次のフォルダーに移動
$ cd amplify\backend\function\applayer\opt
TSファイルを作成(ここではPowershellのコマンドで新規作成しています)
$ New-Item layer.ts
適当に処理を書きます
// @ts-ignore
import { format as _format } from "date-fns";
// @ts-ignore
import ja from "date-fns/locale/ja";
export const formatJa = (date: Date, format: string): string => {
return _format(date, format, { locale: ja });
};
2022/04/22追記:以下のようにpackage.jsonのmainの修正が必要
「index.js」→「layer.js」
4. tsconfig.jsonを作成する
TSエラーが出るので、1つ上のフォルダーに移動してtsconfig.jsonを作成する
$ cd ../
$ tsc --init
中身は適宜書き換え
{
"compilerOptions": {
"target": "es2017",
"noImplicitAny": false,
"allowJs": true,
"noImplicitUseStrict": true,
"types": ["node"],
"moduleResolution": "node",
"module": "CommonJS",
"baseUrl": "./",
"paths": {
"*": ["./lib/nodejs/node_modules/@types/*", "./lib/nodejs/node_modules/*"]
}
},
"include": ["./opt/*.ts"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
VSCodeを使用していると、TSエラーが解消されないことがあるので、
TSサーバーを再起動するか 一度エディターを開き直す
5. 中間フォルダ構成
ここまでのフォルダ構成
<プロジェクルート>\amplify\backend\function\applayer # 手順1で作成
│ applayer-awscloudformation-template.json
│ layer-configuration.json
│ parameters.json
│ tsconfig.json # 手順4で作成
│
├─lib
│ └─nodejs
│ │ package-lock.json
│ │ package.json
│ │ README.txt
│ │
│ └─node_modules
│ └─date-fns # 手順2で作成
│
└─opt
layer.ts # 手順3で作成
Step2. Lambda Functionを作成する
amplify add function
で追加
1. ? Provide existing layers or select layers in this project to access from this function
のところで、Step1で作成したLambda Layer(ここではapplayer
)を選択する
$ amplify add function
? Select which capability you want to add: Lambda function (serverless function)
? Provide an AWS Lambda function name: func
? Choose the runtime that you want to use: NodeJS
? Choose the function template that you want to use: Hello World
Available advanced settings:
- Resource access permissions
- Scheduled recurring invocation
- Lambda layers configuration
- Environment variables configuration
- Secret values configuration
? Do you want to configure advanced settings? Yes
? Do you want to access other resources in this project from your Lambda function? No
? Do you want to invoke this function on a recurring schedule? No
? Do you want to enable Lambda layers for this function? Yes
? Provide existing layers or select layers in this project to access from this function (pick up to 5): applayer
? Do you want to configure environment variables for this function? No
? Do you want to configure secret values this function can access? No
? Do you want to edit the local lambda function now? Yes
Edit the file in your editor: <プロジェクトルート>amplify\backend\function\func\src\index.js
? Press enter to continue
Successfully added resource func locally.
2. tsconfig.jsonを作成する
次のフォルダーに移動
$ cd amplify\backend\function\func\src
後でTSファイルを作成するので、先にtsconfig.jsonを作成しておく
$ tsc --init
中身は適宜書き換え
{
"compilerOptions": {
"target": "es2017",
"noImplicitAny": false,
"allowJs": true,
"noImplicitUseStrict": true,
"types": ["node"],
"module": "CommonJS",
"baseUrl": "./",
"paths": {
"/opt/layer": ["../../applayer/opt/layer"],
"*": [
"../../applayer/lib/nodejs/node_modules/@types/*",
"../../applayer/lib/nodejs/node_modules/*"
]
}
},
"include": ["."],
"exclude": ["node_modules", "**/*.spec.ts"]
}
3. index.tsを作成
次に、TSファイルを作成(ここではPowershellのコマンドで新規作成しています)
$ New-Item index.ts
index.tsの処理を書きます
import { formatJa } from "/opt/layer";
import { Callback, Context, Handler } from "aws-lambda";
interface IEvent {
arguments: {
input: {
message: string;
};
};
}
interface IResult {
statusCode: number;
body: string;
}
/**
* @type {import('@types/aws-lambda').APIGatewayProxyHandler}
*/
export const handler: Handler<IEvent, IResult> = async (
event: IEvent,
context: Context,
callback: Callback<IResult>
) => {
const { message } = event.arguments.input;
return {
statusCode: 200,
body: `${message} ${formatJa(new Date(), "yyyy-MM-dd")}`,
};
};
ここまでのフォルダ構成
<プロジェクトルート>\amplify\backend\function\func # 手順1で作成
│ custom-policies.json
│ func-cloudformation-template.json
│ parameters.json
│
└─src
│ event.json
│ index.js
│ index.ts # 手順3で作成
│ package-lock.json
│ package.json
│ tsconfig.json # 手順2で作成
Step3. ローカルの状態をAWS上に反映(push)する
1. プロジェクトルートのpackage.jsonにコードを追加
...
"scripts": {
...
"amplify:applayer": "cd amplify/backend/function/applayer/opt && tsc",
"amplify:func": "cd amplify/backend/function/func/src && tsc"
},
...
amplify function push
で反映
2. プロジェクトルートに戻って、amplify function push
コマンドを実行
$ amplify function push
Current Environment: <環境名>
┌──────────┬───────────────────┬───────────┬───────────────────┐
│ Category │ Resource name │ Operation │ Provider plugin │
├──────────┼───────────────────┼───────────┼───────────────────┤
│ Function │ applayer │ Create │ awscloudformation │
├──────────┼───────────────────┼───────────┼───────────────────┤
│ Function │ func │ Create │ awscloudformation │
└──────────┴───────────────────┴───────────┴───────────────────┘
? Are you sure you want to continue? Yes
Suggested configuration for new layer versions:
applayer
- Access permissions: Maintain existing permissions
- Description: Updated layer version <yyyy-MM-ddTHH:mm:ss.SSSZ>
? Accept the suggested layer version configurations? Yes
後はテストして問題なければ、完了
テストを作成
テスト結果
2022/04/22追記
ローカル環境でTSファイルをJSファイルにコンパイルする方法について書きました。
Discussion