Skip to content

fix(Resolver): yield strings from stack iterator and accept string in has()#569

Merged
alexander-akait merged 1 commit into
mainfrom
claude/fix-issue-567-M2hY5
May 7, 2026
Merged

fix(Resolver): yield strings from stack iterator and accept string in has()#569
alexander-akait merged 1 commit into
mainfrom
claude/fix-issue-567-M2hY5

Conversation

@alexander-akait

Copy link
Copy Markdown
Member

Restore the pre-5.21 Set<string> shape that plugins observe through
resolveContext.stack: iteration now yields the formatted
"hookName: (path) request" strings (not the internal StackEntry
objects), and StackEntry#has accepts a string query alongside the
structural StackEntry overload. Fixes #567.

Also extracts the two _withResolvers implementations into named
helpers so the JSDoc blocks no longer hang off ternary arms — that
shape was triggering jsdoc/check-alignment + prettier circular fixes
in the lint-staged pre-commit hook.

@changeset-bot

changeset-bot Bot commented May 6, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 02d0dd5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
enhanced-resolve Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@linux-foundation-easycla

linux-foundation-easycla Bot commented May 6, 2026

Copy link
Copy Markdown

CLA Not Signed

@codecov

codecov Bot commented May 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.51%. Comparing base (37eafd5) to head (02d0dd5).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #569      +/-   ##
==========================================
- Coverage   96.51%   96.51%   -0.01%     
==========================================
  Files          50       50              
  Lines        2896     2895       -1     
  Branches      911      911              
==========================================
- Hits         2795     2794       -1     
  Misses         85       85              
  Partials       16       16              
Flag Coverage Δ
integration 96.51% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed-hq

codspeed-hq Bot commented May 6, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 98.37%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
❌ 2 regressed benchmarks
✅ 135 untouched benchmarks

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Memory resolve-to-context: directory resolve (warm) 1.7 KB 101.8 KB -98.37%
Memory tsconfig-paths: 5 path prefixes (warm) 1.8 KB 96.6 KB -98.17%
Memory array-alias: @ -> [preferred, fallback] (warm) 1.8 KB 1.5 KB +16.92%

Comparing claude/fix-issue-567-M2hY5 (02d0dd5) with main (37eafd5)

Open in CodSpeed

@alexander-akait alexander-akait force-pushed the claude/fix-issue-567-M2hY5 branch 14 times, most recently from bb53926 to 7d8bec5 Compare May 7, 2026 17:27
`[Symbol.iterator]` yields each entry as its formatted `toString()`
form so plugins written against the pre-5.21 `Set<string>` shape —
e.g. `[...resolveContext.stack].find(a => a.includes("module:"))` —
keep working without TypeError.

`StackEntry`'s shape stays exactly as base. `doResolve`'s recursion
check is unchanged. Resolves that never iterate the stack allocate
nothing extra; iteration costs one `toString()` per stack frame.

Code that read structural fields off iterated entries in 5.21
(`.name`, `.path`, `.module`, …) needs to switch to parsing the
string form. The boxed-`String`-with-fields shim that briefly
provided both shapes was reverted because it consistently regressed
CodSpeed memory benchmarks even on warm-cache cases that never
iterate the stack — V8 attributes the bytecode/IC state for a new
`String`-object factory to whichever benchmark first triggers it,
which Massif counts as a ~96 KB regression.
@alexander-akait alexander-akait force-pushed the claude/fix-issue-567-M2hY5 branch from 7d8bec5 to 02d0dd5 Compare May 7, 2026 17:38
@alexander-akait alexander-akait merged commit e1f07eb into main May 7, 2026
33 of 34 checks passed
@alexander-akait alexander-akait deleted the claude/fix-issue-567-M2hY5 branch May 7, 2026 17:40
alexander-akait pushed a commit that referenced this pull request May 7, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## enhanced-resolve@5.21.1

### Patch Changes

- Allocation-free reductions on hot-path code: hoist `/#/g`, `/\$/g` and
`/\\/g` to module-level constants and gate the corresponding `.replace`
calls behind `includes(…)` so paths/queries/requests without the match
char skip the regex state machine entirely (the common case); share a
single `EMPTY_NO_MATCH` tuple instead of allocating `[[], null]` per "no
match" / "no condition matched" return; switch `directMapping`'s
`for...of` over `mappingTarget` and inner results to indexed loops to
avoid iterator-object allocation per call; inline `isConditionalMapping`
at its two hot-path call sites and merge the duplicate `default` /
`conditionNames.has(condition)` branches in `computeConditionalMapping`;
replace `invalidSegmentRegEx.exec(…) !== null` with `.test(…)` (no
match-array allocation); drop the dead
`deprecatedInvalidSegmentRegEx.test(…) !== null` clause in
`ImportsFieldPlugin` (`.test` returns boolean; `true !== null` and
`false !== null` are both true, so it was `&& true`); drop the redundant
`relativePath.length === 0` guard before `!startsWith("./")` in
`ExportsFieldPlugin` (the empty-string case is already covered). (by
[@alexander-akait](https://github.com/alexander-akait) in
[#558](#558))

- restore plugin compatibility for `[...resolveContext.stack]` iteration
(by [@alexander-akait](https://github.com/alexander-akait) in
[#569](#569))

- fix `TsconfigPathsPlugin` to support `resolveSync` with
`useSyncFileSystemCalls` (by
[@alexander-akait](https://github.com/alexander-akait) in
[#572](#572))

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

Breaking behavior due to enhanced-resolve 5.21.0

2 participants