Skip to content

fix(pnp): align exports resolution with enhanced-resolve#196

Open
ha1fstack wants to merge 2 commits intorstackjs:mainfrom
ha1fstack:dev/pnp-name-mismatch-exports-fix
Open

fix(pnp): align exports resolution with enhanced-resolve#196
ha1fstack wants to merge 2 commits intorstackjs:mainfrom
ha1fstack:dev/pnp-name-mismatch-exports-fix

Conversation

@ha1fstack
Copy link
Copy Markdown

Background

rspack-resolver’s PnP path previously called load_package_self(&cached_path, specifier, ...) before resolving exports.
That flow depends on package_json.name matching the request package prefix, which is valid for Node self-reference, but can be wrong for PnP edge cases (aliases, virtualized layouts, or name-mismatch paths).

enhanced-resolve does not rely on that check in its PnP path. It derives the subpath from the request and resolves exports from that subpath directly.

Original fallback behavior (and why it was problematic)

In the old load_pnp flow:

  1. Try load_package_self(&cached_path, specifier, ...).
  2. If it returns None, fall back to inner_request and call the inner resolver from the PnP-resolved package path.
  3. For bare requests, fallback often became resolve(path, "."), which can proceed via directory/main/index resolution.

Problem in mismatch cases:

  • When PnP resolves to a package root whose package.json.name differs from the requested specifier, load_package_self fails early due to name check.
  • This skips the intended exports resolution path even though the PnP resolution already identified the correct package location/subpath context.
  • The fallback ("." / filesystem-style main/index pathing) is not equivalent to exports-field resolution and can produce incorrect results or NotFound for requests that should be resolved by exports.

What changed

  • In the PnP branch, derive and use the PnP subpath directly for:
    • exports subpath resolution
    • inner request fallback construction
  • Avoid relying on load_package_self package-name matching in the PnP-specific flow.
  • Keep non-PnP behavior unchanged, including normal self-reference checks outside PnP.

Why

This aligns rspack-resolver with enhanced-resolve behavior in PnP mode and ensures deterministic exports resolution based on the PnP-resolved package/subpath, not on package.json.name string matching.

Tests

Added/updated tests (modeled after enhanced-resolve scenarios) covering:

  • bare package request in PnP
  • subpath request in PnP
  • name-mismatch case where exports must still resolve

Result

  • Before fix: PnP name-mismatch cases could bypass exports and fail via fallback behavior.
  • After fix: exports resolution succeeds from PnP-derived subpath; non-PnP semantics remain intact.

Copilot AI review requested due to automatic review settings April 12, 2026 10:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adjusts Yarn PnP resolution so exports are resolved from the PnP-derived subpath (matching enhanced-resolve) rather than relying on package.json.name matching for the PnP branch, which could incorrectly bypass exports in alias/name-mismatch scenarios.

Changes:

  • Update PnP resolution flow to resolve exports using the request-derived (PnP-provided) subpath via load_package_exports.
  • Normalize PnP subpaths before constructing exports and inner fallback requests.
  • Add fixtures + tests covering PnP exports resolution for bare, subpath, and name-mismatch cases.

Reviewed changes

Copilot reviewed 4 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/lib.rs Changes PnP branch to resolve exports from the PnP subpath directly, avoiding package-name matching in load_package_self.
src/tests/pnp.rs Adds regression tests for PnP exports handling (bare + subpath) with a name-mismatch fixture.
fixtures/pnp/package.json Adds a linked dependency @user/m1 pointing to the name-mismatch fixture.
fixtures/pnp/yarn.lock Updates lockfile entries for the new linked dependency.
fixtures/pnp/shared-name-mismatch/package.json Adds a fixture package whose name intentionally differs from the requested specifier while providing exports.
fixtures/pnp/shared-name-mismatch/dist/a.js Adds the exported target file used by the new tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

2 participants