何が起きたか
- Android 5 の標準ブラウザでReact動かそうとしたら
Map
Set
がないと言われて動かなかった。 -
@babel/preset-env
で polyfill してるから Map, Set はあるはずなのになぜ‥
babel.config.js
...
presets: [
[require('@babel/preset-env').default,
{
forceAllTransforms: true,
targets: {
ie: '11',
android: '5'
},
debug: true,
useBuiltIns: 'usage',
corejs: 3,
modules: false
},
...
原因
-
@babel/preset-env
のuseBuiltIns: 'usage'
はコードを解析して必要なpolyfillのみを読み込んでくれる。 - babel 7 はデフォルトで node_modules 以下をコンパイルの対象外としてる
- これにより、React 内部で使われてる
Map
、Set
が polyfill されずに例外になってた。
We also exclude
node_modules
by default and only look in the root unless you opt-in to setting an array of the.babelrcRoots
option such as"babelrcRoots": [".", "node_modules/pkgA"]
対応1
babel.config.js
...
useBuiltIns: 'entry'
...
にして、エントリーポイントで
index.jsなど
import "core-js/stable";
import "regenerator-runtime/runtime";
する。問題としてはファイルサイズがでかくなる。
対応2
babel.config.js
...
useBuiltIns: 'usage'
...
のまま、エントリーポイントで
index.jsなど
import "core-js/modules/es.map";
import "core-js/modules/es.set";
する。問題としてはほかにnode_modulesでpolyfillが必要なものが使われてたら例外になるので怖い。
対応3
node_modules もコンパイルする