Webpack で ビルド時に環境ごとに読み込む環境変数を分けたい


概要

ほとんどの Laravel などのバックエンドフレームワークは環境変数ファイルが用意され、環境ごとに読み込まれる環境変数を動的に変えることができる機能が備わっています。
しかし、javascript の場合は環境変数を環境ごとに読み込む機能を自分で設定するか npm パッケージ を利用するしかなかったので、自分的ベストな方法をまとめておきます。

結論

Webpack の alias 機能を使えばパッケージやライブラリなしで環境変数を分けることができます!!!!!!

設定方法

今回編集するファイルは下記ファイルになります。

webpack.config.js
package.json

前提環境

開発環境は node サーバをローカルにたてて開発。
本番、ステージサーバは CI・CD を利用してビルド後デプロイするといった環境で行いました。

フォルダ構成

フォルダ構成は下記のとおり Webpack を利用した際の一般的な javascript の開発構成です。
環境変数をステージ毎に切り替えるための .env フォルダを用意しています。このフォルダにステージごとの環境変数を定義した js ファイルを用意します。

.env
  |_ dev.js
  |_ stg.js
  |_ prd.js
dist
  |_ main.js
src
  |_ index.js
node_modules
package-lock.json
package.json
webpack.config.js

環境変数ファイルの作成

.env フォルダ内に環境変数用の javascript ファイルを作成します。

dev.js
export default {
    apiUrl : 'https://dev-example.com'
}
prd.js
export default {
    apiUrl : 'https://example.com'
}

このような感じでステージごとの環境変数を設定していきます。

package.json の scripts 設定

package.json に npm run <ステージ>の実行コマンドを定義します。
ステージごとに環境変数定義ファイルを動的に読み込むために NODE_ENV=stg を設定します。
NODE_ENVwebpack.config.jsファイルで参照できる環境変数になります。環境変数の名前は何でも大丈夫です。
下記のようにステージごとに渡してあげる環境変数を変えてあげましょう。

package.json
{
  "scripts": {
    "stg": "NODE_ENV=stg webpack --mode production",
    "prd": "NODE_ENV=prd webpack --mode production",
    "start": "NODE_ENV=dev webpack-dev-server --mode development --hot --inline --watch-content-base"
  },
// 省略

webpack の設定

webpack.config.js に alias の設定を行います。

webpack.config.js
const environment = process.env.NODE_ENV || 'dev';

module.exports = {
  mode: 'development',

  resolve: {
    alias: {
      userEnv$: path.resolve(__dirname, `.env/${environment}.js`),
    },
  },
// 省略
}

alias は 深くネストされた javascript ファイルのパスをいちいち書くのがめんどくさい人用にエイリアスとして設定できるようにしてくれる Webpack の機能です。
この alias を利用してステージ毎に環境変数ファイルを動的に読み込むように設定しています。

process.env.NODE_ENV は package.json で定義した環境変数が取得できます。
この環境変数によって、読み込みたい環境変数が定義されたファイルを動的に変更します。
※環境変数を定義したファイルまでのパスは絶対パスで指定しましょう。

userEnv$: path.resolve(__dirname, `.env/${environment}.js`)

以上で設定は終わりです。

利用方法

javascript 側で環境変数を利用するときは下記のように import してあげましょう。

test.js

import userEnv from 'userEnv';
console.log(userEnv.apiUrl);

あとはローカルや CI・CDで npm コマンドを実行しましょう。


// ローカル開発環境
npm run start

// CI・CDスクリプト
npm run stg
npm run prd

これでステージごとに環境変数を読み込むことができました。
環境変数を動的に切り替えるパッケージが結構あるみたいですが alias を使う方法だとパッケージいらずに環境変数を切り替えられるので簡単に利用できると思います。

※ ちなみに node サーバではなくフロント側の環境変数の設定方法なので漏れてはいけない key などの情報は設定しないでね。全部漏れちゃいますので

環境変数用のパッケージに cross-envdotenvなどがありますがそれらを利用する場合の違いやメリット・デメリットがよくわかってないのでわかる人いたら教えてくださいm(_ _)m