概要
AWS Lambda + TypeScriptで開発を行う際にデバッグを行う方法をまとめた記事です。
環境情報
この記事では以下の環境で開発を行っています。
- HostsOS(MacOS 10.12.3)
- vagrant(1.9.1)
-
VirtualBOX(5.1.12)
※GuestOSはCentOSの7系を利用 - typescript(2.3.4)
- serverless(1.15.3)
今回詳しい環境構築の方法は割愛させて頂きます。(私自身がまだ試行錯誤している段階なので、情報をまとめ次第環境構築の記事を別途投稿します。)
2017-06-21 追記
serverlessが動作するローカル環境を Ansible Playbook として公開しました。
下記に現在利用しているgithubのrepositoryを記載しておきます。
※このrepository自体まだ試行錯誤を繰り返している段階ですので内容は徐々に変化していく点はご了承下さい。
なお、npm packageを管理する為に yarn を利用しています。
ローカルでAWS Lambdaを実行出来る環境を作る
効率良くデバッグを行うにはローカルでAWS Lambdaを実行出来る環境を構築する必要があります。
ローカルでAWS Lambdaを実行する為には今のところ2種類の方法があります。
- serverless-offline を利用する方法
-
serverless-webpack の
serverless webpack serve
を利用する方法
今回この記事で扱うのは serverless-webpack の serverless webpack serve
を利用する方法です。
serverless-webpack のインストールを行う
まずは serverless-webpack のインストールを行います。
プロジェクトルートで以下のコマンドを実行しましょう。
yarn add serverless-webpack
次にserverless.ymlに以下の記述を追加します。
plugins:
- serverless-webpack
node-inspector をインストールする
node-inspector はNodeをChrome上でステップ実行出来るようにするツールです。
プロジェクトルートで以下のコマンドを実行しましょう。
yarn add node-inspector
source-map-support のインストール
TypeScriptはその性質上、TypeScriptのコードがそのまま解釈されて実行されている訳ではなく、一旦JavaScriptにコンパイルされ、コンパイルされたコード(JavaScript)が実行されるという流れになります。
その為、ブレークポイントを設定する際にTypeScriptのコードに対して設定出来ないと非常に不便です。
それを可能にするのが sourceMap という仕組みです。
source-map-support はNode上でそれを利用出来るようにする仕組みです。
以下のコマンドでインストールを実行しましょう。
yarn add source-map-support
yarn add @types/source-map-support
さらにLambdaが実行される前に以下のコードを追加してしておきます。
import * as sourceMapSupport from "source-map-support";
sourceMapSupport.install();
これで sourceMap が出力されるようになります。
ここまでで事前準備は完了となります。
serverless-webpack でローカルサーバを起動する
以下のコマンドでローカルサーバを起動させます。
serverless webpack serve
成功すると下記のような形でサーバが起動します。
ローカルサーバのprocessIDを取得する
次にローカルサーバのprocessIDを取得します。
pgrep -l node
ここでは 2110 node
が出力されたと仮定します。
実行中のprocessIDに対してUSR1シグナルを送信する
Node でデバッガを起動する為にはNodeの実行processに対してUSR1シグナルを送信します。
そこで先程取得したprocessIDに対してUSR1シグナルを送信します。
kill -s USR1 2110
すると実行中のサーバコンソールに Starting debugger agent. Debugger listening on port 5858
と表示されるかと思います。
node-inspector を起動
先程インストールしたnode-inspectorを起動します。
./node_modules/.bin/node-inspector
これで http://127.0.0.1:8080/?port=5858 にChromeでアクセスすれば良いのですが、私の場合はvagrantのIPに192.168.33.60を割り当てていたので以下のURLで接続を行います。
接続してしばらく時間が経つと下記のような画面が表示されます。
ブレークポイントを指定して実行する
左側に表示されているディレクトリツリーに webpack:// と記載されている部分があります。
ここからブレークポイントを設定してLambdaの実行を行ってみます。
今回の例では下記の画像のように src/functions/auth.ts 125行目にブレークポイントを設定しています。
実行すると下記のようにブレークポイントで止まっている事が確認出来るかと思います。
右側のメニューから変数の中身等も視覚化されています。
※右上の再生ボタンを押すと最後まで実行が完了します。
最後に
以上がServerless Framework + TypeScriptでデバッグを行う為の手順でした。
この記事では serverless-webpack を利用していますが、近々 serverless-offline を利用する方法に切り替えようと思っています。
理由は下記の通りです。
- serverless-webpack の開発速度が2017年に入ってから若干落ちている。
-
serverless webpack serve
はAPI Gatewayの動作と若干異なる部分がある。(Custom Authorizerが無効になっている等)
serverless-offline を利用する場合、 serverless-webpack に頼らずに、普通にwebpackを使ってbuildを行う形に変更しようと考えています。
※これらの内容は構築が完了次第、別の記事を投稿しようと思います。
とは言えこの記事の内容でも、都度AWSにデプロイしてconsoleでデバッグを行うよりは遥かに効率が良いので、同じ組み合わせで開発を行っている方々の参考になれば幸いと思い、この記事を書かせて頂きました。
それから私自身、TypeScriptやServerlessアーキテクチャに対して高度な技術を持っている訳ではありません、これを見て何かお気づきの方はコメントを貰えると嬉しいです。
以上になります。最後まで読んで頂きありがとうございました。
2017-06-21 追記
serverless-webpack の利用を停止しました(2017-06-21 追記1)
serverless-webpack は更新が止まってしまったようなので、現状、webpackの利用を辞めて tsc
を使う方法に変更してあります。
詳しくは Amazon API Gateway の Custom Authorizer で ServerlessなAPIを作ってみた に追記しました。
ただしこの代償としてデプロイパッケージのサイズが大きくなってしまいました。
serverless.yml
に余計なファイルはexcludeする設定を書きましたが、それでもwebpackによる最適化には遠く及びません。
webpackによる最適化の恩恵を受けつつ最新のwebpackの利用したいという場合は serverless-webpack 相当のPluginを自作するしかないのかもしれません。
デバッグ方法の簡略化(2017-06-21 追記2)
簡単なデバッグ方法を発見したので こちらのページ に記載してあります。
この方法であれば自分でprocessIDを調べて USR1
シグナルを送ったりする必要はありません。(SourceMapが利用出来ない問題があるのでそれは別途解決する必要がありますが・・・)