ECMAScript モジュール
Jest は、実験的な ECMAScript モジュール (ESM) のサポートを提供しています。
実装にはバグが含まれている可能性があり、機能が不足している可能性があります。最新の状況については、issue と、issue トラッカーのラベルを確認してください。
また、Jest が ESM サポートを実装するために使用する API は、Node (バージョン18.8.0
現在) によってもまだ実験的とみなされています。
警告を踏まえた上で、テストで ESM サポートを有効にする方法を説明します。
-
transform: {}
を渡すことでコード変換を無効にするか、またはトランスフォーマを構成して、デフォルトの CommonJS (CJS) ではなく ESM を出力するようにしてください。 -
--experimental-vm-modules
を使用してnode
を実行します。例:node --experimental-vm-modules node_modules/jest/bin/jest.js
またはNODE_OPTIONS="$NODE_OPTIONS --experimental-vm-modules" npx jest
など。Windows では、環境変数を設定するために
cross-env
を使用できます。Yarn を使用している場合は、
yarn node --experimental-vm-modules $(yarn bin jest)
を使用できます。このコマンドは、Yarn Plug'n'Play を使用する場合にも機能します。コードベースに
*.wasm
ファイルからの ESM インポートが含まれている場合、node
に--experimental-wasm-modules
を渡す必要はありません。Jest の WebAssembly インポートの現在の実装は実験的な VM モジュールに依存していますが、これは将来変更される可能性があります。 -
それ以外では、「ESM モード」の有効化に関する
node
のロジックに従います (package.json
のtype
や.mjs
ファイルの確認など)。詳細はNode のドキュメントを参照してください。 -
他のファイル拡張子(
.jsx
や.ts
など)を ESM として扱う場合は、extensionsToTreatAsEsm
オプション を使用してください。
ESM と CommonJS の違い
違いの大部分はNode のドキュメントで説明されていますが、そこに記載されていることに加えて、Jest は実行されるすべてのファイルに特別な変数、jest
オブジェクトを挿入します。ESM でこのオブジェクトにアクセスするには、@jest/globals
モジュールからインポートするか、import.meta
を使用します。
import {jest} from '@jest/globals';
jest.useFakeTimers();
// etc.
// alternatively
import.meta.jest.useFakeTimers();
// jest === import.meta.jest => true
ESM でのモジュールモック
ESM はコードを見る前に静的な import
ステートメントを評価するため、CJS で行われる jest.mock
呼び出しのホイスティングは ESM では機能しません。ESM でモジュールをモックするには、jest.mock
呼び出しの後で、モックされたモジュールをロードするために require
または動的な import()
を使用する必要があります。モックされたモジュールをロードするモジュールにも同じことが当てはまります。
ESM モックは jest.unstable_mockModule
でサポートされています。名前が示すように、この API はまだ開発中であるため、この issue をフォローしてアップデートを確認してください。
jest.unstable_mockModule
の使い方は、ファクトリ関数が必須であり、同期または非同期にすることができるという2つの違いを除いて、jest.mock
と基本的に同じです。
import {jest} from '@jest/globals';
jest.unstable_mockModule('node:child_process', () => ({
execSync: jest.fn(),
// etc.
}));
const {execSync} = await import('node:child_process');
// etc.
CJS モジュールのモックには、引き続き jest.mock
を使用してください。以下の例を参照してください。
const {BrowserWindow, app} = require('electron');
// etc.
module.exports = {example};
import {createRequire} from 'node:module';
import {jest} from '@jest/globals';
const require = createRequire(import.meta.url);
jest.mock('electron', () => ({
app: {
on: jest.fn(),
whenReady: jest.fn(() => Promise.resolve()),
},
BrowserWindow: jest.fn().mockImplementation(() => ({
// partial mocks.
})),
}));
const {BrowserWindow} = require('electron');
const exported = require('./main.cjs');
// alternatively
const {BrowserWindow} = (await import('electron')).default;
const exported = await import('./main.cjs');
// etc.