LoginSignup
15
7

More than 5 years have passed since last update.

webpack + Babel 環境で依存パッケージによっては ES6 未対応ブラウザで JS が動作しなくなる問題

Last updated at Posted at 2017-05-21

状況

iOS 9 や IE などの ES6 未対応のブラウザで、const や Arrow function といった ES6 の構文が解釈できずに JavaScript が動作しない問題が発生した。

具体的には、あるプロジェクトで re-bulma を使っていて、このパッケージを import していると、ES6 未対応ブラウザで以下のように ES6 の構文が解釈できず、エラーを吐かれる。

[Error] SyntaxError: Unexpected keyword 'const'. Const declarations are not supported in strict mode.

今回のプロジェクトでは、webpack の設定で Babel に node_modules 下のディレクトリは対象外 (exclude) とするようにしているため、例えば依存パッケージが ES6+ で書かれていても、ES5 向けにはトランスパイルしない。
その ES6+ で書かれた依存パッケージだけ exclude しない (トランスパイル対象とする) という解決策がひとつあるが、理想的ではない。

原因

re-bulma の package.json は、エントリーポイントを指定している部分を抜粋すると、以下のようになっている。

package.json
{
  ...
  "main": "lib/index.js",
  "module": "lib-es/index.js"
  ...
}

lib-es/index.js は ES6 向け、lib/index.js は ES5 向けにトランスパイルされてビルドされたものになっている。
ここで、webpack が依存解決時に lib/index.js ではなく lib-es/index.js を参照していることが原因であった。

解決法

webpack では、依存パッケージを解決するとき、resolve.mainFields の値を参照する。
このデフォルト値は ["browser", "module", "main"] となっているため1、ES5 をサポートしたい場合、module フィールドの優先度を main フィールドよりも下げる必要がある2

今回は以下のように設定した。

webpack.config.js
const config = {
  // ...
  resolve: {
    extensions: ['.js', '.jsx'],
    modules: [
      pathLib.resolve(__dirname, './app'),
      pathLib.resolve(__dirname, './node_modules'),
    ],
    mainFields: ['browser', 'main'],
  },
  // ...
}

module.exports = config

参考


  1. https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsDefaulter.js#L93-L98 

  2. 今回の場合は main フィールドが ES5 向けだったため優先度を上げたが、そうでない場合は優先度を変える必要がある。 

15
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
7