(2020/07/03 ... 記事を全面リニューアルしました)
令和の時代、わが国の企業は大部分が未だIEの呪縛に囚われている・・・
MicrosoftがいくらIEを非推奨としてEdge(Chromium)を推奨しても、御社の情シスはそれを許しません。
そんな闘う社内エンジニアの方々に朗報です。
HTMLサンプル
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="height=device-height, width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<script src="https://cdn.jsdelivr.net/npm/@babel/polyfill@latest/dist/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@babel/standalone@latest/babel.min.js"></script>
<title>Babel</title>
</head>
<body>
Babel Test
</body>
<style>
html{
color: #d8d8d8;
background-color: #242424;
}
</style>
<script type="text/babel" data-presets="env,stage-3">
class FileReaderEx extends FileReader{
constructor(){
super();
}
#readAs(blob, ctx){
return new Promise((res, rej)=>{
super.addEventListener("load", ({target}) => res(target.result));
super.addEventListener("error", ({target}) => rej(target.error));
super[ctx](blob);
});
}
readAsArrayBuffer(blob){
return this.#readAs(blob, "readAsArrayBuffer");
}
readAsDataURL(blob){
return this.#readAs(blob, "readAsDataURL");
}
readAsText(blob){
return this.#readAs(blob, "readAsText");
}
}
(async()=>{
const blob = new Blob([new Uint8Array(1024)]);
const buffer = await new FileReaderEx().readAsArrayBuffer(blob);
console.log(buffer);
})();
</script>
</html>
バリバリなES6+ですが、このHTMLはそっくりそのままIE11で動きます。
解説
@babel/standalone
というBabelのスタンドアロン版を使用します。
通常版はWebpackやParcelといったビルドツール経由で受動的に使用されることを前提としているのに対し、スタンドアロン版はそれ単体で能動的に動作します。
@babel/polyfill
はBabelがトランスパイル時に使用する機能も含まれているので@babel/standalone
より先にロードする必要があります。
具体的な動作としては、HTML内の<script type="text/babel">
タグを検出し、その中のソースコードをトランスパイルした後にHTML内へ挿入します。
通常であればbabelrcに記載するコンフィグはdata-xxx
属性へ記載します。
{
"presets": [
"@babel/preset-env",
"@babel/preset-stage-3"
]
}
<script type="text/babel" data-presets="env,stage-3">
また、Babelはwindow.Babel
としてグローバルスコープへ展開されているので、ソースコードを任意のタイミングでトランスパイルすることも可能です。
const src = "(async() => await new Promise(res => res(1)))();";
const transpiled = Babel.transform(src, {
presets: ["env", "stage-3"]
}).code;
なお、通常版は7.4.0
から@babel/polyfill
の使用が非推奨となり、代わりにポリフィル内部で使用されていたcore-js
とregenerator
を直接ロードする方法が推奨となりました。
しかし、この2つは現時点ではバンドル済のコードが存在しないため、スタンドアロン版ではバンドル済の@babel/polyfill
を使用する必要があります。
おわりに
御社が1日も早くIEの呪縛から解放されますように...