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

ECMAScript モジュール

非公式ベータ版翻訳

このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →

注意

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

実装にはバグや機能不足が存在する可能性があります。最新の状況はissueとissueトラッカーのlabelで確認してください。

また、JestがESMサポートに使用しているAPIは、Node.jsにおいても(バージョン18.8.0時点で)実験的とみなされていることに注意してください。

注意点を確認した上で、テストでESMサポートを有効化する方法を説明します。

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

  2. node--experimental-vm-modulesフラグ付きで実行します(例: 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. それ以外では、node の「ESMモード」を有効化するロジック(package.jsontypeフィールドや.mjsファイルの確認など)に従います。詳細は公式ドキュメントを参照してください。

  4. その他の拡張子(.jsx.tsなど)をESMとして扱いたい場合は、extensionsToTreatAsEsmオプションを使用してください。

ESMとCommonJSの違い

主な違いはNode.jsのドキュメントで説明されていますが、それに加えて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の使い方は基本的にjest.mockと同じですが、2つの違いがあります:ファクトリ関数が必須であること、そして同期/非同期の両方が可能なことです:

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.