かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Webpack 4 production モードで console.log を削除したい

gulpでは本番環境用にconsole.logを削除するのにgulp-strip-debugした後にgulp-uglifyでminify化すれば削除できていました。

webpackで、productionモードの時だけconsole.logを削除する方法のメモ

環境

  • node v10.15.0
  • webpack v4.29.0

1. UglifyJsPlugin uglifyjs-webpack-plugin を使うパターン

プラグインのインストール

$ yarn add -D uglifyjs-webpack-plugin

webpack.config.js

const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  optimization: {
    minimizer: [
      new UglifyJsPlugin({
        uglifyOptions: {
          compress: {drop_console: true}
        }
      })
    ],
  },
}

webpack 4 入門 - Qiita こちらの記事によると、uglifyjs-webpack-pluginは廃止になったとありました。
自分の作ったwebpack 4.29.0の環境だとuglifyjs-webpack-pluginを使ってconsole.logの削除を行うことが出来たのでメモとして残しました。
もしかするとmodeで自動的にuglifyjsするので、その設定の上書きとかしてしまったりであまり良くないのかもしれません。(廃止になったというテキストをググっても上手く発見することが出来ず… 時間を書けて調べてないので、推察ですが...)

2. TerserPlugin terser-webpack-plugin を使うパターン

プラグインのインストール

$ yarn add -D terser-webpack-plugin

webpack.config.js

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {drop_console: true}
        }
      })
    ],
  },
}

設定はuglifyjs-webpack-pluginterser-webpack-pluginも同じ感じです。
webpackコマンドを実行すると、console.logが削除されるようになっていればOK

production mode の時だけconsole.logを削除する

developmentモードのときもconsole.logが削除されると開発しづらいので、productionモードの時だけconsole.logを削除するようにします。

モード別に webpack の 設定ファイルを分ける

webpackで読み込むconfigファイルをモード別にしている場合はproductionモードのときに使うconfigファイルにだけ設定を書けばOKです。
設定ファイルは--config <config file path>オプションで指定することが出来ます。
例えばproductionモード用の設定ファイルをwebpack.production.config.jsにした場合は次のようなコマンドになります

$ webpack --mode production --config webpack.production.config.js

長いのでpackage.jsonscriptsに設定してしまうのが良さそうです。 package.json

{
  "scripts": {
    "build": "./node_modules/.bin/webpack --mode production --config webpack.production.config.js"
  }
}

実行

$ npm run build

1つのwebpack 設定ファイル(webpack.config.js)の内部で分岐させる

あまり巨大でない設定ならファイル内で設定の分岐を作成してしまうことも出来ます。
コマンドライン--modeオプションはargvで取得することが出来るようです。

webpack.config.js ( TerserPlugin 版 )

const TerserPlugin = require('terser-webpack-plugin');
const webpackConfig = {
  mode: "development",
  // 略
  optimization: {},
};

module.exports = (env, argv) => {
  const is_production = argv.mode === 'production';
  if( is_production ) {
    webpackConfig.mode = 'production'; // もしかしたら不要かも
    webpackConfig.optimization.minimizer = {
      new TerserPlugin({
        terserOptions: {
          compress: {drop_console: true}
        },
      }),
    }
  }
  return webpackConfig;
}

module.exportsで実行する関数内だと渡される引数argvオブジェクトからargv.modeで取得することが出来ますが、そこ以外だとprocess.argvが配列なのでオプションの渡し方によってはモードの判別が大変そうです。

webpack --mode production コマンドを実行するとconsole.logが削除され、developmentモードのwebpackコマンドだとconsole.logが残ったままにできるようになりました\\ ٩( ᐛ )و//

gulpに慣れ親しんでいたから、webpackの場合分けの設定作るの大変でした。
何より検索すると色々出てきすぎて、プラグインは公式サイトでも検索しづらく、どれが最新な情報なのか判別するのがとても難しかったです…
( CSSコンパイルまでwebpackでやるとwebpackの設定ファイルが秘伝のタレになりませんかねコレ...???


[参考]

gulp-strip-debug は console.logvoid 0に置き換える。uglifyするとvoid 0は削除される

I did previously remove it, but JS has so many edge-cases that it's safer to replace it with a void statement. See sindresorhus/strip-debug#1. Void is a noop anyways, so doesn't have any negative effect to leave it in.

Uglify is able to remove it since knows about all edge cases and how to handle them.
void 0; · Issue #2 · sindresorhus/gulp-strip-debug · GitHub