lazy developers blog

Laravel MixでTypescriptをトランスパイルする(IE11対応)

IE11のサポート終了が近づいてきていますが、しばらくはIE11に対応する必要があると思います。今回、Laravel Mixを使用してTypescriptをトランスパイルする際に、IE11に対応させるための設定を紹介します。

環境

  • Typescript : 4.3.5
  • laravel-mix : 6.0.25
  • laravel-mix-polyfill : 3.0.1

Laravel Mixの使用方法

まずはLaravel Mixを使用し、Typescriptをトランスパイルしていきます。

Laravel Mixのインストール

npmまたはyernを使用してLaravel Mixをインストールします。

1npm init -y
2npm i -D laravel-mix

Typescriptのトランスパイルに必要な以下のパッケージもインストールしておきます。

1npm i -D typescript ts-loader

設定ファイルの作成

Laravel Mixの設定ファイルをwebpack.mix.jsという名前でプロジェクト直下に作成します。 ディレクトリ構造は以下のようになります。

1root
2  ┣ node_modules/
3  ┣ package.json
4  ┗ webpack.mix.js

index.tsという名前のTypescriptファイルをトランスパイルし、distフォルダに出力する場合、webpack.mix.jsは以下のようになります。

webpack.mix.js
1const mix = require('laravel-mix');
2
3mix.ts('src/index.ts', 'dist');

index.tsファイルにアラートを出力するだけのプログラムを書きます。

index.ts
1alert('hello world');

Typescriptをトランスパイルするための設定ファイルを作成します。

1./node_modules/.bin/tsc   // or npx tsc --init

プロジェクト直下にtsconfig.jsonファイルが作成されます。

1root
2  ┣ node_modules/
3  ┣ package.json
4  ┣ tsconfig.json
5  ┗ webpack.mix.js

tsconfig.jsonファイルの中身をプロジェクトに応じて修正します。 (今回はそのまま使用します。)

tsconfig.json
1{
2  "compilerOptions": {
3    "target": "es5",
4    "module": "commonjs",
5    "strict": true,
6    "esModuleInterop": true,
7    "skipLibCheck": true,
8    "forceConsistentCasingInFileNames": true
9  }
10}

コンパイル(トランスパイル)

Typescriptをコンパイルします。

npxコマンドを使用してコンパイルする

以下のコマンドを使用してコンパイルします。

1npx mix --production

package.jsonのscriptsを利用してコンパイルする

package.jsonファイルのscriptsに以下を追加します。

package.json
1{
2  "scripts": {
3    "prod": "mix --production"
4  }
5}

npm runコマンドを使用して、コマンドを実行します。

1npm run prod

distフォルダにindex.jsという名前のファイルが作成されます。作成されたファイルの中身を見ると、アロー関数が使用されているため、このままではIE11で動作しないので、laravel-mix-polyfillを使用してIE11でも動作するようにします。

index.js
1(()=>{"use strict";alert("hello world")})();

Laravel Mix Polyfillの使用方法

npmまたはyarnを使用してLaravel Mix Polyfillをインストールします。

1npm i -D laravel-mix-polyfill

設定ファイルの編集

webpack.mix.jsファイルを以下のように書き換えます。

webpack.mix.js
1const mix = require('laravel-mix');
2
3require('laravel-mix-polyfill');
4
5mix.ts('src/index.ts', 'dist')
6  .polyfill({
7    enabled: true,
8    useBuiltIns: "usage",
9    targets: "ie 11"
10  });

この状態でコンパイルを実行した場合、作成されるindex.jsファイルは以下のようになります。アロー関数を関数式に置き換えてくれるため、IE11でも問題なく動作します。

index.js
1!function(){"use strict";alert("hello world")}();

※先頭が!になっていますが、これはjavascriptの即時関数の書き方が複数あるためで、以下のコードと同じです。

1(function(){"use strict";alert("hello world")})();
2// or
3(function(){"use strict";alert("hello world")}());

targetsプロパティについて

targetsプロパティを設定すると、webpackのtargetプロパティに指定した値が設定されます。 例えば、ie 11と指定した場合は以下のように設定されます。

1"target": "browserslist:ie 11"

Laravel Mix Polyfillのtargetsの書き方について

webpackのtargetとは違い、Laravel Mix Polyfillのtargetsには文字列しか指定できません。文字列以外を指定した場合、targetにはデフォルトの値(browserslist or web)が使用されます。

こちらのQiitaの記事では、targetsにオブジェクトを指定していますが、現状これは正常に動作しません。

browserslistのデフォルト値は> 0.5%, last 2 versions, Firefox ESR, not deadです。 その場合、現時点でのブラウザの一覧は以下のようになるため、IE11でも動作することになります。

1$ npx browserslist
2and_chr 91
3and_ff 89
4and_qq 10.4
5and_uc 12.12
6android 91
7baidu 7.12
8chrome 91
9chrome 90
10edge 91
11edge 90
12firefox 89
13firefox 88
14firefox 78
15ie 11
16ios_saf 14.5-14.7
17ios_saf 14.0-14.4
18ios_saf 13.4-13.7
19kaios 2.5
20op_mini all
21op_mob 62
22opera 77
23opera 76
24safari 14.1
25safari 14
26samsung 14.0
27samsung 13.0

.browserslistrcファイルを使用してターゲットを指定する

webpack.mix.jsでは指定せず、プロジェクトの直下に.browserslistrcファイルを配置しても設定できます。 ※両方で指定した場合は、webpack.mix.jsで指定した方が優先されます。

.browserslistrc
1IE 11

package.jsonのbrowserslistを使用してターゲットを指定する

package.jsonファイルにbrowserslistを指定することでも設定できます。

package.json
1{
2  "browserslist": [
3    "ie 11"
4  ]
5}

useBuiltInsプロパティについて

Laravel Mixは、内部でbabelを使用してTypescriptをjavascriptにトランスパイルしており、useBuiltInsプロパティにより、polyfillをどのように設定するか選択できます。 設定できる値は、"usage" | "entry" | falseの内のどれかで、デフォルトはfalseが設定されています。

動作の違いを見るために以下のようなファイルをそれぞれトランスパイルしてみます。

index.ts
1const a = new Map();

new Map()はES2015(ES6)で追加された機能ですが、アロー関数のように単純に置き換えができないためpolyfillを読み込むことになります。

usageの場合

必要なpolyfillのみ追加されます。ファイルサイズは最小限になります。

entryの場合

browserslistに指定されたブラウザに必要なpolyfillを全て追加します。ファイルサイズは大きくなります。

falseの場合

polyfillを自動で追加しません。そのため、手動で読み込む必要があります。

おわりに

Laravel Mixを使用する場合のTypescriptのトランスパイルで、IE11に対応するための設定を紹介してきました。Laravel Mix Polyfillのtargetsの指定が文字列であることを知っていれば特に難しいことはないと思います。

ただ、Tree Shakingなどの機能はIEでは使用できないため、IE11に対応する必要がなくなる日が待ち遠しいです。