Package subpath './src/ngtsc/reflection' is not defined by "exports" in /node_modules/@angular/compiler-cli/package.json

I am trying to run the ng test with jest and getting this following error

Package subpath './src/ngtsc/reflection' is not defined by "exports" in /Users/oyf992/source/app-mngt/node_modules/@angular/compiler-cli/package.json

I am using

"@angular/core": "^13.0.1", "jest": "27.2.3", "jest-preset-angular": "10.0.1",

let me know what could be the reason and possible solution.


TL;DR

  1. upgrade the following Jest dependencies at minimum*, and
  2. update Jest and Typescript configuration

*Your project may require additional upgrades--mine did. I've found search results related to (1) Angular 13 upgrade + Jest and (2) Jest ESModule support to be most helpful.

"@angular-builders/jest": "^13.0.2",
"jest": "^27.4.7",
"jest-preset-angular": "^11.0.1",
"ts-jest": "^27.1.2",

Angular 13 and Jest: what changed?

The most disruptive breaking change to Jest in Angular 13 was ESModule artifacts (.mjs). Jest runs in the Node which supports CommonJS modules. It has experimental support for ESModules and requires additional configuration to enable it.

Upgrading jest-preset-angular resolved the first error (reflection subpath) and uncovered a second error:

$HOME/$PROJECT/node_modules/@angular/core/fesm2015/testing.mjs:7
    import { getDebugNode, RendererFactory2, ɵstringify, ɵReflectionCapabilities, Directive, Component, Pipe, NgModule, ɵgetInjectableDef, resolveForwardRef, ɵNG_COMP_DEF, ɵRender3NgModuleRef, ApplicationInitStatus, LOCALE_ID, ɵDEFAULT_LOCALE_ID, ɵsetLocaleId, ɵRender3ComponentFactory, ɵcompileComponent, ɵNG_DIR_DEF, ɵcompileDirective, ɵNG_PIPE_DEF, ɵcompilePipe, ɵNG_MOD_DEF, ɵtransitiveScopesFor, ɵpatchComponentDefWithScope, ɵNG_INJ_DEF, ɵcompileNgModuleDefs, NgZone, Compiler, COMPILER_OPTIONS, ɵNgModuleFactory, ModuleWithComponentFactories, InjectionToken, Injector, InjectFlags, ɵresetCompiledComponents, ɵflushModuleScopingQueueAsMuchAsPossible } from '@angular/core';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

Next I upgraded @angular-builders/jest, jest, and ts-jest. Changes to your Jest and Typescript configuration may also be needed. In your tsconfig.json or tsconfig.spec.json, check that it "has module [in compilerOptions] with value for ESM, e.g. ES2015 or ES2020 etc..." as noted in the ts-lint migration doc.

Below are the changes I made to my project's Jest configuration, but each project is a little different.

// jest.config.js
const esModules = ['@angular', '@ngrx', 'd3', [...]];
module.exports = {
  // [...]
  extensionsToTreatAsEsm: ['.ts'], // ts-jest
  globals: {
    'ts-jest': {
      useESM: true, // ts-jest
    },
  },
  moduleFileExtensions: ['ts', 'html', 'js', 'json', 'mjs'], // jest-preset-angular
  moduleNameMapper: {
    '^(\\.{1,2}/.*)\\.js$': '$1', // ts-jest
  },
  preset: 'jest-preset-angular',
  transform: {
    '^.+\\.(ts|js|mjs|html|svg)$': 'jest-preset-angular',
  },
  transformIgnorePatterns: [
    `<rootDir>/node_modules/(?!.*\\.mjs$|${esModules.join('|')})`, // jest-preset-angular
  ],
}

If you're still having issues I've included links to each migration doc below. I'm still working through issues with other packages but hope this sets you on a good path!

Migration and ESM support docs

  • Angular latest upgrade: https://angular.io/guide/update-to-latest-version
  • @angular-builders/jest: https://github.com/just-jeb/angular-builders/blob/master/MIGRATION.MD
  • jest-preset-angular: https://thymikee.github.io/jest-preset-angular/docs/next/guides/angular-13+/
  • ts-jest ESM support: https://kulshekhar.github.io/ts-jest/docs/guides/esm-support/
  • Jest ESM support: https://jestjs.io/docs/ecmascript-modules
  • If you're still getting Cannot use import errors, a helpful comment on a closed GitHub issue: https://github.com/thymikee/jest-preset-angular/issues/1149#issuecomment-963506942