ESM Support
Jest will take into account of the following things when working with ESM:
- ESM runtime
- The value of
moduleoption in tsconfig file is either:Node16/Node18/NodeNext: this MUST go together withtype: "module"inpackage.json.- Otherwise, the value MUST BE one of the ES values, e.g.
ES2015,ES2020etc...
One can configure jest-preset-angular to work with Jest in ESM mode by following the steps below.
We have EXAMPLE APPS which contains base ESM setup to work with Jest and Angular.
Configure Jest runtime
Jest runtime currently has a few issues related to support ESM:
- Not taking into account of
type: "module"field inpackage.jsonyet to run as ESM mode. - Mocking ES modules are not supported yet, track progress here https://github.com/jestjs/jest/pull/10976
Overall progress and discussion can be found at https://github.com/jestjs/jest/issues/9430
If one is using Jest config in TypeScript, one should install ts-node as a dev dependency.
- npm
- Yarn
- pnpm
- Bun
npm install -D ts-node
yarn add --dev ts-node
pnpm add -D ts-node
bun add --dev ts-node
Execute Jest with with --experimental-vm-modules flag for NodeJs
node --experimental-vm-modules node_modules/jest/bin/jest.js
Alternative way for Yarn users:
yarn node --experimental-vm-modules $(yarn bin jest)
This command will also work if you use Yarn Plug'n'Play.
Configure tsconfig
One can choose EITHER ONE of the following options for tsconfig:
Using ES module values
{
"compilerOptions": {
"module": "ESNext", // or any values starting with "es" or "ES"
"target": "ESNext",
"esModuleInterop": true
}
}
Using hybrid module values
Hybrid module values requires type field in package.json to be set explicitly to:
commonjsforCommonJScodemoduleforESMcode
See official TypeScript documentation at https://www.typescriptlang.org/docs/handbook/modules/reference.html#node16-node18-nodenext
Currently, the code transpiler which is used by jest-preset-angular ONLY supports hybrid values with isolatedModules: true
{
"compilerOptions": {
"module": "Node16", // or Node18/NodeNext
"target": "ESNext",
"esModuleInterop": true,
"isolatedModules": true
}
}
Configure Jest config
Jest will attempt to load ESM files from node_modules with default jest-resolve which usually works for most of the cases.
However, there are cases like Angular libraries ESM built files or ESM files which are outside node_modules might not be loaded
correctly.
To fix that, one can use moduleNameMapper in jest config to instruct Jest to load the correct ESM files or create a
custom Jest resolver.
- Node <22.18
- Node 22.18+
import type { Config } from 'jest';
import { createEsmPreset } from 'jest-preset-angular/presets';
export default {
//...
...createEsmPreset(),
moduleNameMapper: {
tslib: 'tslib/tslib.es6.js',
'^rxjs': '<rootDir>/node_modules/rxjs/dist/bundles/rxjs.umd.js',
},
} satisfies Config;
import type { Config } from 'jest';
import { createEsmPreset } from 'jest-preset-angular/presets/index.js';
export default {
//...
...createEsmPreset(),
moduleNameMapper: {
tslib: 'tslib/tslib.es6.js',
'^rxjs': '<rootDir>/node_modules/rxjs/dist/bundles/rxjs.umd.js',
},
} satisfies Config;
Resolve .mjs/.mts extensions
This step is optional and only needed if you are using .mjs or .mts extensions in your code.
See an example one from ts-jest