This post goes over how to enable ECMAScript Modules (ESM) support for Jest tests written in TypeScript.
Prerequisites
Your Jest is configured with ts-jest:
// jest.config.ts
import type { Config } from 'jest';
const config: Config = {
preset: 'ts-jest',
};
export default config;
Scripts
Update your package.json script “test”:
{
"scripts": {
- "test": "jest"
+ "test": "node --experimental-vm-modules $(npx which jest)"
}
}
npx which jestevaluates tonode_modules/.bin/jest.
Or alternatively:
{
"scripts": {
- "test": "jest"
+ "test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest
}
}
Configs
Update your Jest config to transform using ESM:
// jest.config.ts
import type { Config } from 'jest';
const config: Config = {
- preset: 'ts-jest',
+ extensionsToTreatAsEsm: ['.mts', '.ts'],
+ moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1' },
+ transform: { '^.+\\.m?[tj]sx?$': ['ts-jest', { useESM: true }] },
};
export default config;
Set module to esnext (or es2022) in your tsconfig.json:
{
"compilerOptions": {
"target": "es2022",
+ "module": "esnext",
"moduleResolution": "node"
}
}
Tests
Import jest to access the object:
import { jest } from '@jest/globals';
jest.fn();
Use await import to import relative files:
const { myUtil } = await import('./my-util.js');
ESM relative import must include the file extension.
Mock a module with jest.unstable_mockModule:
jest.unstable_mockModule('node:os', () => ({
platform: jest.fn(),
}));
Both the 1st and 2nd arguments are required.
Unmock with jest.unstable_unmockModule:
jest.unstable_unmockModule('node:os');