Nuxt.js製WebアプリをIE11対応させるために(Javascript編)

## 概要

Nuxt.jsは、本体と自分で書いたコードは勝手にIE対応してくれるけれども、外部ライブラリはしてくれないので自分で設定をする必要があります。
よのなかのHow to記事には、外部ライブラリはトランスパイルする必要があるので設定しよう！というものはたくさん見たのですが、いやどれをすりゃいいのよというところには答えてくれるものが見つけられず、自分で頑張ってみた記録です。

新しい記法を使っているライブラリをトランスパイル対象に加えることと、Polyfill用のスクリプトの読み込みを行います。
(トランスパイルやPolyfillとはなんぞやというのは、末尾につけてあります。)

また、この記事の対策はベストではないとおもっています、もっと詳しい方がいたらツッコミを入れてほしいというのもこの記事の目的の一つです。
Javascript編とある理由はCSSのほうでもいろいろ苦労したのからなのですが、、いまのところそちらは記事として書く予定はないです。

では、以下からスタート。

## Polyfill

[polyfill.io](https://polyfill.io/v3/)では、アクセス元のブラウザに対して必要なPolyfillを返してくれる便利なサイトがあります。
必要な機能だけに絞ることもできるのですが、、

https://polyfill.io/v3/url-builder/

どの機能を含める必要があるのかひとつひとつ調べるのは大変なので、まとめて読み込むことにします。
FirefoxやChromeといったまともなブラウザを、ちゃんと更新して使っていればほとんど空のファイルが返ってくるだけなので、ファイルをダウンロードする時間がちょっと増えてしまいますが、ブラウザがサポートしている機能をPolyfillで上書きしたりといったことは起きないはずです。

```javascript:nuxt.config.js
export default {
  ...
  head: {
    script: [
      { src: 'https://polyfill.io/v3/polyfill.min.js' } // 追加
    ],
  },
  ...
}
```

Nuxt.js本体や自分で書いたコードがPolyfillされるということは、外のライブラリをわざわざみにいかなくてもビルド時のオプションでどうにかなりそうな気はします。
これは詳しい人がいたらおしえてほしい、、。

## 外部ライブラリのトランスパイル

Polyfillと違って、こちらはちょっと大変です。
ライブラリをトランスパイル対象に入れるには、nuxt.config.jsで以下のようにライブラリ名を書くだけです。正規表現を使って、特定のパターンの名前のライブラリをまとめて指定することも可能です。

```javascript:nuxt.config.js
export default {
  ...
  build: {
    transpile: ['vuetify']
  },
  ...
}
```

最初は楽をしようと思って、ここに

```
transpile: [/.+/]
```

とすべてのライブラリが対象になるようにしてみたのですが、悲しいことに現在のプロジェクトではChromeですら動かないコードが出来てしまいました。また、ビルド時間もかなり長くなってしまっていたので、できるだけ最小限に留めるべきだと思います。

で、このどのライブラリをトランスパイル対象にすべきかという調査が大変でした。。。

Windowsの検証機がなかったため、人から借りてプロダクションビルドをデプロイした環境をみてもらうことしかできませんでした。
このためちょっとまわりくどいことをしています。

### トランスパイル対象のライブラリを調べる

#### 1. IEで問題を起こしている記法を見つける

production環境でIEを使いページを開き、ページが開けていないことを確認します。(もし開けていたらそもそも対策いらないのでハッピーですね。)
開発者ツールのコンソールを開き、エラーを起こしている行を見てなにが起きているかを確認します。

`SCRIPT1002` というエラーになっていたら、アロー関数や`class`が使用されていないか見ます。
エラーの特定には、下の記事がとても役に立ちました。

https://qiita.com/siruku6/items/3465fd6e0588ee35cc78

#### 2. その記法がなんのライブラリ由来か調べる

devモードでNuxtサーバーを立ち上げ、FirefoxなりChromeでアクセスします。
`_nuxt/vendors/app.js` がバンドルされた外部ライブラリがまとめられているファイルなので、これを分析します。
たとえば、アロー関数 `=>` がIEで問題を起こしている場合、アロー関数が使われている箇所を探して、その数行上を見るともとのライブラリ名がわかります。下の例では、ansi-regexというライブラリが怪しそうです。

![devtool.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133157/2bd2b08d-cd77-c029-8f80-702503cfdab2.png)

名前がわかったら、このライブラリを先程のようにnuxt.config.jsのトランスパイル対象にいれます。
リロードして、さきほどはあったアロー関数がなくなったことを確認しましょう。

#### 3. 1と2を繰り返す

1の工程で、エラーが全部出てくれたら良いのですが、最初に見つかったIE非対応の構文しかしることができません。
アロー関数をつぶして、次はclassをつぶして、次は…というように、ひとつひとつ対処しました。

## 前提知識

新しいJavascriptを古いブラウザに対応させるには、２つやることがあります。
ひとつはトランスパイル。こちらはアロー関数のような、そもそも古いブラウザについているJavascriptインタープリターだと構文としてエラーになってしまうものを、古いJavascriptの書き方に直すものです。

たとえば、

```javascript
() => {
  [1, 2, 3].map(e => console.log(e * 2) )
}
```

を、

```javascript
(function () {
  [1, 2, 3].map(function (e) {
    return console.log(e * 2);
  });
});
```

Polyfillは、文法的にただしいけれどもうごかない機能を追加するものです。
たとえば、Array.prototype.includesのような。

```javascript
[1, 2, 3].includes(3)
// => true
```

Array.prototypeに新しいメソッドを生やすようです。
例を貼ってみようと思ったのですが、長くてやめました。

https://polyfill.io/v3/polyfill.js?features=Array.prototype.includes

を、IEやらwgetやらでアクセスすると見ることができます。