Let webpack resolve nested node_modules like node does - #27421
Draft
dennisoelkers wants to merge 1 commit into
Draft
dennisoelkers wants to merge 1 commit into
dennisoelkers wants to merge 1 commit into
Conversation
`resolve.modules` treats its entries differently depending on their shape: a
bare name like `node_modules` makes webpack walk up the directory tree from
the importing module, exactly like node, while an absolute path is searched
as one fixed directory and nothing else. `webpack/core.js` and
`webpack.preflight.ts` listed only absolute paths, so nested `node_modules`
were invisible to the bundle and every request resolved to whatever yarn
happened to hoist to the top level — regardless of the range the requiring
package declared.
That silently collapses versions the package manager deliberately kept
apart. The failure mode is not a missing module but a wrong one, and when
two packages depend on each other it becomes a require cycle: the second
module gets the first's half-initialised `module.exports` and calling it
throws at import time. `get-intrinsic` 1.3.0 with a hoisted `gopd` 1.0.1 is
exactly this shape, and it takes down the whole bundle on load. Note that
`webpack.vendor.ts` sets no `resolve` block at all and so has always had the
correct behaviour — this only aligns the other two configs with it.
Adding the bare `node_modules` entry restores node's semantics. The absolute
entries stay as fallbacks: plugins build out of tree, where `rootPath` is the
plugin directory, and walking up from a plugin source file never reaches
`<web-interface>/node_modules`.
## Plugin builds are deliberately left alone
`PluginWebpackConfig` prepends `<web-interface>/node_modules` to this list,
so for plugin builds the merged order is:
[<wi>/src, <wi>/node_modules, <plugin>/src/web, node_modules,
<plugin>/node_modules, <plugin>/public]
The flat `<wi>/node_modules` staying ahead of the walk-up entry is
load-bearing, not an oversight. graylog-plugin-enterprise ships its own
`react` 18.3.1, `react-dom` 18.2.0, `styled-components` 6.1.1 and `moment`
2.29.4; those must come from the web interface so plugins share the single
instance in the vendor DLL. Moving the walk-up entry ahead of it would give
plugins their own React and break hooks and theming. Plugin bundles
therefore keep the old flattening behaviour. Fixing that properly means
pinning the shared singletons with `resolve.alias` instead of relying on
list order, which is a bigger change and left for later.
## Verification
Resolution was checked directly through webpack's own `enhanced-resolve`
with the real merged module lists:
| From | Request | Before | After |
| --- | --- | --- | --- |
| `get-intrinsic` | `hasown` | `<wi>/node_modules/hasown` 2.0.2 | `get-intrinsic/node_modules/hasown` 2.0.0 |
| `@floating-ui/dom` | `@floating-ui/utils` | root 0.2.10 | nested 0.2.8 |
| `i18next` | `@babel/runtime/...` | root | nested |
| plugin source | `react` | `<wi>` 18.3.1 | `<wi>` 18.3.1 |
| plugin source | `styled-components` | `<wi>` 6.1.1 | `<wi>` 6.1.1 |
Bundle contents confirm it end to end: the app build goes from 0 to 61
modules resolved out of a nested `node_modules`, at a cost of about 83 KB of
minified JS (+0.35%). Duplication only appears where yarn could not hoist,
which is precisely where the versions genuinely conflict.
`yarn build`, `yarn build:preflight` and `yarn check-production-build` all
pass, `yarn tsgo` is clean, and `yarn test` is 777 suites / 4169 passed / 0
failures. `yarn lint:path` reports the same 28 pre-existing errors on these
two files before and after, none on the changed lines.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Motivation and Context
This PR is changing
resolve.modulesconfiguration for both core andplugin webpack configs, to avoid silently collapsing package versions
from different
node_modulesdirectories./nocl Internal refactoring.
How Has This Been Tested?
Screenshots (if appropriate):
Types of changes
Checklist: