アレについて記す

AWS SAM Local + TypeScript の開発環境を整える 前編

Posted on May 03, 2018 at 10:00 (JST)

AWS LambdaをTypeScriptで開発するための環境構築時につまずいた点などを記す。
前編はTypeScript環境構築について、後編はSAM Local + Localstack環境構築について記載する。

今回はTypeScript + Webpack + Mocha + power-assertの組み合わせで下記を実現した

  • 複数の成果物(LambdaのFunction単位で必要となるJSファイル)を生成
  • ビルド時の引数により環境別変数やモックインスタンスの切り替えをおこなう
  • Mocha + power-assertによるユニットテスト実行
  • VSCodeによるデバッグ実行

作成したコード [ sam-local-typescript-sample ]

複数の成果物を生成

Webpackの設定ファイルにてentryoutputを指定することで実現できる。

build/entries.conf.js

const root = process.cwd()

module.exports = {
  helloEnv: root + '/src/main/handlers/helloEnv.ts',
  s3Handler: root + '/src/main/handlers/s3Handler.ts',
}

build/webpack.config.js(抜粋)

entry: entries,
output: {
  path: process.cwd() + '/.dist',
  filename: '[name]/index.js',
  libraryTarget: 'commonjs2'
},

entry objectのvalueはビルドの基点となるファイルのパスを指定する。
keyはoutput[name]を置き換える値となる。
上記の設定の場合下記のように成果物ができあがる。

root
|-- .dist
    |-- helloEnv
    |   └── index.js   // helloEnv.tsを基点として生成されたJavaScript
    └── s3Handler
        └── index.js   // s3Handler.tsを基点として生成されたJavaScript


[ caution! ] libraryTarget: 'commonjs2'を指定しないと下記エラーが発生する。

Handler 'handler' missing on module 'index'

環境別変数やモックの切り替え

下記のディレクトリ構成とし、ローカル向けビルド時はenvironments/local、本番向けビルド時はenvironments/prodのファイルを使用することで切り替えを行う。

root
|-- src
    |-- environments
        |-- local            // ローカル開発用
        |   |-- env.ts       // 環境依存する設定値を定数として定義
        |   └── modules.ts   // モックやローカル向けServiceインスタンス生成
        └── prod             // 本番環境用
            |-- env.ts
            └── modules.ts   

どのディレクトリをビルド対象とするのかは、Webpackに設定できる。
package.jsonに下記を追加し、どの環境向けのビルドなのかを引数--env=${env}にて判定できるようにする。

"scripts": {
  "build-prod": "webpack --config ./build/webpack.config.js --env=prod",
  "build": "webpack --config ./build/webpack.config.js"
},

webpack.config.jsにてコマンド実行時の引数を解析し、ビルド対象ディレクトリをWebpackへ伝えるよう設定する。

$npm run build-prodを実行するとprocess.env.npm_lifecycle_scriptからwebpack --config ./build/webpack.config.js --env=prodという文字列が取得できるので解析する。

const argsEnv = process.env.npm_config_env
  ? process.env.npm_config_env
  : findArgsEnv(process.env.npm_lifecycle_script)
const envPath =
  argsEnv === 'prod' ? 'src/environments/prod/' : 'src/environments/local/'

resolve.modulesでビルド対象ディレクトリを指定。

resolve: {
  extensions: ['.ts', '.js', '.json'],
  modules: ['src/main', 'node_modules'].concat(envPath)
}


以上の設定でビルド・テスト・デバッグ実行は問題なく行えるようになるが、VSCodeでコードを表示した際にパスが解決できない警告が出る。
tsconfig.jsonにビルド対象ディレクトリの設定を記述することでエディタがパス解決できるようになる。

"baseUrl": "src",
"paths": {
  "*": ["main/*", "environments/local/*"]
},


なお、最初はWebpackのalias設定で実現しようとしていたが、後述するテストおよびVSCodeでのデバッグ実行時にうまくモジュールのpathを解決できなかったため今回の方式に切り替えた。 

Mocha + power-assert

Mochaは下記コマンドのように実行時にNODE_PATHを指定することで、モジュールのpathを解決できるようになる。

$ NODE_PATH=src/main/:src/environments/local ./node_modules/.bin/mocha --require espower-typescript/guess ./src/test/**/*.ts

複数ディレクトリをsrcのrootディレクトリとする場合は半角コロン(:)で連結する。
(Windowsの場合はセミコロンで連結する必要があるらしい。)

  power-assertを利用する場合は下記2点に気をつけること

  1. --require espower-typescript/guessを使用する
  2. test用のJSファイルのソースrootディレクトリがpackage.jsonと同階層のtestディレクトリではない場合は、package.jsonにて下記の設定が必要
"directories": {
  "test": "src/test"
}

directories未指定時

directories未指定テスト失敗

directories指定後

directories指定後テスト失敗

VSCodeによるデバッグ実行

プロジェクト直下の.vscode/launch.jsonを用意することで、テストコードを起点としてデバッグ実行できるようになる。

debuggerの起動方法

  1. テストコードを開き、任意の場所にデバッグポイントを設定する
  2. アクティビティーバー(左メニュー)でデバッグアイコンをクリックする
  3. 再生ボタンを押下する

debug1
debug2
debug3


参考