webpackでbabel-loaderを使うとき、普通は次のようにnode_modulesを除外すると思う。
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader',
},
],
しかしそうすると、npmでインストールしたパケージにES2015+で書かれたモジュールがあって、それをインポートしている場合、それがBabelで変換されずにバンドルされてしまう。
一般的に、npmパッケージのモジュールはES5で書かれている。(ソースがES2015+であってもES5にコンパイルされている)。だが稀にES2015+で書かれたモジュールもある。
ES2015+で書かれたモジュールを変換せずにバンドルしてしまうと、バンドル後のjsファイルはES2015+をサポートしていないプラグイン(例えばwebpack v3系に含まれているUglifyjsWebpackPlugin v0.4系)で処理できなくなる。また、それを公開すると、IE11のような古いブラウザではエラーが出るだろう。
回避策
次のように、ES2015+で書かれたモジュールをbabel-loaderの除外対象から除外することで、この問題を回避できる。(webpack v3.9.1で問題なく動作することを確認。)
rules: [
{
test: /\.js$/,
exclude: {
include: /node_modules/,
// node_modulesの中のモジュールを除外対象とする。
exclude: /node_modules\/foo\//,
// fooパッケージのモジュールを除外対象から除外する。
// パターンの末尾に"\/"がないと、名前がfooで始まるすべてのパッケージのモジュールが
// 除外対象から除外されてしまうので注意。
},
use: 'babel-loader',
},
],