Zum Hauptinhalt springen
Version: 29.7

ECMAScript-Module

Inoffizielle Beta-Übersetzung

Diese Seite wurde von PageTurner AI übersetzt (Beta). Nicht offiziell vom Projekt unterstützt. Fehler gefunden? Problem melden →

Vorsicht

Jest bietet experimentelle Unterstützung für ECMAScript-Module (ESM).

Die Implementierung kann Fehler enthalten und Funktionen vermissen. Für den aktuellen Status siehe das Issue und das Label im Issue-Tracker.

Beachten Sie auch, dass die APIs, die Jest für die ESM-Unterstützung verwendet, von Node weiterhin als experimentell betrachtet werden (Stand Version 18.8.0).

Nach diesen Warnungen zeigen wir Ihnen, wie Sie die ESM-Unterstützung in Ihren Tests aktivieren.

  1. Stellen Sie sicher, dass Sie entweder Code-Transformationen deaktivieren, indem Sie transform: {} übergeben, oder konfigurieren Sie Ihren Transformer so, dass er ESM statt des Standard-CommonJS (CJS) ausgibt.

  2. Führen Sie node mit --experimental-vm-modules aus, z.B. node --experimental-vm-modules node_modules/jest/bin/jest.js oder NODE_OPTIONS="$NODE_OPTIONS --experimental-vm-modules" npx jest usw.

    Unter Windows können Sie cross-env verwenden, um Umgebungsvariablen setzen zu können.

    Wenn Sie Yarn verwenden, können Sie yarn node --experimental-vm-modules $(yarn bin jest) nutzen. Dieser Befehl funktioniert auch bei Verwendung von Yarn Plug'n'Play.

    Wenn Ihr Codebase ESM-Imports aus *.wasm-Dateien enthält, müssen Sie --experimental-wasm-modules nicht an node übergeben. Die aktuelle Implementierung von WebAssembly-Imports in Jest basiert auf experimentellen VM-Modulen, dies könnte sich jedoch in Zukunft ändern.

  3. Darüber hinaus versuchen wir, der Logik von node für die Aktivierung des "ESM-Modus" zu folgen (z.B. durch Prüfung von type in package.json oder .mjs-Dateien). Details finden Sie in deren Dokumentation.

  4. Wenn Sie andere Dateiendungen (wie .jsx oder .ts) als ESM behandeln möchten, verwenden Sie die Option extensionsToTreatAsEsm.

Unterschiede zwischen ESM und CommonJS

Die meisten Unterschiede sind in Nodes Dokumentation erklärt. Zusätzlich zu den dort genannten Punkten injiziert Jest eine spezielle Variable in alle ausgeführten Dateien - das jest-Objekt. Um in ESM auf dieses Objekt zuzugreifen, müssen Sie es aus dem Modul @jest/globals importieren oder import.meta verwenden.

import {jest} from '@jest/globals';

jest.useFakeTimers();

// etc.

// alternatively
import.meta.jest.useFakeTimers();

// jest === import.meta.jest => true

Modul-Mocking in ESM

Da ESM statische import-Anweisungen auswertet, bevor der Code betrachtet wird, funktioniert das Hoisting von jest.mock-Aufrufen, das in CJS stattfindet, nicht für ESM. Um Module in ESM zu mocken, müssen Sie require oder dynamisches import() nach jest.mock-Aufrufen verwenden, um die gemockten Module zu laden - dasselbe gilt für Module, die die gemockten Module laden.

ESM-Mocking wird über jest.unstable_mockModule unterstützt. Wie der Name schon sagt, ist diese API noch in Arbeit. Bitte verfolgen Sie dieses Issue für Updates.

Die Verwendung von jest.unstable_mockModule ist im Wesentlichen dieselbe wie bei jest.mock mit zwei Unterschieden: Die Factory-Funktion ist erforderlich und sie kann synchron oder asynchron sein:

import {jest} from '@jest/globals';

jest.unstable_mockModule('node:child_process', () => ({
execSync: jest.fn(),
// etc.
}));

const {execSync} = await import('node:child_process');

// etc.

Für das Mocking von CommonJS-Modulen sollten Sie weiterhin jest.mock verwenden. Siehe Beispiel unten:

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.