Angular >=13
Angular 13 introduces ESM package format for Angular packages. jest-preset-angular
currently supports testing with Jest in CommonJS
mode with Angular 13 using default preset.
With Jest 28 and jest-preset-angular
v12.0.0, ng-jest-resolver
is no longer required to have in Jest config. This
resolver is also excluded from our default and default ESM presets.
Starting from v11.0.0, jest-preset-angular
introduces a few extra changes to be able to run Jest with Angular 13:
-
moduleFileExtensions
is updated to includemjs
files as accepted module format. -
transformIgnorePatterns
is added to inform Jest to transform.mjs
files. -
transform
is updated to include.mjs
extension to transform toCommonJS
codes.
Migration steps from Angular < 13
-
Upgrade the project to Angular 13 following guide
-
If one is using the default preset as following:
- JavaScript
- TypeScript
// jest.config.js
module.exports = {
preset: 'jest-preset-angular',
};
// jest.config.ts
import type { Config } from 'jest';
const jestConfig: Config = {
preset: 'jest-preset-angular',
};
export default jestConfig;
there are no migration steps required
Using ES Modules
ES Modules support is new and may encounter issues. See example-app-v13 for an example with tests that run using ESM, and using ESM + isolated.
Your jest.config.js
should be changed to something like:
- JavaScript
- TypeScript
// jest.config.js
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { paths } = require('./tsconfig.json').compilerOptions;
/** @type {import('ts-jest/dist/types').JestConfigWithTsJest} */
module.exports = {
preset: 'jest-preset-angular/presets/defaults-esm',
transform: {
'^.+\\.(ts|js|html|svg)$': [
'jest-preset-angular',
{
tsconfig: '<rootDir>/tsconfig-esm.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
isolatedModules: true,
useESM: true,
},
],
},
moduleNameMapper: {
...pathsToModuleNameMapper(paths, { prefix: '<rootDir>' }),
tslib: 'tslib/tslib.es6.js',
},
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
};
// jest.config.ts
import type { Config } from 'jest';
import { pathsToModuleNameMapper } from 'ts-jest';
import { compilerOptions } from './tsconfig.json';
const jestConfig: Config = {
preset: 'jest-preset-angular/presets/defaults-esm',
transform: {
'^.+\\.(ts|js|html|svg)$': [
'jest-preset-angular',
{
tsconfig: '<rootDir>/tsconfig-esm.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
isolatedModules: true,
useESM: true,
},
],
},
moduleNameMapper: {
...pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>' }),
tslib: 'tslib/tslib.es6.js',
},
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
};
export default jestConfig;
Before upgrading to ng13 and switching to ES Modules, your setup-jest.ts
file most likely uses the preset setup-jest
, like the following:
- TypeScript CJS
- TypeScript ESM
// setup-jest.ts
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone';
setupZoneTestEnv();
// setup-jest.ts
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone/index.mjs';
setupZoneTestEnv();
Potential issues with Angular 13 ESM package format and workaround
Cannot find modules
error when importing any deep paths from Angular ESM format packages
Cannot find module '@angular/common/locales/xx' from 'src/app/app.component.spec.ts'
To fix this issue, one needs to add mjs
to moduleFileExtensions
as following
- JavaScript
- TypeScript
// jest.config.js
module.exports = {
// ...other options
moduleFileExtensions: ['ts', 'html', 'js', 'json', 'mjs'],
};
// jest.config.ts
import type { Config } from 'jest';
const jestConfig: Config = {
// ...other options
moduleFileExtensions: ['ts', 'html', 'js', 'json', 'mjs'],
};
export default jestConfig;
Usage with Angular libraries which are built with Angular CLI 13
Besides, the changes in Angular packages themselves, Angular libraries which are built with Angular CLI 13 also introduce
ESM package format. Similar to Angular packages, Jest doesn't understand .mjs
files which are in these new format
libraries in Jest CommonJS mode.
To fix this issue, one should modify transformIgnorePatterns
to be as following:
- JavaScript
- TypeScript
// jest.config.js
module.exports = {
// ...other options
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
};
// jest.config.ts
import type { Config } from 'jest';
const jestConfig: Config = {
// ...other options
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
};
export default jestConfig;
Usage with Ionic 6 or 7
To support Ionic 6 or 7 you will need to modify transformIgnorePatterns
to be as following:
- JavaScript
- TypeScript
// jest.config.js
module.exports = {
// ...other options
transformIgnorePatterns: ['<rootDir>/node_modules/(?!(@ionic/core|@ionic/angular|@stencil/core|.*\\.mjs$))'],
};
// jest.config.ts
import type { Config } from 'jest';
const jestConfig: Config = {
// ...other options
transformIgnorePatterns: ['<rootDir>/node_modules/(?!(@ionic/core|@ionic/angular|@stencil/core|.*\\.mjs$))'],
};
export default jestConfig;