fix(Resolver): yield strings from stack iterator and accept string in has()#569
Conversation
🦋 Changeset detectedLatest commit: 02d0dd5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
|
Codecov Report✅ All modified and coverable lines are covered by tests. 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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Merging this PR will degrade performance by 98.37%
|
| 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)
bb53926 to
7d8bec5
Compare
`[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.
7d8bec5 to
02d0dd5
Compare
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>
Restore the pre-5.21
Set<string>shape that plugins observe throughresolveContext.stack: iteration now yields the formatted"hookName: (path) request"strings (not the internalStackEntryobjects), and
StackEntry#hasaccepts a string query alongside thestructural
StackEntryoverload. Fixes #567.Also extracts the two
_withResolversimplementations into namedhelpers 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.