fix: resolve aliases pointing at a package directory ending in .js - #21542
Conversation
🦋 Changeset detectedLatest commit: 68a0820 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 |
|
This PR is packaged and the instant preview is available (d1b5b6d). Install it locally:
npm i -D webpack@https://pkg.pr.new/webpack@d1b5b6d
yarn add -D webpack@https://pkg.pr.new/webpack@d1b5b6d
pnpm add -D webpack@https://pkg.pr.new/webpack@d1b5b6d |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #21542 +/- ##
=======================================
Coverage 93.82% 93.82%
=======================================
Files 620 620
Lines 73591 73591
Branches 21273 21273
=======================================
Hits 69046 69046
Misses 4545 4545
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 regress 1 benchmark
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Memory | benchmark "many-chunks-esm", scenario '{"name":"mode-production","mode":"production"}' |
7.3 MB | 9.3 MB | -21.5% |
| ⚡ | Memory | benchmark "devtool-eval", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
3.1 MB | 1.3 MB | ×2.4 |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing fix/typescript-auto-resolve-defaults (68a0820) with main (9cdcc57)
…ts own extension (#641) <!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. --> **Summary** `ExtensionAliasPlugin` marks every candidate `fullySpecified: true` and 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 via `package.json#main`. With the source extension listed among its own aliases (`{ ".js": [".js", ".ts"] }` — the documented TypeScript recipe, and what `experiments.typescript` sets 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 `.js` becomes 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. <!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? --> <!-- Try to link to an open issue for more information. --> <!-- Any other information related to changes. --> <!-- In addition to that please answer these questions: --> **What kind of change does this PR introduce?** fix <!-- E.g. a fix, feat, refactor, perf, test, chore, ci, build, style, revert, docs or describe it if you did not find a suitable kind of change. --> **Did you add tests for your changes?** Yes — three cases in `test/extension-alias.test.js` (directory named `dir3.js`, an aliased absolute path to a `pkg.js` package, and a strict mapping that must keep failing) plus the matching fixtures. <!-- Please note: in most cases, if you change the code, we will not merge your changes unless you add tests. --> **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 this PR introduces a breaking change, please describe the impact and a migration path for existing applications. --> **If relevant, what needs to be documented once your changes are merged or what have you already documented?** `extensionAlias` docs 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. <!-- List all the information that needs to be added to the documentation after merge that has already been documented in this PR. --> **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. <!-- If you have used AI, please state so here. Explain how you used it. Make sure to read our AI policy (https://github.com/webpack/governance/blob/main/AI_POLICY.md) or your Pull Request may be closed due to irresponsible use of AI. -->
f11b2ca to
a8b8955
Compare
|
CI is red on every job for one reason, and it is expected:
Unblocking is a release, not a code change. Once enhanced-resolve 5.24.4 is out, Generated by Claude Code |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a8b8955. Configure here.
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.
Relying on the `experiments.typescript` "auto" default made the case a no-op below Node.js 22.6, where the alias is never installed.
0080355 to
68a0820
Compare

Summary
experiments.typescript: "auto"only checks that Node.js can strip types and that no TS loader is registered — never whether the project contains any TypeScript — so since 5.109.0 every project on Node.js >= 22.6 silently got TypeScript resolution semantics:.tsahead of.js,tsconfigpaths, the.js->.tsextension alias, and thetypescriptexports condition. Those now require an explicit opt-in, and.tsstays a low-priority extension otherwise, matching how thecss/html"auto"defaults already avoid shadowingx.js. Fixes #21541.What kind of change does this PR introduce?
fix
Did you add tests for your changes?
Yes —
test/configCases/typescript/experiments-auto-resolve-defaultscovers all three resolution changes, andtest/Defaults.unittest.jsasserts the auto vs. explicit vs.futureDefaultsresolve options.Does this PR introduce a breaking change?
No — it restores the pre-5.109.0 resolution behavior for projects that never opted into TypeScript;
experiments.typescript: trueis unchanged.If relevant, what needs to be documented once your changes are merged or what have you already documented?
experiments.typescriptdocs should note thattsconfigpaths, the.js->.tsextension alias, thetypescriptexports condition and.ts-before-.jsordering needtypescript: true, not the"auto"default.Use of AI
AI (Claude Code) was used to trace the regression through the resolve defaults, probe the other auto-enabled resolution changes, and draft the fix and tests; the diagnosis and the final diff were reviewed by a human before submitting.
Generated by Claude Code
Note
Low Risk
Dependency-only resolver patch plus an integration test; no webpack core logic changes beyond the lockfile bump.
Overview
Fixes a regression where
resolve.aliastargets (and similar paths) could fail when the real package folder name ends with.js(e.g.node_modules/pkg.js), especially whenresolve.extensionAliasmaps.js→.ts.The change bumps
enhanced-resolvefrom^5.24.2to^5.24.4, which carries the resolver fix; webpack itself has no resolver logic changes in this diff. A new config casealias-to-package-directoryasserts thatrequire("vendor/pkg.js")resolves through an alias tonode_moduleswith the same.js→.tsextensionAliasshape TypeScript experiments use, without treating the package directory as an extension rewrite target.Reviewed by Cursor Bugbot for commit 68a0820. Bugbot is set up for automated code reviews on this repo. Configure here.