Skip to content

Fix/pnp require cache extensions 7234 - #7256

Open
Ayush442842q wants to merge 4 commits into
yarnpkg:masterfrom
Ayush442842q:fix/pnp-require-cache-extensions-7234
Open

Fix/pnp require cache extensions 7234#7256
Ayush442842q wants to merge 4 commits into
yarnpkg:masterfrom
Ayush442842q:fix/pnp-require-cache-extensions-7234

Conversation

@Ayush442842q

Copy link
Copy Markdown

What's the problem this PR addresses?

Under Yarn PnP on Node.js versions affected by HAS_BROKEN_FSTAT_FOR_ZIP_FDS (such as Node.js v22.22.3+, v24.15.0, v25.7.0+), require.cache and require.extensions are undefined in CommonJS dependencies (such as rechoir, webpack-cli, tailwindcss, eslint).

Root Cause

  1. In affected Node.js versions, a regression in Node's ESM loader caused fstatSync on virtual file descriptors for files inside .zip archives to throw EBADF: bad file descriptor, fstat.
  2. To work around this in Yarn PnP, HAS_BROKEN_FSTAT_FOR_ZIP_FDS was added to return { format: 'commonjs', source: <file_content> } from the ESM load hook for CJS files in zip archives.
  3. Returning source for format: 'commonjs' forces Node's ESM loader to construct a synthetic CommonJS module wrapper instead of using standard CJS module loading (Module._load).
  4. Node's synthetic require function passed to CJS modules loaded via the ESM loader does not attach require.cache or require.extensions (undefined). Any dependency inside a zip archive accessing require.cache or require.extensions fails with a TypeError.

Closes #7234.

How did you fix it?

  1. Patched Module.prototype._compile: In packages/yarnpkg-pnp/sources/loader/applyPatch.ts, monkey-patched Module.prototype._compile to inject a single-line safeguard statement at the top of CommonJS module contents:

    if (typeof require !== 'undefined') { if (!require.cache) require.cache = Module._cache; if (!require.extensions) require.extensions = Module._extensions; };
  2. Shebang Compatibility: If the source file starts with a shebang (#!), the safeguard statement is inserted immediately after the shebang line to preserve shebang parsing.

  3. Line Numbering Preservation: Because the safeguard is a single statement on a single line, line numbers in stack traces and sourcemaps remain unaffected.
    Rebuilt Hook Artifacts: Recompiled PnP hook bundles (sources/hook.js, sources/hook.raw.js, sources/esm-loader/built-loader.js).

  4. Added Acceptance Test: Added an acceptance test in packages/acceptance-tests/pkg-tests-specs/sources/require.test.js verifying that require.cache and require.extensions are available inside required dependencies under PnP.

Checklist

  • I have read the Contributing Guide.
  • I have set the packages that need to be released for my changes to be effective.
  • I will check that all automated PR checks pass before the PR gets reviewed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Yarn PnP: require.cache and require.extensions are undefined in dependencies (regression in nodejs v22.22.3)

1 participant