NestJSでステージング環境を作る

4 min read読了の目安(約3700字

この記事について

NestJSでステージング環境を作っていきます💪

NestJSのひな型が既に作成されている事を想定しています

必要なモジュールをインストール

$ npm i --save @nestjs/config cross-env

yarnを使っている場合は、以下のようになります。

$ yarn add @nestjs/config cross-env
  • @nestjs/config の使い方やオプションについては、以下の記事を参照してください。

https://docs.nestjs.com/techniques/configuration

https://zenn.dev/uttk/scraps/5169d2bb2e3d767533f3#comment-65d278330ab6d7a86627
  • cross-env は、環境変数を設定するために使用します。

📌 cross-env はメンテナンスモードに入りましたが、基本的な使い方をする分には何も問題はありません!
参考: https://github.com/kentcdodds/cross-env/issues/257

AppModuleにConfigModuleをインポートする

@nestjs/config を使うには、以下のように修正します。

app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [
    ConfigModule.forRoot({
       // 他のクラスで、ConfigServiceを使えるようにする
      isGlobal: true,
      
      // ロードするenvファイルを指定する
      envFilePath: `.env.${process.env.NODE_ENV}`,

      // 複数指定する場合は、配列を使用する
      // 値に被りがある場合は、インデックスが小さいほうが優先されます
      // envFilePath: [`.env.${process.env.NODE_ENV}`, `.env.hoge`],
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

envFilePathの部分で、process.env.NODE_ENVの値によって読み込むファイルを変更しています。これによって、ステージングが出来るようになります。

npm scriptsを定義する

nestコマンドでひな型を生成した場合、npm scriptsは以下のように定義されています。(※2020年12月現在)

package.json
"scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
},

上記の中で、startstart:devstart:debugstart:prod の部分を cross-env を使って以下のように修正します。

package.json
"scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
+   "start": "cross-env NODE_ENV=development nest start",
+   "start:dev": "cross-env NODE_ENV=development nest start --watch",
+   "start:debug": "cross-env NODE_ENV=development nest start --debug --watch",
+   "start:prod": "cross-env NODE_ENV=production node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
},

envファイルを定義

ここまで出来たら、あとはenvファイルを定義するだけです。

共通のファイル(常時読み込まれる)

.envファイルは、AppModuleでインポートする時に何も設定しなくても読み込まれます。
なので、複数の環境で共通の値などは .env ファイルに記述したほうがいいです。

値に被りがあった場合は、envFilePath で指定したファイルの値の方が優先されます。

.env(サンプル)
FILE_NAME=".env"

NODE_ENV=developmentの時に読み込まれるファイル

development環境の時に使いたい変数を定義します。

.env.development(サンプル)
FILE_NAME=".env.development"

対応するnpm scripts

$ npm run start
$ npm run start:dev
$ npm run start:debug

NODE_ENV=productionの時に読み込まれるファイル

production環境の時に使いたい変数を定義します。

.env.production(サンプル)
FILE_NAME=".env.production"

対応するnpm scripts

$ npm run start:prod

終わり

以上で環境構築は終わりです。お疲れ様でした🙌