serverless frameworkの実践プラクティス

モバイルアプリサービス部の五十嵐です。

serverless frameworkのプロジェクトで、小さな改善ができたので紹介します。

serverlessのバージョンをプロジェクトごとに定義する

以前は npm install -g serverless のようにserverlessをグローバルにインストールしていたのですが、複数のserverlessプロジェクトを扱っているとそれぞれでバージョンが異なるため、グローバルにインストールしたserverlessのバージョン管理が面倒でした。

そこで、プロジェクトの package.json にserverlessのバージョンを指定して、プロジェクトのローカルにインストールすることにしました。最低限だけ書くと以下のようになります。

{
  "name": "sample",
  "devDependencies": {
    "serverless": "^1.8.0"
  },
  "scripts": {
    "sls": "serverless"
  }
}

これで npm install を実行すると、プロジェクトディレクトリのnode_moduleディレクトリにserverlessがインストールされます。また、serverlessのコマンドを実行するためにパスを通してあげたいので scripts フィールドにコマンドを定義しておきます。 scripts フィールド内ではnode_moduleにパスが通っていますので、 npm run sls と実行することで、ローカルのserverlessが実行されます。

$ npm run sls -- -v
1.8.0

注意が必要なのは sls にオプションを指定する場合は -- が必要なことです。 -- を付けないと、 npm コマンドのオプションと認識されてしまいます。

また、 sls コマンドが正常に終了しなかった時は npm のエラーログが出力されて邪魔くさいので、 .npmrc にエラーログを出力しない設定をしておくと良いです。

echo "loglevel=silent" > .npmrc

ユニットテストの環境変数を設定する

Lambdaに環境変数がサポートされ、serverless.yamlにも環境変数が設定できるようになりました。これについては以前に書いた記事 serverless frameworkによるAWS Lambdaの実践的デプロイ | Developers.IO でも紹介しました。とても便利というか、無くてはならない機能ですよね。これを使うとアプリケーションコードには以下のようなコードが出現するはずです。

const someVar = process.env.SOME_VAR;

このようなコードを含むソースをユニットテストする時、環境変数にSOME_VARが定義されていないと困りますよね。以前はコードにデフォルト値を設定していたのですが、テストのためにソースに改変を加えるのは筋が悪いです。環境変数を設定し忘れたらデフォルト値で動いてしまいますし。

const someVar = process.env.SOME_VAR || 'TEST';

前提としてユニットテストは mocha を使っており package.json の scripts フィールドにコマンドを定義しています。

  "scripts": {
    "test": "mocha",
  },

これに対してユニットテストの実行時に環境変数を与える方法がないかなと調べた結果、 dotenv を使うことにしました。これは環境変数をファイルに書いておき、ソースコードで読み込むことができるライブラリです。

設定例としては以下のようになります。

$ tree -a test
test
├── environments
│   └── .env # ここにdotenvの設定ファイルを置く

$ cat test/environments/.env
SOME_VAR=TEST

これをテストコードから読み込みます。

// environment
require('dotenv').config({path: 'test/environments/.env'});

このようにすることで、ユニットテスト実行時に環境変数を設定することができました。

まとめ

実際に使っているTipsを2つ紹介しました。これらのプラクティスがベストとは思っていないので、「もっとこんなやり方があるよ!」というのがあればぜひコメントで教えてください。