環境変数を使ってnpm scriptsを改良したお話

2本立てのスクリプトの管理がめんどくさい!

元々、1つのスクリプトについて、productiondevelopmentの2本立てで書いていました。

"scripts": {
  ...
  "prod": "run-p watch:prod server:prod",
  "dev": "run-p watch:dev server:dev",
  "webpack:prod": "webpack --mode production",
  "webpack:dev": "webpack --mode development",
  "watch:prod": "nodemon --ignore docs/ --ignore node_modules/ -e js,ts,mjs,css,scss,ejs,html -x \"run-s webpack:prod beautify copy\"",
  "watch:dev": "nodemon --ignore docs/ --ignore node_modules/  -e js,ts,mjs,css,scss,ejs,html -x \"run-s webpack:dev beautify copy\"",
  "server:prod": "webpack-dev-server --mode production",
  "server:dev": "webpack-dev-server --mode development",
  ...
}

実行するときはproddevのどちらか一方をnpm runするだけですが、スクリプトに何らかの手を加える場合は2箇所に修正を施す必要があったので、面倒に感じていました。

これを何とか一本化したいなーと思って試行錯誤しましたが、複数のスクリプト間で引数を受け渡すところがどうしても上手くできなかったので、時代に逆行して、環境変数を使う方法に落ち着きました。

環境変数を使ってwebpackのモードを切り替える

cross-envパッケージのインストール(ついでにnodemon.jsonを作成)

環境変数の設定とスクリプトの実行を同時に行いたいので、cross-envパッケージをインストールします。

$ npm install --save-dev cross-env

ついでに、watchの行が長いので、nodemonの設定をnodemon.jsonに移行しました。

{
  "ext": "js,ts,mjs,css,scss,ejs,html",
  "ignore": [
    "node_modules/",
    "docs/",
    ...
  ]
}

スクリプトの書き換え

以上を踏まえて、npm scriptを以下のように書き換えます。

"scripts": {
  ...
  "prod": "cross-env NODE_ENV=production run-p watch server",
  "dev": "cross-env NODE_ENV=development run-p watch server",
  "watch": "nodemon --config nodemon.json -x \"run-s webpack beautify copy\"",
  "server": "webpack-dev-server",
  "webpack": "webpack",
  ...
}

だいぶすっきりしました。

webpack.config.jsに環境変数の読み込みを追加

環境変数をWebpackに適用するため、webpack.config.jsに手を加えます。

...
const env = process.env.NODE_ENV

module.exports = {
  mode: env || 'development',
  ...
}

本来は、こういう設定の手間を減らすのがWebpack4のコンセプトなんだと思いますが…。ごちゃごちゃしていたスクリプトを数行減らすことができたので、当面はこちらの方法を使っていく予定です。