fix: keep the original request resolvable when extensionAlias lists its own extension - #641
Conversation
…ts own extension ExtensionAliasPlugin marked every candidate fullySpecified and refused to fall back, so a request ending in an aliased extension could no longer resolve as a directory or with appended extensions.
🦋 Changeset detectedLatest commit: 1e33470 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 #641 +/- ##
=======================================
Coverage 98.12% 98.12%
=======================================
Files 49 49
Lines 9902 9910 +8
=======================================
+ Hits 9716 9724 +8
Misses 186 186
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Merging this PR will degrade performance by 73.23%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Memory | extensions-many: 6-extension list (warm) |
1.9 KB | 96.6 KB | -98.05% |
| ❌ | Memory | self-reference: import own package name (warm) |
2.1 KB | 2.5 KB | -15.24% |
| ⚡ | Memory | node-compare: node require.resolve x 1000 |
24.7 KB | 21.2 KB | +16.26% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing fix/extension-alias-original-request-fallback (1e33470) with main (2bcac6e)
|
Closing — this was the wrong layer.
The actual cause of webpack/webpack#21541 is on the webpack side: Generated by Claude Code |
|
Reopened with a corrected rationale (title and description updated); my earlier comment was right that this is not the cause of webpack/webpack#21541, but wrong to conclude nothing needed fixing here. The webpack-side fix (webpack/webpack#21542) stops Generated by Claude Code |
The `.js` -> `.ts` extensionAlias that `experiments.typescript` installs made `ExtensionAliasPlugin` resolve such a request as an exact file only, so a package directory named `pkg.js` became unreachable. Fixed in enhanced-resolve (webpack/enhanced-resolve#641); take the release and add a regression test.
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.24.4 ### Patch Changes - Keep the original request resolvable when `extensionAlias` lists its own extension. (by [@alexander-akait](https://github.com/alexander-akait) in [#641](#641)) - Fix string `restrictions` boundary checks: a restriction ending with a separator no longer rejects everything inside it, restrictions are normalized before they are compared, and a Windows path now matches the way `path.win32` does, treating `/` and `\` as interchangeable and comparing case-insensitively, while `\` stays a filename character in a posix path. The same comparison backs `tsconfig` path matching. (by [@alexander-akait](https://github.com/alexander-akait) in [#643](#643)) - Treat a UNC path (`\\server\share\…`) as a Windows path, so it normalizes, joins and walks up with `path.win32` semantics instead of being taken for a bare module request. (by [@alexander-akait](https://github.com/alexander-akait) in [#644](#644)) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
The `.js` -> `.ts` extensionAlias that `experiments.typescript` installs made `ExtensionAliasPlugin` resolve such a request as an exact file only, so a package directory named `pkg.js` became unreachable. Fixed in enhanced-resolve (webpack/enhanced-resolve#641); take the release and add a regression test.
…21542) * fix: resolve aliases pointing at a package directory ending in .js The `.js` -> `.ts` extensionAlias that `experiments.typescript` installs made `ExtensionAliasPlugin` resolve such a request as an exact file only, so a package directory named `pkg.js` became unreachable. Fixed in enhanced-resolve (webpack/enhanced-resolve#641); take the release and add a regression test. * test: pin the extensionAlias in the regression case Relying on the `experiments.typescript` "auto" default made the case a no-op below Node.js 22.6, where the alias is never installed. * build: lock enhanced-resolve 5.24.4
Summary
ExtensionAliasPluginmarks every candidatefullySpecified: trueand then refuses to fall back, so a request ending in an aliased extension can only ever resolve as an exact file — never as a directory or viapackage.json#main. With the source extension listed among its own aliases ({ ".js": [".js", ".ts"] }— the documented TypeScript recipe, and whatexperiments.typescriptsets in webpack) that entry is meant to keep the original request valid, but it is tried fully specified too, so any package or directory whose name ends in.jsbecomes unreachable. This makes the identity entry mean what it says: after the fully specified candidates fail, fall through to normal resolution. A mapping that drops the source extension ({ ".js": [".ts"] },{ ".mjs": ".mts" }) stays strict.Refs webpack/webpack#21541. That regression is fixed on the webpack side in webpack/webpack#21542 and does not need this; this closes the same failure for projects that genuinely enable TypeScript today, and ahead of TypeScript becoming a default.
What kind of change does this PR introduce?
fix
Did you add tests for your changes?
Yes — three cases in
test/extension-alias.test.js(directory nameddir3.js, an aliased absolute path to apkg.jspackage, and a strict mapping that must keep failing) plus the matching fixtures.Does this PR introduce a breaking change?
No — it only turns previously failing resolutions into successes; exact-file candidates are still tried first, so nothing that resolves today resolves differently.
If relevant, what needs to be documented once your changes are merged or what have you already documented?
extensionAliasdocs should say that listing an extension among its own aliases keeps the original request resolvable in its normal form, while omitting it makes the mapping strict.Use of AI
AI (Claude Code) was used to trace the failure, draft the fix and tests, and verify them; the diagnosis and the final diff were reviewed by a human before submitting.