webpack tsconfig.jsonが"target": "es5"でもIE11ではエラーになる

IE11ではアロー関数が使えない

IE11ではアロー関数が使えないのでJavaScript内にアロー関数があるとエラーになる。

そのため、IE11でもコードを実行したい場合はアロー関数をIE11でも実行できる形に変換する必要がある。

tsconfig.jsonのes5はアロー関数あり

tsconfig.jsonにはcompilerOptionsがあるが、compilerOptionsをアロー関数がないes5を指定しても、webpackを実行すると(() => {})();でコードがラップされてしまう。

// tsconfig.json
{
  "compilerOptions": {
    "target": "es5"
  },
  "files": [
    "index.ts"
  ]
}
// TypeScript
const add = (a: number, b: number): void => {
  console.log(a + b)
}
add(1, 2)
add(3, 4)
// JavaScript
(()=>{var o=function(o,n){console.log(o+n)};o(1,2),o(3,4)})();

このコードはIE11はアロー関数が使えないため、関数内のコードはすべてエラーとなり実行不可となる。

仕事でIE11を使用することがあるのだが、これを知らずにコンパイル後のJavaScriptコードにアロー関数を含むWebサイトがたまにあるため注意が必要。

この問題はwebpack側の問題なのでwebpack.config.jsにtarget: ['web', 'es5'],を追記すれば解消できる。

const path = require('path')

module.exports = () => {
  return {
    mode: 'production',
    target: ['web', 'es5'],
    entry: {
      index: path.join(__dirname, 'index.ts')
    },
    output: {
      path: path.join(__dirname, 'dist'),
      filename: 'index.js'
    },
    module: {
      rules: [
        {
          use: [{ loader: 'ts-loader' }],
          test: /\.ts$/
        }
      ]
    }
  }
}

tsconfig.jsonがes6以上だと無効

「webpack.config.jsにtarget: ['web', 'es5'],を追記すれば解消できる」と書いたが、TypeScriptを使用していてcompilerOptionsでtargetにes6以降を指定している場合はwebpack.config.jsのtarget指定が効かなくなることがある。
(アロー関数で書き出される)

{
  "compilerOptions": {
    "target": "es6"
  },
  "files": [
    "index.ts"
  ]
}

例えば以下のようにtsconfig.jsonのtargetがes6以降でなければコンパイルできないコードの場合はtsconfig.jsonにes6、webpack.config.jsがes5が設定されている場合はes6(アロー関数)で書き出される。

class Person {
  #_age!: number

  get age(): number {
    return this.#_age
  }

  set age(v: number) {
    if (v < 0) {
      throw new RangeError('age >= 0')
    }
    this.#_age = v
  }
}

const p = new Person()
p.age = 10
console.log(p.age);