share facebook facebook twitter menu hatena pocket slack

2017.07.31 MON

【webpack】環境によってビルドする内容を分ける方法

jsのconfigファイルが本番環境と開発環境で違う場合があります。
しかしconfigファイルを含んだファイルをビルドする場合、phpのように.envで分けるみたいなことが出来ません。
そこで、本番環境用にビルドする時と、開発環境用にビルドする時でコマンドを分けることで、この問題が解消されます。

この分ける方法には大きく3つの方法があります。
状況に応じて使い分けていただければと思います。

独立した設定ファイルを作る方法

webpackはデフォルトではwebpack.config.jsというファイルに設定を定義します。
これを開発用と本番用でファイルを分けて別々に実行します。
例えば
開発用はwebpack.dev.js
本番用はwebpack.prod.js
で別々に作ります。
そしてビルドする時は
開発用ならwebpack --config webpack.dev.js
本番用ならwebpack --config webpack.prod.js
を実行します。

ちなみに
webpack.config.js

module.exports = function(env) {
  return require('./webpack.${env}.js')
}

このようにして

webpack --env=dev

みたいな感じで分けられるようなことが【公式ドキュメント】書いてあったので試してみたが出来なかった。
出来た人居たら教えてください。

独立した設定ファイルを作る方法はシンプルで分かりやすいかと思います。
しかしデメリットとして、共通部分も2回編集しなければならなくなります。

環境変数を使って分ける方法

開発環境と本番環境で違いが少ない場合は環境変数を使って分ける方法が良いかと思います。

nodeの環境変数を渡す方法

コマンド

NODE_ENV=production webpack

するとjs側でprocess.env.NODE_ENVという環境変数で取得することが出来ます。
なので変数によってif文で分けてあげれば良いだけです。
例えば本番と開発でentryするファイルを分けたい場合は以下のようにします。
webpack.config.js

if (process.env.NODE_ENV === 'production') {
    console.log('production');
    var configfile = 'config.js';
}else{
    console.log('devlope');
    configfile = 'config-dev.js';
}

これで本番の時はNODE_ENV=production webpackを実行して、
それ以外のときはwebpackと実行すればよいです。

参考
* Node.jsでの環境変数の使い方

dotenvを使う方法

npmでdotenvをインストールします。

npm install dotenv --save

そうするとphpの.envと同じ要領で使う事ができます。

.env

DB_HOST="localhost"
DB_USER="root"

config.js

console.log(process.env.DB_HOST);
console.log(process.env.DB_USER);

こんな感じで。
どちらの環境でもwebpackを実行出来る場合は、各環境でwebpackを実行すればよい。
出来ない場合として本番がs3だったりとか…

参考
* Nodeプロジェクトで環境依存の設定の管理方法

webpack-mergeを使う方法

これはテンプレートエンジンみたいな感じです。

共通部分をwebpack.common.jsに記述します。
本番のみの箇所をwebpack.prod.jsに記述してwebpack.common.jsをマージします。
開発のみの箇所をwebpack.dev.jsに記述してwebpack.common.jsをマージします。


webpack.common.js

module.exports = {
    "entry": {
        ...
    },
    "output": {
        ...
    },
    module: {
        ...
    },
}


webpack.dev.js、webpack.prod.js

const Merge = require('webpack-merge');
const CommonConfig = require('./webpack.common.js');

module.exports = Merge(CommonConfig, {
    "entry": {
        ...
    },
    "output": {
        ...
    },
    module: {
        ...
    },
}

実行するには

webpack --config webpack.dev.js

本番と開発で変える箇所がまあまああるときはこちらを使うと良いかと思います。

【おまけ】DefinePluginを使って環境変数をモジュールに使う方法

webpack.config.jsのentryに書いているファイルがモジュールなのだが、そのモジュール内でも環境変数を使いたい場合にDefinePluginを使う。
使い方としては
webpack.config.js

module.exports = {
    "entry": {
        ...
    },
    "output": {
        ...
    },
    module: {
        ...
    },
    plugins: [
        new webpack.DefinePlugin({
          NODE_ENV: JSON.stringify(process.env.NODE_ENV),
        })
    ]
}

みたいな感じで設定すればモジュールで

console.log(PRODUCTION);

見ないな感じで取れるはず。
ちなみにDefinePluginは試して居ないので動かないかも

参考
* Webpackを使ってJSでも.envしたい
* webpackでReact/Reduxを本番環境用にビルド(production build)する
* 【公式ドキュメント】DefinePlugin

元記事はこちら

【webpack】環境によってビルドする内容を分ける方法

宇敷 久里也

宇敷 久里也

WEBプログラマです。WEBに関することは、なんでも興味あります。

cloudpack

cloudpackは、Amazon EC2やAmazon S3をはじめとするAWSの各種プロダクトを利用する際の、導入・設計から運用保守を含んだフルマネージドのサービスを提供し、バックアップや24時間365日の監視/障害対応、技術的な問い合わせに対するサポートなどを行っております。
AWS上のインフラ構築およびAWSを活用したシステム開発など、案件のご相談はcloudpack.jpよりご連絡ください。