diff --git a/packages/jest-util/src/__tests__/installCommonGlobals.test.ts b/packages/jest-util/src/__tests__/installCommonGlobals.test.ts index 251dce275d35..1ef24160ebf1 100644 --- a/packages/jest-util/src/__tests__/installCommonGlobals.test.ts +++ b/packages/jest-util/src/__tests__/installCommonGlobals.test.ts @@ -48,3 +48,16 @@ it('turns a V8 global object into a Node global object', () => { expect(fake).toHaveBeenCalledTimes(1); }); + +it('overrides process.features.require_module to false when present', () => { + const myGlobal = installCommonGlobals(getGlobal(), {}); + + // Some Node versions may not expose the flag; only assert if present + const features = (myGlobal.process as any).features; + if ( + features && + Object.prototype.hasOwnProperty.call(features, 'require_module') + ) { + expect(features.require_module).toBe(false); + } +}); diff --git a/packages/jest-util/src/createProcessObject.ts b/packages/jest-util/src/createProcessObject.ts index 59d67c0000c0..598fa672976c 100644 --- a/packages/jest-util/src/createProcessObject.ts +++ b/packages/jest-util/src/createProcessObject.ts @@ -117,5 +117,32 @@ export default function createProcessObject(): typeof Process { }, }); + // Ensure feature flags reflect Jest's capabilities inside the VM. + // Node may expose `process.features.require_module` which signals that + // requiring ESM via `require()` is supported. Jest's runtime does not + // support requiring ESM modules through CJS `require`, so we override + // the flag to false to allow defensive code paths to behave correctly. + // + const features: unknown = (newProcess as any).features; + if (features && typeof features === 'object') { + // Only override if the host process exposes the flag + if ('require_module' in (features as Record)) { + try { + Object.defineProperty(features as object, 'require_module', { + configurable: true, + enumerable: true, + get: () => false, + }); + } catch { + // If redefining fails for any reason, fall back to direct assignment + try { + (features as any).require_module = false; + } catch { + // ignore if we cannot override + } + } + } + } + return newProcess; }