🃏

Jest実行時にJest encountered an unexpected token が出てつらい思いをした

2024/01/23に公開

何が起きたか

import { getGridLocalization } from '@mui/x-data-grid/utils/getGridLocalization';

〜略〜

上記のようなimportがあるファイルを呼び出したテストファイル実行時に、エラーが発生😠

● Test suite failed to run
    Jest encountered an unexpected token
    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
    By default "node_modules" folder is ignored by transformers.
    〜略〜
    SyntaxError: Cannot use import statement outside a module
    > 1 | import { getGridLocalization } from '@mui/x-data-grid/utils/getGridLocalization';

Jestがファイルの解析に失敗しているらしい

原因

JestはCommonJsで実行されているため、ESMで書かれたファイルは変換が必要ですが、
デフォルトの設定によりnode_modules配下のファイルは変換されないようになっています

しかし新しめのパッケージなどはESMで書かれているものもあり、CommonJsが用意されていないとエラーになるようです

@mui/x-data-grid/utils/getGridLocalizationはESMで書かれていてCommonJsが用意されていないため、変換されずエラーとなっていたようです

解決方法

設定ファイルにnode_modulesでも変換するようにする対象を指定します
今回は@mui/x-data-grid/utilsを対象にして実行したところ
@babel/runtime/helpers/esmでも発生している旨のエラーが出ていたため以下のように設定しました

// ここに変換したい対象を指定していく
const esModules = ['@mui/x-data-grid/utils', '@babel/runtime/helpers/esm'].join('|');

const jestConfig = {
  // 〜その他設定〜
  transformIgnorePatterns: [`/node_modules/(?!${esModules})`],
  transform: {
    [`(${esModules}).+\\.js$`]: "ts-jest",
  },
}
export default jestConfig;

transformIgnorePatterns

変換から除外したい対象を指定
esModulesに記載したディレクトリ以外のnode_modulesのディレクトリ)

transform

変換する対象を指定
esModulesに記載したディレクトリの.jsファイル

これでテストが通るようになりました、やった〜🥇

今後も同じエラーが出たら以下に対象を追加していけばok

const esModules = ['@mui/x-data-grid/utils', '@babel/runtime/helpers/esm'].join('|');

とはいえ全て追加するのはめんどうなので、早くJestでもESM使えるようになるといいですね🦥

Discussion