かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Jest テスト内で axios のインポートが出来ないエラーにハマる

Jest を使ったテストをしていて axios を使っているコンポーネントのテストで下記のようなエラーになった

SyntaxError: Cannot use import statement outside a module
    > 1 | import axios from 'axios';
        | ^

SyntaxError: Cannot use import statement outside a module

axios が import できないっぽい。なんでや!

環境
  • jest 26.6.3
  • axios 1.4.0

axios が ESM で提供されていて、Jest が CommonJS で実行されるためにエラーが発生している

For context: Problem seem to be that Axios is now built as ES Module instead of CommonJs when not run in Node. Problem with Jest is that it runs code in Node, but application is built for web-clients. This is why telling Jest to transform Axios works.
cf. Jest tests failed after upgrading axios to v1.1.2 · Issue #5101 · axios/axios · GitHub

jest は node_module かのファイルを変換しないので ESM の axios の import/export が上手く扱えずエラーになっているっぽ

Basically, jest runs on Node.js environment, so it uses modules following the CommonJS. If you want to use axios up to 1.x.x, you have to transpile the JavaScript module from ECMAScript type to CommonJS type. Jest ignores /node_modules/ directory to transform basically.
cf. node.js - "Cannot use import statement outside a module" with Axios - Stack Overflow

axios 内にある CommonJS でビルドされたパスを Jest に設定する事で解決できる

node_modules にインストールされた axios 内には CommonJS にビルドされたものがあるので、そのパスを moduleNameMapper で Jest に渡してあげれば良い

package.json

"jest": {
  "moduleNameMapper": {
    "^axios$": "axios/dist/node/axios.cjs"
  }
}

jest.config.ts を作成している場合は require.resolve('axios') でもいけるらしい

moduleNameMapper: {
  '^axios$': require.resolve('axios'),
},

cf. Jest tests failed after upgrading axios to v1.1.2 · Issue #5101 · axios/axios · GitHub


[参考]