2019/6 AWS LambdaのTypeScript化
2018/10 AWS Lambdaを使った雑務への取り組みで紹介しましたが、大阪事務所では雑務にLambdaを使っています。 Lmabdaは最近Node.js v10に対応したこともあり、アップデートを兼ねてTypeScript化しましたのでご紹介します。
フォルダ構成
以下のような構成で、srcフォルダで開発してビルドしたものがdist、dist.zipになるという構成です。
├─ package.json # パッケージ設定ファイル
├─ tsconfig.json # TypeScript設定ファイル
│
├─ src # TypeScriptソース
│ └─ index.ts #
│
├─ dist # ビルド後のJSソース
│ └─ index.js #
└─ dist.zip # zipアップロード用
設定ファイル
package.json
> npm install -g typescript
TypeScript自体はインストールしている前提で、以下のようにしました。
型補完用の@types/nodeやaws-sdk、TypeScript系のパッケージをインストールしています。
{
"name": "sample",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"clean": "rimraf dist && rimraf dist.zip",
"ts": " tsc -p tsconfig.json",
"cp": "cp -f ./package.json ./dist",
"install": "npm --prefix ./dist install --production ./dist",
"zip": "cd dist/ && bestzip ../dist.zip *",
"build": "npm run clean && npm run ts && npm run cp && npm run install && npm run zip"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@types/node": "^12.0.0",
"aws-sdk": "^2.441.0",
"bestzip": "^2.1.2",
"rimraf": "^2.6.3",
"ts-loader": "^5.4.3",
"ts-node": "^8.1.0",
"tsconfig-paths": "^3.8.0"
},
"dependencies": {
}
}
tsconfig.json
TypeScript設定ファイルは基本的な設定だけです。 Node.js v10なのでtargetをes2017にしてみました。
{
"compilerOptions": {
"module": "commonjs",
"target": "es2017",
"declaration": false,
"removeComments": true,
"sourceMap": false,
"outDir": "./dist",
"baseUrl": "./src"
},
"exclude": ["node_modules"]
}
ビルド&デプロイ
> npm run build
このビルドコマンドを実行すればpackage.jsonのscriptsに記載している
- clean: distフォルダとdist.zipの事前削除
- ts: TypeScriptビルド
- cp: package.jsonのコピー
- install: distフォルダ内でdependenciesパッケージのインストール
- zip: dist.zipの作成
一連の処理が実行されdist.zipが出来上がるので、AWSの管理画面からdist.zipをアップロードする感じです。
コード
index.ts
雑務につかっているコード例です。引数Event型をわかりやすいように定義してあげて、hanlder関数内で用途に応じて分岐、async/await構文が使えるのでスッキリしました。
import { polling } from './cron';
import { hookSlack, hookBitbucket } from './webhook';
type Event = {
// 機能
mode: string;
// Slack
token?: any;
team_id?: any;
team_domain?: any;
channel_id?: any;
command?: any;
text?: any;
// Bitbucket
push?: { changes: any[] };
repository?: { name:string; };
};
export const handler = async(event: Event, context: {succeed: (a:string)=>void; fail: (a:any)=>void; }, callback:(a:any, b:any)=>void)=>{
if(event.mode == 'polling'){
await polling();
// slack
}else if(event.token && event.team_id && event.team_domain && event.channel_id){
const message = await hookSlack(event.team_domain, event.channel_id, event.command, event.text);
context.succeed(message);
// bitbucket
}else if(event.repository && event.push){
await hookBitbucket(event.repository, event.push);
context.succeed('complete bitbucket.');
}
};
感想
LambdaをTypeScript化すると言うと大事に聞こえますが、実際やっていることは必要なパッケージをインストールしてtsconfig.jsonを整えてJSへビルドしてあげるだけの簡単な作業でした。