メインコンテンツへスキップ
バージョン: 29.7

ECMAScript モジュール

注意

Jest は、実験的な ECMAScript モジュール (ESM) のサポートを提供しています。

実装にはバグが含まれている可能性があり、機能が不足している可能性があります。最新の状況については、issue と、issue トラッカーのラベルを確認してください。

また、Jest が ESM サポートを実装するために使用する API は、Node (バージョン18.8.0 現在) によってもまだ実験的とみなされています

警告を踏まえた上で、テストで ESM サポートを有効にする方法を説明します。

  1. transform: {} を渡すことでコード変換を無効にするか、またはトランスフォーマを構成して、デフォルトの CommonJS (CJS) ではなく ESM を出力するようにしてください。

  2. --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 モジュールに依存していますが、これは将来変更される可能性があります。

  3. それ以外では、「ESM モード」の有効化に関する node のロジックに従います (package.jsontype.mjs ファイルの確認など)。詳細はNode のドキュメントを参照してください。

  4. 他のファイル拡張子(.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 を使用してください。以下の例を参照してください。

main.cjs
const {BrowserWindow, app} = require('electron');

// etc.

module.exports = {example};
main.test.cjs
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.