upinetree's memo

Web系技術の話題とか。Qiitaも合わせてどうぞ (http://qiita.com/upinetree)

Webpacker 3.0 でのWebpackの設定カスタマイズ

Webpacker 3.0 以降ではWebpackの設定を直接書かずに、npmモジュールに定義されるデフォルトを上書きする形になった。 いい感じにデフォルトがそのまま使えて楽になった反面、すでに設定を結構いじったりしている場合にバージョンアップをするのがちょっと面倒だった。

カスタマイズの基本的な方法はドキュメントに書いてある。

https://github.com/rails/webpacker/blob/v3.0.1/docs/webpack.md

が、書いてあること以外で考えたことを以下にメモ。

環境ごとにPlugin設定の一部を上書き

// config/webpack/production.js
const environment = require('./environment');

const UglifyJsPlugin = environment.plugins.get('UglifyJs');
UglifyJsPlugin.options.sourceMap = false;

module.exports = environment.toWebpackConfig();

プラグインのoptionsオブジェクトに入っているのを上書きする。 Webpackプラグインの作りは理解してないけど、おそらくこのoptionsがあるという構造は統一されているのかな。

なお、この例ではプロダクションでソースマップを無効にしている。 (ソースマップ生成って結構パワー使うので)

一度プラグインを消しちゃって追加し直す方法もある。ぜんぜん違う設定にするときは楽かも。

参考: https://github.com/rails/webpacker/issues/771

environment.plugins.delete('UglifyJs')

environment.plugins.set(
  'UglifyJs',
  new UglifyJsPlugin({
    sourceMap: false
  })
)

動作確認は NODE_ENV 環境変数を利用するとかんたん。

$ NODE_ENV=production bin/webpack

staging環境

npmパッケージからデフォルトで提供されるenvironmentsは、 development, test, production のみ。 それ以外の環境はまっさらなEnvironmentオブジェクトがそのまま渡ってくる。

https://github.com/rails/webpacker/blob/v3.0.1/package/index.js#L10

めんどうなのでproductionと同じにしたいのだけれども、デフォルトで参照するenvironmentは環境変数 NODE_ENV で切り分けるため、NODE_ENV=production で起動する以外なさそう。

とはいえstaging固有の設定もしたいわけで、ひとまず以下のようにproduction相当の設定をべた書きする形となった。

const environment = require('./environment');
const webpack = require('webpack');
const CompressionPlugin = require('compression-webpack-plugin');

environment.plugins.set('ModuleConcatenation', new webpack.optimize.ModuleConcatenationPlugin());

environment.plugins.set('UglifyJs', new webpack.optimize.UglifyJsPlugin({
  sourceMap: true,
  compress: {
    warnings: false,
  },
  output: {
    comments: false,
  },
}));

environment.plugins.set('Compression', new CompressionPlugin({
  asset: '[path].gz[query]',
  algorithm: 'gzip',
  test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/,
}));

module.exports = environment.toWebpackConfig();

もうちょっとうまい感じの方法はないかな…。