はじめに
政府や行政サイトの「IE縛り」に代表されるように、IE汚染国である日本で仕事としてJavaScriptを書く場合、IEと共存するしなければならない場合が多いです。
with コロナならぬwith IEです。
IE生活様式
- Transpile
- Bundle
- Polyfill
TranspileとBundle は、ES5の書き方で1つのファイルに書いていれば不要です。
エンジニアが不便を我慢すれば必要ない工程ではありますが、そんな我慢はしたくありません。
コロナで言えばマスク、消毒、手洗い、うがい、密を避ける、換気のような個人でできる対策に当たると思います。
Polyfillは、もともとIE11が対応していない機能に対応させるもので、コロナでいえば治療薬ともいえるものだと思いますが、薬なのでリスクもあります。
コロナと違って、みんなでIEやめる合意が取れればIE対応せずに済む世界になるんですが。
河野大臣、ハンコ、書面、FAXに続いて、IE対応不要もお願いします。
JavaScriptをIE11対応する
webpackとBabelのインストール
npm install -D webpack webpack-cli babel-loader @babel/core @babel/preset-env
パッケージ | 内容 |
---|---|
webpack | webpack本体 |
webpack-cli | webpackのコマンドラインツール |
babel-loader | webpackでBabelを使えるようにする |
@babel/core | Babel本体 |
@babel/preset-env | 指定したブラウザ環境で動作するように変換するプラグイン |
設定ファイルの準備
package.jsonの編集
package.jsonにビルドコマンドを追加します。
{
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
}
webpack.config.jsの作成
プロジェクトルートにwebpackの設定ファイルのwebpack.config.jsを作成します。
babelでtargetsを指定しないとbabel/preset-envがbrowserslistとの連携を行なってくれるので指定しません。
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: "babel-loader"
}
]
}
]
}
};
.babelrc
プロジェクトルートにBabelの設定ファイルの.babelrcファイルを作成します。
※webpack.config.js内に記述することもできます。
{
"presets": ["@babel/preset-env"]
}
.browserslistrc
プロジェクトルートに対象ブラウザを指定する.browserslistrcファイルを作成します。
ie 11
Transpile
TranspileするJavaScriptの準備
window.addEventListener("load", () => {
alert("InternetExplorer");
});
Transpile後のJavaScriptを読み込むHTMLの準備
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="main.js"></script>
</body>
</html>
ビルド
npm run build
動作確認
IE11でdist/index.htmlを開いて、JavaScriptが実行できているか確認します。
polyfillの追加
APIがサポートされていないなど、構文の変換だけでは対応できない機能への対応を行うpolyfillを追加できるようにします。
core-jsのインストール
npm install -S core-js
.babelrcの変更
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": {
"version": 3,
"proposals": false
}
}
]
]
}
Polyfillを追加するJavaScriptの準備
alert(Array.from("InternetExplorer"));
ビルド
npm run build
動作確認
IE11でdist/index.htmlを開いて、JavaScriptが実行できているか確認します。
regenerator-runtime
必要に応じてregenerator-runtimeを使用します。
(ビルド時にCan't resolve 'regenerator-runtime/runtime'が表示されたとき)
regenerator-runtimeのインストール
npm i -S regenerator
regenerator-runtimeのインポート
import regeneratorRuntime from "regenerator-runtime" ;
//もしくは
//import "regenerator-runtime / runtime.js" ;
TypeScriptをIE11対応する
webpackとTypeScriptのインストール
npm install -D webpack webpack-cli typescript ts-loader
table:パッケージ
パッケージ | 内容 |
---|---|
webpack | webpack本体 |
webpack-cli | webpackのコマンドラインツール |
typescript | TypeScript本体 |
ts-loader | webpackでTypeScriptを読み込む |
設定ファイルの準備
package.jsonの編集
package.jsonにビルドコマンドを追加します。
{
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
},
tsconfig.jsonの作成
tsconfigでは.browserslistrcが使えないので、targetでJavaScriptのバージョンを指定します。
{
"compilerOptions": {
"target": "ES5",
"lib": ["dom", "ES5","ScriptHost"]
}
}
target | lib省略時に暗黙的に指定されているもの |
---|---|
ES5 | DOM,ES5,ScriptHost |
ES6 | lib: DOM,ES6,DOM.Iterable,ScriptHost |
※この時点ではlibの記述は不要ですが、後でlibを追加するので先にデフォルトのlibを記述しています。
webpack.config.jsの作成
module.exports = {
module: {
rules: [
{
test: /\.ts$/,
loader: 'ts-loader'
}
]
},
resolve: {
extensions: ['.ts', '.js']
}
}
Transpile
TranspileするJavaScriptの準備
アロー関数のコードをIEで実行できるように変換
window.addEventListener("load", () => {
alert("InternetExplorer");
});
Transpile後のJavaScriptを読み込むHTMLの準備
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="main.js"></script>
</body>
</html>
ビルド
npm run build
IE11での動作確認
IE11でdist/index.htmlを開いて、JavaScriptが実行できているか確認します。
polyfillの追加
APIがサポートされていないなど、構文の変換だけでは対応できない機能への対応を行うpolyfillを追加できるようにします。
core-jsのインストール
npm install -S core-js
動作確認用のコードの準備
import "core-js";
alert(Array.from("InternetExplorer"));
tsconfig.jsonの変更
libに追加します。
{
"compilerOptions": {
"target": "ES5",
"lib": ["dom", "ES5","ScriptHost","ES2015.Core"]
}
}
今回はlibに"ES2015.Core"を追加しましたが、コードによって追加する内容は変わります。
libの値
- es5
- es6
- es2015
- es7
- es2016
- es2017
- es2018
- es2019
- es2020
- esnext
- dom
- dom.iterable
- webworker
- webworker.importscripts
- scripthost
- es2015.core
- es2015.collection
- es2015.generator
- es2015.iterable
- es2015.promise
- es2015.proxy
- es2015.reflect
- es2015.symbol
- es2015.symbol.wellknown
- es2016.array.includees2017.object
- es2017.sharedmemory
- es2017.string
- es2017.intl
- es2017.typedarrays
- es2018.asyncgenerator
- es2018.asynciterable
- es2018.intl
- es2018.promise
- es2018.regexp
- es2019.array
- es2019.object
- es2019.string
- es2019.symbol
- es2020.bigint
- es2020.promise
- es2020.string
- es2020.symbol.wellknown
- es2020.intl
- esnext.array
- esnext.symbol
- esnext.asynciterable
- esnext.intl
- esnext.bigint
- esnext.string
- esnext.promise
ビルド
npm run build
動作確認
IE11でdist/index.htmlを開いて、JavaScriptが実行できているか確認します。
regenerator-runtime
必要に応じてregenerator-runtimeを使用します。
(ビルド時にCan't resolve 'regenerator-runtime/runtime'が表示されたとき)
regenerator-runtimeのインストール
npm i -S regenerator
regenerator-runtimeのインポート
import regeneratorRuntime from "regenerator-runtime" ;
//もしくは
//import "regenerator-runtime / runtime.js" ;
環境を作らずにIE11対応する
あまり手をかけずにIE11対応をします。
Babel
https://babeljs.io/
https://babeljs.io/repl
アクセスしたブラウザ用にTranspileできるようですが、肝心のIE11が非対応のようです・・・・。
Polyfill
TranspileもBundleも不要で、Polyfillだけ使いたい場合はダウンロードしてきてHTMLから読み込めば使えるようになります。
例:intersectionObserver(https://github.com/w3c/IntersectionObserver/tree/master/polyfill)
<script src="intersection-observer.js"></script>
Fastly Polyfill
JavaScriptのPolyfillを配信しているサービスです。
※当然ですが、外部から読み込むので、polyfill.ioで障害が発生してしまったらPolyfillは無効になります。
下記URLで必要な機能を検索して、そのPolyfillを使えるURLを取得できます。
https://polyfill-fastly.io/
//ES2019の全polyfill取得
<script src="https://polyfill-fastly.io/v3/polyfill.min.js?features=es2019"></script>
//fetch機能だけのpolyfillを取得
<script src="https://polyfill-fastly.io/v3/polyfill.min.js?features=fetch"></script>