IE11案件のべき乗対応

2 min read読了の目安(約2500字

背景

残念なことにIE11も要件に入っているサイトのスクリプトをTypescriptで記述している。

現象

使用しているライブラリで記述しているべき乗**がビルドされたJavascriptにもそのままで出力されている。

Buffer.prototype.readBigUInt64LE = defineBigIntMethod(function readBigUInt64LE (offset) {
  offset = offset >>> 0
  validateNumber(offset, 'offset')
  const first = this[offset]
  const last = this[offset + 7]
  if (first === undefined || last === undefined) {
    boundsError(offset, this.length - 8)
  }

  const lo = first +
    this[++offset] * 2 ** 8 +
    this[++offset] * 2 ** 16 +
    this[++offset] * 2 ** 24

  const hi = this[++offset] +
    this[++offset] * 2 ** 8 +
    this[++offset] * 2 ** 16 +
    last * 2 ** 24

  return BigInt(lo) + (BigInt(hi) << BigInt(32))
})

IE11は**を認識しないため、実行時に構文エラーが発生する。

調査

べき乗**はES2016(ES7)で採用されている。

IE11には存在していないオブジェクトやメソッドの代替コードを提供してくれるのはPolyfill。Polyfillとして、core-jsというのを使用している。しかし、今回のエラーは構文エラーなので、polyfillでは解決できない。
TypescriptからJavascriptへの構文変換はBabelかTypescript自身のtscツールを利用する。今回はtscを利用している。
なので、構文変換はtsconfig.jsonを変更する。
compilerOptions.targetはIE11もターゲットなのでes5を選択している。

対応

tsconfig.jsonのcompileOptions.libにES2016を追加してビルドをした。

{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig.json to read more about this file */

    /* Basic Options */
    // "incremental": true,                   /* Enable incremental compilation */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "amd",                          /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "lib": [
      "DOM",
      "ES5",
      "ES2016",  /* ES2016を追加した */
      "ScriptHost"
    ],

ビルドしたjsファイルを読み込ませてIE11で実行したところ、エラーは解消された。

2018年に見直した現代的なJavaScriptの記法を紹介するぜ」の最後の方に書かれている崩れた表に、polyfillを使うべきかトランスパイルで対応すべきか、またその時のECMAScriptバージョンが記述されているので、参考にするとよい。

出典