Skip to content

Fix @react-native/jest-preset failing under pnpm and Yarn pnpm-mode - #58489

Closed
amroaltah wants to merge 1 commit into
react:mainfrom
amroaltah:fix-jest-preset-pnpm-isolation-56641
Closed

Fix @react-native/jest-preset failing under pnpm and Yarn pnpm-mode#58489
amroaltah wants to merge 1 commit into
react:mainfrom
amroaltah:fix-jest-preset-pnpm-isolation-56641

Conversation

@amroaltah

Copy link
Copy Markdown

The preset fails in two ways under strict-isolation installs (pnpm and Yarn pnpm-mode): react-native is not a declared dependency so jest-preset.js cannot resolve it, and the transformIgnorePatterns rule only matches classic node_modules layouts so preset sources ship untransformed.

  • Declare react-native as a peer dependency so the installer links it into the preset's scope.
  • Move @babel/core from dependencies to peerDependencies: babel-jest peer-depends on it, so it must be provided, but as a direct dependency a strict installer gives the preset its own copy and the consumer's babel.config.js presets would then load under a different @babel/core instance than the consumer's own. A peer keeps one copy, matching how react and react-native are already declared. @babel/runtime stays a direct dependency: the preset's sources are compiled with @babel/plugin-transform-runtime helpers enabled, so the transformed jest/setup.js requires @babel/runtime/helpers/* from the preset's own scope at Jest runtime.
  • Resolve the babel-jest transformer from the preset's own scope via require.resolve('babel-jest') instead of the bare specifier.
  • Match react-native packages at any nesting depth in transformIgnorePatterns so pnpm (.pnpm/...) and Yarn pnpm-mode (.store/...) layouts still transform preset and react-native sources, while real -suffix packages stay ignored as before.
  • Add two regression tests: an isolated-install test proving the preset loads with only declared dependencies linked, and a transform test proving the transformer resolves from the preset scope and the ignore pattern covers pnpm/Yarn layouts without widening.

Known limitation: under Yarn pnpm-mode's .store layout, the virtual-suffix allowance also matches packages like react-native-virtualized-view whose names begin with react-native-, so those get transformed too. The impact is performance-only (extra transform work, no behavior change) and confined to Yarn pnpm-mode.

Fixes #56641.

Changelog:
[General][Fixed] - Fix @react-native/jest-preset failing to resolve react-native and to transform preset sources under pnpm and Yarn pnpm-mode installs

Test Plan:

  • Repo Jest suite over packages/jest-preset: 3 suites, 4 tests pass, including the two new regression tests.
  • A real-pnpm strict-isolation repro (minimal monorepo installing the preset via file:, hoist=false): before the transformIgnorePatterns fix Jest fails with Cannot use import statement outside a module; with the fix the preset loads and Jest passes.

The preset failed in two ways under strict-isolation installs (pnpm and
Yarn pnpm-mode): `react-native` was not a declared dependency so
`jest-preset.js` could not resolve it, and the `transformIgnorePatterns`
rule only matched classic `node_modules` layouts so preset sources
shipped untransformed.

- Declare `react-native` as a peer dependency so the installer links it
  into the preset's scope.
- Move `@babel/core` from dependencies to peerDependencies: `babel-jest`
  peer-depends on it, so it must be provided, but as a direct dependency
  a strict installer gives the preset its own copy and the consumer's
  `babel.config.js` presets would then load under a different
  `@babel/core` instance than the consumer's own. A peer keeps one copy,
  matching how `react` and `react-native` are already declared.
  `@babel/runtime` stays a direct dependency: the preset's sources are
  compiled with `@babel/plugin-transform-runtime` helpers enabled, so the
  transformed `jest/setup.js` requires `@babel/runtime/helpers/*` from
  the preset's own scope at Jest runtime.
- Resolve the `babel-jest` transformer from the preset's own scope via
  `require.resolve('babel-jest')` instead of the bare specifier.
- Match `react-native` packages at any nesting depth in
  `transformIgnorePatterns` so pnpm (`.pnpm/...`) and Yarn pnpm-mode
  (`.store/...`) layouts still transform preset and `react-native`
  sources, while real `-suffix` packages stay ignored as before.
- Add two regression tests: an isolated-install test proving the preset
  loads with only declared dependencies linked, and a transform test
  proving the transformer resolves from the preset scope and the ignore
  pattern covers pnpm/Yarn layouts without widening.

Known limitation: under Yarn pnpm-mode's `.store` layout, the
virtual-suffix allowance also matches packages like
`react-native-virtualized-view` whose names begin with `react-native-`,
so those get transformed too. The impact is performance-only (extra
transform work, no behavior change) and confined to Yarn pnpm-mode.

Fixes react#56641.

Changelog:
[General][Fixed] - Fix `@react-native/jest-preset` failing to resolve `react-native` and to transform preset sources under pnpm and Yarn pnpm-mode installs

Test Plan:
- Repo Jest suite over `packages/jest-preset`: 3 suites, 4 tests pass, including the two new regression tests.
- A real-pnpm strict-isolation repro (minimal monorepo installing the preset via `file:`, `hoist=false`): before the `transformIgnorePatterns` fix Jest fails with `Cannot use import statement outside a module`; with the fix the preset loads and Jest passes.
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Sep 11, 2026
@amroaltah

Copy link
Copy Markdown
Author

Closing this PR — taking the change through internal review instead. Will link the internal diff here if it gets exported.

@amroaltah amroaltah closed this Sep 11, 2026
@amroaltah
amroaltah deleted the fix-jest-preset-pnpm-isolation-56641 branch September 11, 2026 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@react-native/jest fails to resolve react-native in monorepos

1 participant