Open2

バグ対応をメモしていく

ocknamoocknamo

jestでReferenceError: TextDecoder is not defined

ReferenceError: TextDecoder is not defined

yarn.lockを削除してyarnをし直しただけなのに、jestのtestで上記のエラーが出るようになった。
(実際はもっと泥臭くてyarn.lock削除が原因だと突き止めるのに1時間くらいかかっている)

調べるとこちらのissueが出てきた。

https://github.com/ipfs/js-ipfs/issues/3620

web-encodingの1.1.3と1.1.4でTextDecoderのコンストラクターが無くなっているらしい。
yarnを使っていたので書かれているように以下のオプションを追加した。

  "resolutions": {
    "web-encoding": "1.1.3"
  },

しかし同じエラーが出続けている。issueは既にクローズされている。

一旦yarn.lockファイルをもとに戻して、web-encodingを1.1.3,1.1.4などに変更してもエラーが出ないのでこのissueは関係ないことがわかった。

web-encodingの方を見てみる。似たような感じのissueが上がっている。

https://github.com/Gozala/web-encoding/issues/1#issuecomment-676811667

jestのバグだからjestのバージョンを上げろとのことなので試すが特に変わらず。jestがまだ対応していないのか?
ググって解決することを諦めてエラーが発生しているmultibaseの該当コードを検証してみることに。

'use strict'

const textDecoder = new TextDecoder()

TextDecoderはモジュールから読み込まれていない。TextDecoderってそもそもなんだっけ。

// typescript/lib/lib.dom.d.ts
declare var TextDecoder: {
    prototype: TextDecoder;
    new(label?: string, options?: TextDecoderOptions): TextDecoder;
};

あっ。”typescript/lib/lib.dom.d.ts”

これWEB APIだわ。ということにやっと気がつく。

https://developer.mozilla.org/ja/docs/Web/API/TextDecoder

jestの実行環境でTextDecoderが存在しないことが問題なのだとするとjestのバグとかでissueが上がっているはず。

ググったらあった。

https://github.com/facebook/jest/issues/9983

jestが使っているjsdomがTextDecoderTextEncoderをサポートしていないらしい。
結果としてjestのセットアップファイル(setupJest.tsなど)に以下のポリフィルを追加して解決した。

// Polyfill for encoding which isn't present globally in jsdom
if (typeof global.TextEncoder === 'undefined') {
  global.TextEncoder = TextEncoder;
}

if (typeof global.TextDecoder === 'undefined') {
  global.TextDecoder = TextDecoder;
}

反省

  • ググったほうが速い場合もあるが今回は罠にはまった。(でも普通とりあえずググるよね)
  • WEBAPIの知識がちゃんとしてればもっと早く対処できたので基礎知識大事。
ocknamoocknamo

「おもしろい?バグ」というタイトルにしてみたけど書いたやつがあんまり面白くないし、ハードルを下げるために「バグ対応をメモしていく」に変更しました。

どうやってバグ対応したかとかすぐ忘れちゃうので備忘録です。