Modules ECMAScript
Jest ships with experimental support for ECMAScript Modules (ESM).
The implementation may have bugs and lack features. For the latest status check out the issue and the label on the issue tracker.
Also note that the APIs Jest uses to implement ESM support are still considered experimental by Node (as of version 18.8.0
).
Une fois les avertissements levés, voici comment activer le support ESM dans vos tests.
-
Ensure you either disable code transforms by passing
transform: {}
or otherwise configure your transformer to emit ESM rather than the default CommonJS (CJS). -
Execute
node
with--experimental-vm-modules
, e.g.node --experimental-vm-modules node_modules/jest/bin/jest.js
orNODE_OPTIONS="$NODE_OPTIONS --experimental-vm-modules" npx jest
etc.Sous Windows, vous pouvez utiliser
cross-env
pour pouvoir définir des variables d'environnement.Si vous utilisez Yarn, vous pouvez utiliser
yarn node --experimental-vm-modules $(yarn bin jest)
. Cette commande fonctionnera également si vous utilisez Yarn Plug'n'Play.If your codebase includes ESM imports from
*.wasm
files, you do not need to pass--experimental-wasm-modules
tonode
. Current implementation of WebAssembly imports in Jest relies on experimental VM modules, however, this may change in the future. -
Au-delà, nous essayons de suivre la logique de
node
pour activer le « mode ESM » (comme regardertype
dans les fichierspackage.json
ou.mjs
), consultez leurs docs pour plus de détails. -
Si vous souhaitez traiter d'autres extensions de fichiers (comme
.jsx
ou.ts
) en tant que ESM, veuillez utiliser l'optionextensionsToTreatAsEsm
.
Différences entre ESM et CommonJS
La plupart des différences sont expliquées dans la documentation de Node, mais en plus des choses qui y sont mentionnées, Jest injecte une variable spéciale dans tous les fichiers exécutés - l'objet jest
. Pour accéder à cet objet dans ESM, vous devez l'importer depuis le module @jest/globals
ou utiliser import.meta
.
import {jest} from '@jest/globals';
jest.useFakeTimers();
// etc.
// alternativement
import.meta.jest.useFakeTimers();
// jest === import.meta.jest => true
Module mocking in ESM
Puisque ESM évalue les déclarations statiques import
avant de regarder le code, le hoisting des appels jest.mock
qui se produit dans CJS ne fonctionnera pas pour ESM. Pour simuler des modules en ESM, vous devez utiliser un require
ou un import()
dynamique après les appels jest.mock
pour charger les modules simulés - il en va de même pour les modules qui chargent les modules simulés.
La simulation ESM est supportée par jest.unstable_mockModule
. As the name suggests, this API is still work in progress, please follow this issue for updates.
L'utilisation de jest.unstable_mockModule
est essentiellement la même que jest.mock
avec deux différences : la fonctionfactory est requise et elle peut être synchrone ou asynchrone :
import {jest} from '@jest/globals';
jest.unstable_mockModule('node:child_process', () => ({
execSync: jest.fn(),
// etc.
}));
const {execSync} = await import('node:child_process');
// etc.
Pour la simulation des modules CJS, vous devez continuer à utiliser jest.mock
. Voir l'exemple ci-dessous :
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.