TypeScriptなり、JSXやSFCなりを使ってトランスパイルして、Webpackを使ってビルド、babel-loaderをかましていい感じに動いているのをChromeで確認して、本番にあげる。すると、聞こえてくる悲鳴は、IEでは死んでいる。
そう、僕たちはいつもIEをないがしろにして、Chromeを基準に物事を考てしまう。リッチなブラウザをたよりに、ちゃんと動いていると信じ込んでしまう。そして、原因はbabelのpluginが足りなかったり、core-jsを読み込んでいなかったりといった原因を探り出し、ようやく解決して本番に再pushする。そうすれば解決すると信じて...。
core-jsを利用する、しかし...
@babel/polyfill
🚨 As of Babel 7.4.0, this package has been deprecated in favor of directly including core-js/stable (to polyfill ECMAScript features) and regenerator-runtime/runtime (needed to use transpiled generator functions):import "core-js/stable";
import "regenerator-runtime/runtime";
なるほど、@babel/polyfill
は非推奨であり、イマドキのような設定をする必要があるようだ。上記を参考にして、ビルドを行ってみる。
しかし。
SCRIPT5022: catch ステートメントでは適用されますが、throw ステートメントでは適用されません。
のエラー。
エラーが発生した部分を整形して、解析してみる。
なるほど、わからん。
// ...
t.exports = {
set: n, get: a, has: i, enforce: function (t) {
return i(t) ? a(t) : n(t, {})
}, getterFor: function (t) {
return function (e) {
var r;
// 以下の行ではTry-Catchが行われていないため、IEではエラーとなる...??
if (!s(e) || (r = a(e)).type !== t) throw TypeError("Incompatible receiver, " + t + " required");
return r
}
}
}
//...
ビルドした成果物が悪ければどうしようもないし、ではcore-jsのせいなのか、あるいはプラグインの不足なのかを探り、探る。しかし原因を探し当てることが難しい。3日ほど溶かしちゃうのではないか。3日ほど溶かすといえば、これを思い出した。
すでに3日悩んだことがあるからだよ。 https://t.co/xBLF6oGJ4T
— えいや (@aya_eiya) June 8, 2020
core-jsだけでは問題は解決しない
さて、結論から言えば、 core-js
と regenerator-runtime
を読み込むだけでは解決しない場合がある。ある程度はIEでもcore-jsを利用したビルドが功を奏することもあるが、そうでない場合もあることは教訓として覚えておく必要がある。ではどのように解決していけばよいか悩んでいたなかで、以下の記事にたどり着いた。
最新版で学ぶwebpack 4入門 - Babel 7でES2020環境の構築(React, Vue, Three.js, jQueryのサンプル付き)
※最新版のBabelでは@babel/polyfillではなく、core-jsを利用する方法を推奨されています。しかし、2020年1月現在、core-jsを組み込む方法は注意する点が多くあります(特にIE11で利用可能にするのは難しい)。本記事では@babel/polyfillでの方法でしばらく継続して掲載します。
そう、@babel/polyfill
は非推奨ではあるが、読み込んでしまえというものである。
さて、これで解決したのかといえば、残念ながら解決はしなかった。次はSCRIPT438: オブジェクトは 'assign' プロパティまたはメソッドをサポートしていません。
に遭遇した。Object.assignが使えない、それはわかるが、、、もうつらい、、、もう面倒くさい...。
ではどうしたのか。
polyfill.ioでよくないか?
最終兵器、polyfill.io
以下のコードをHTMLに差し込むだけで解決した。
<html>
<head>
...
<script src="https://polyfill.io/v3/polyfill.min.js?features=Object.assign"></script>
</head>
...
IEとの対決
上記のような、polyfill.ioを用いた方法が最善だとは思えない。しかしそういう逃げ方もできるということを知っておくべきだと思う。本来的な手順としては、
-
core-js
+regenerator-runtime
を用いる - 1が正常に動かない場合、非推奨となっている
@babel/polyfill
を導入して様子を見てみる - 2が正常に動かず、一般的なメソッドの定義が欠損しているだけであれば、polyfill.ioを利用して、うまいこと逃げる
- 3でも動かない場合は、es5で書かれていないコードを見直し、適宜es5に変更していく
という戦略で望むのがよいかと思う。
IEを切り捨てられる未来はまだまだ遠い。