Skip to content

Commit 328ff7e

Browse files
refactor(dependencies): group lib/dependencies by owner (#22301)
* refactor(dependencies): move feature-owned dependencies to their directory A dependency only one feature builds belongs with that feature, by the rule the directory grouping already follows: the applier decides. The three ExternalModule* go to lib/node/ rather than lib/externals/, which never touches them — only NodeStuffPlugin does, to import fileURLToPath for __dirname. * refactor(dependencies): group the context dependency family Move the context-module dependencies into `lib/dependencies/context/`: the `ContextDependency` base every syntax family's context variant extends, `require.context`, `import.meta.webpackContext` and the glob form. The two `import.meta.webpackHot` dependencies join the `module.hot` pair in `lib/dependencies/hmr/`, and `CriticalDependencyWarning` moves to `lib/errors/` with the other warning classes. `import.meta` itself stays at the root: `WebpackOptionsApply` applies `ImportMetaPlugin` unconditionally, it taps `javascript/auto` as well as `javascript/esm`, and `lib/node/`, `lib/url/`, `lib/hmr/` and `worker/` read its hooks, so it is not an ESM-only surface. Each moved class keeps its old serializer request open with `registerLegacyRequest`. `ContextElementDependency` also keeps a re-export at its old path: context-map-webpack-plugin requires it unconditionally and names webpack 5 in its peer dependencies. The other three recorded paths are imported only from hard-source-webpack-plugin's webpack 4 module, so they are recorded as removed instead. * refactor(dependencies): group the WebAssembly and single-family dependencies Move the two WebAssembly dependencies into `lib/dependencies/wasm/`: the async and sync paths share `WebAssemblyImportDependency`, so neither `lib/wasm/` nor `lib/wasm-sync/` owns it alone. Three more follow their only applier into a directory that already exists: `TopLevelAwaitDependency` into `esm/`, `ModuleDecoratorDependency` into `commonjs/`, and the generically named `UnsupportedDependency`, which only AMD emits, into `amd/`. Each keeps its old serializer request open with `registerLegacyRequest`. The two recorded paths are imported only from hard-source-webpack-plugin's webpack 4 module, so they are recorded as removed rather than shimmed. * refactor(dependencies): group the dynamic import family Move `import()` into `lib/dependencies/import/`: the three dependencies, the context variant, the parser plugin, `ImportPlugin` and the options check. It is not `esm/`, although `import()` is ESM syntax. `ImportPlugin` is applied by `WebpackOptionsApply`, not `ESMModulesPlugin`, and it taps `javascript/dynamic` as well as `auto` and `esm`, since the expression is legal in a script. `ImportPhase` stays at the root, read by `graph/`, `optimize/`, `externals/` and more. Each moved class keeps its old serializer request open with `registerLegacyRequest`. The four recorded paths are imported only from hard-source-webpack-plugin's webpack 4 module, so they are recorded as removed rather than shimmed.
1 parent 42b2bfe commit 328ff7e

84 files changed

Lines changed: 629 additions & 500 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎AGENTS.md‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,15 @@ This is the canonical repository map. **When you add, rename or remove a top-lev
6060
- `lib/cache/` — filesystem and memory caches.
6161
- `lib/config/` — user config → `Compiler`: `validateSchema` checks the schema, `normalization.js` canonicalizes the shape, `defaults.js` fills values, `WebpackOptionsApply` applies the implied plugins. `WebpackOptionsDefaulter` is the deprecated normalize+default pair; `OptionsApply` is the apply step's base class. Also the target presets, `defineConfig`, and `PlatformPlugin` (pins the platform a `target: false` build can't infer). `cli.js` reads the schema the other way — derives CLI flags and applies parsed args back — hence webpack-cli uses it via `webpack.cli`. That object's terminal colors are `lib/util/terminalColors.js`, kept apart so reading a color doesn't parse the schema.
6262
- `lib/container/` — Module Federation.
63-
- `lib/context/` — context modules (`require.context`, dynamic request directories) and the plugins narrowing them.
63+
- `lib/context/` — context modules (`require.context`, dynamic request directories) and the plugins narrowing them; their dependencies are `lib/dependencies/context/`.
6464
- `lib/css/` — CSS Modules, parsing, generation. `syntax.js` reaches `syntax-parser.js` (reads) and `syntax-printer.js` (writes) through getters, like `javascript`, so a walk that never prints never loads the printer. It publishes those two plus `SourceProcessor` only — read a former re-export off `parser` or `printer`.
6565
- `lib/debug/` — debug helpers.
6666
- `lib/define/` — replacing a free identifier with a constant at parse time: `DefinePlugin`, plus `EnvironmentPlugin` (fed from `process.env`) and `DotenvPlugin` (from `.env`). `ProvidePlugin` substitutes an import, not a value → `lib/provide/`.
67-
- `lib/dependencies/` — concrete `Dependency` subclasses and their templates (ESMImport, CommonJsRequire, RequireContext, …); the base `Dependency` is in `lib/graph/`, `DependencyTemplate` in `lib/template/`. Its root holds what every language shares (`NullDependency`, `ModuleDependency`, `ConstDependency`, both `ModuleDependencyTemplateAs*`, the helpers several families read); a syntax family owning a set of them gets its own directory: `amd/` (with the `LocalModule` a named `define` records, plus `RequireJsStuffPlugin`), `commonjs/` (with `require.resolve`, `require.ensure` and `require.include`), `css/`, `esm/`, `html/`, `hmr/`, `system/`, `worker/` (with the `CreateScriptUrlDependency` only it constructs). What decides the directory is which plugin applies it, not the language it names: `CreateRequireParserPlugin` reads a CommonJS `require` out of an ESM module, so it sits in `esm/`, because `ESMModulesPlugin` applies it. A class leaving this root moves its `makeSerializable` request with it and holds the old one open with `registerLegacyRequest`, or a pre-move cache pack stops loading — one that moved twice keeps a registration per old request, which is why the `esm/` classes carry both an `ESM` and a `Harmony` one.
67+
- `lib/dependencies/` — concrete `Dependency` subclasses and their templates (ESMImport, CommonJsRequire, RequireContext, …); the base `Dependency` is in `lib/graph/`, `DependencyTemplate` in `lib/template/`. Its root holds what every language shares (`NullDependency`, `ModuleDependency`, `ConstDependency`, both `ModuleDependencyTemplateAs*`, the helpers several families read); a family owning a set of them gets its own directory: `amd/` (with the `LocalModule` a named `define` records, `RequireJsStuffPlugin`, and the generically named `UnsupportedDependency`, which only AMD emits), `commonjs/` (with `require.resolve`, `require.ensure`, `require.include` and `ModuleDecoratorDependency`), `context/`, `css/`, `esm/` (with `TopLevelAwaitDependency`), `html/`, `hmr/`, `import/`, `system/`, `wasm/`, `worker/` (with the `CreateScriptUrlDependency` only it constructs). Two group by what a request asks for rather than by syntax: `context/` (the `ContextDependency` base every family's context variant extends, plus `require.context`, `import.meta.webpackContext` and the glob form) and `hmr/` (the `module.hot` and `import.meta.webpackHot` accept/decline pairs). What decides the directory is which plugin applies it, not the language it names: `CreateRequireParserPlugin` reads a CommonJS `require` out of an ESM module, so it sits in `esm/`, because `ESMModulesPlugin` applies it. `import.meta` is not `esm/` for the same reason: `WebpackOptionsApply` applies `ImportMetaPlugin` unconditionally, it taps `javascript/auto` as well as `javascript/esm`, and `lib/node/`, `lib/url/`, `lib/hmr/` and `worker/` read its hooks, so it stays at the root and its context and hot dependencies follow their applier. `import()` sits in `import/`, not `esm/`, on the same evidence: `ImportPlugin` is applied by `WebpackOptionsApply` and taps `javascript/dynamic` too, since the expression is legal in a script. Its `ImportPhase` enum stays at the root, read by `graph/`, `optimize/`, `externals/` and more. A dependency a single feature owns is not here at all but with that feature, by the same rule: `LoaderDependency` in `lib/loaders/`, `JsonExportsDependency` in `lib/json/`, `DllEntryDependency` in `lib/dll/`, the `ExternalModule*` three in `lib/node/`. A class leaving this root moves its `makeSerializable` request with it and holds the old one open with `registerLegacyRequest`, or a pre-move cache pack stops loading — one that moved twice keeps a registration per old request, which is why the `esm/` classes carry both an `ESM` and a `Harmony` one. `ContextElementDependency` also keeps a re-export at its old path, the one moved path a published webpack 5 plugin imports.
6868
- `lib/devtool/` — source maps: the `devtool` plugins and their filename helpers.
6969
- `lib/diagnostics/` — plugins raising a build-wide error/warning of their own (case-insensitive filesystem collision, deprecated option, missing `mode`), `IgnoreWarningsPlugin` (filters them) and `NoEmitOnErrorsPlugin` (reacts to errors). Their classes live in `lib/errors/`; `performance` hints in `lib/performance/`.
70-
- `lib/dll/` — DllPlugin / DllReferencePlugin.
71-
- `lib/deno/`, `lib/electron/`, `lib/node/`, `lib/web/`, `lib/webworker/` — target-specific runtime templates and externals presets.
70+
- `lib/dll/` — DllPlugin / DllReferencePlugin, and the two dependencies they own, `DllEntryDependency` and `DelegatedSourceDependency`.
71+
- `lib/deno/`, `lib/electron/`, `lib/node/`, `lib/web/`, `lib/webworker/` — target-specific runtime templates and externals presets. `lib/node/` also holds the three `ExternalModule*` dependencies, which only `NodeStuffPlugin` applies: they import a host module inline (`fileURLToPath` from `node:url` for `__dirname`) and are unrelated to `lib/externals/ExternalModule`, despite the name.
7272
- `lib/entry/` — the `entry` option: `EntryPlugin`, `EntryOptionPlugin` (reads the option into it), `DynamicEntryPlugin` (function entry). `Entrypoint` is a `ChunkGroup` → `lib/graph/`.
7373
- `lib/errors/` — error and warning class hierarchy.
7474
- `lib/esm/` — ESM-specific output (e.g. `import.meta`).
@@ -82,9 +82,9 @@ This is the canonical repository map. **When you add, rename or remove a top-lev
8282
- `syntax.js` reaches `parser` and `printer` through getters: parsing never loads the printer, printing never the parser.
8383
- `syntax-parser.js` — tokenizer, acorn-derived core and every production in one file (any parse reaches the productions, and the coming struct-of-arrays rewrite moves node creation through them). `regexp.js` (pattern validator) is the one on-demand piece, reached only for a pattern the host engine rejected — never `require` it from a build path.
8484
- `syntax-printer.js` — prints JS back out. `jsMinify.js` (the `minify` the default minimizer dispatches JS to) goes through it rather than terser's published entry, because that loader reads terser's sources — letting a phase webpack implements replace terser's method. Each phase taken over is one less thing terser does. A phase states what it reads with `supports`; a minifier that moved any of it, or a runtime that can't import those sources, keeps its own. Add phases to the `PHASES` list there and nowhere else, each writing byte-for-byte what it replaced.
85-
- `lib/json/` — JSON modules, and `jsonMinify`, which strips the whitespace between a JSON asset's tokens for the default minimizer.
85+
- `lib/json/` — JSON modules, with the `JsonExportsDependency` naming what one exports, and `jsonMinify`, which strips the whitespace between a JSON asset's tokens for the default minimizer.
8686
- `lib/library/` — UMD/AMD/ESM/CommonJS library formats, and the deprecated `LibraryTemplatePlugin` (old two-argument API).
87-
- `lib/loaders/` — loader execution (vendored loader-runner): pitching/normal iteration and loader loading, plus `LoaderOptionsPlugin` and `LoaderTargetPlugin`, which feed the loader context.
87+
- `lib/loaders/` — loader execution (vendored loader-runner): pitching/normal iteration and loader loading, plus `LoaderOptionsPlugin` and `LoaderTargetPlugin`, which feed the loader context, and `LoaderPlugin` with the `LoaderDependency`/`LoaderImportDependency` it builds a loader's own imports from.
8888
- `lib/logging/` — Logger API, console formatting, and `ProgressPlugin` (reports through it). `lib/ProgressPlugin` stays a re-export (webpack-stream requires it).
8989
- `lib/module/` — what a module is and what makes one: `Module`, `NormalModule`, the factories (`NormalModuleFactory`, `NullFactory`, `SelfModuleFactory`), base `Parser`/`Generator`, `CodeGenerationResults`, `ModuleProfile`, and the two constants files naming module and source types. A plugin's module subclass lives with the plugin (`ExternalModule` → `lib/externals/`, `CssModule` → `lib/css/`).
9090
- `lib/optimize/` — optimization plugins (`SplitChunksPlugin`, `ConcatenatedModule`, …), `CircularModulesPlugin` (flags import cycles) and `LazyBarrel` (finds barrel files worth deferring). `ConcatenationScope` is scope hoisting's protocol: only `ConcatenatedModule` constructs one; any generator renders through it.
@@ -103,7 +103,7 @@ This is the canonical repository map. **When you add, rename or remove a top-lev
103103
- `lib/typescript/` — experimental TypeScript modules (types stripped via Node's TypeScript API).
104104
- `lib/url/` — `new URL(asset, import.meta.url)`.
105105
- `lib/util/` — helpers no one subsystem owns (a data structure, an algorithm, something several directories share): e.g. `dataURL` (reads/writes `data:` URLs; helpers a minifier drives a caller's `renderEmbeddedSource` through), `RequestShortener` (context-relative requests in user-facing messages), `terminalColors` (color detection and escape wrappers for all terminal output — `ProgressPlugin`, `nodeConsole`, webpack-cli via `webpack.cli`). A helper only one subsystem uses lives there (`semver` → `lib/sharing/`, `numberHash` → `lib/ids/`, `deterministicGrouping` → `lib/optimize/`), so a directory's contents show what it is made of.
106-
- `lib/wasm/` — WebAssembly's async path, plus `EnableWasmLoadingPlugin` and `wasmModuleFilename`, which neither path owns.
106+
- `lib/wasm/` — WebAssembly's async path, plus `EnableWasmLoadingPlugin` and `wasmModuleFilename`, which neither path owns. Both paths' dependencies are `lib/dependencies/wasm/`, since they share `WebAssemblyImportDependency`.
107107
- `lib/wasm-sync/` — the sync WebAssembly path, kept apart until the next major release removes it.
108108
- `lib/watch/` — watch mode: the watching handles a compiler returns, and `WatchIgnorePlugin`.
109109
- `hot/` — browser-side HMR runtime (not Node tooling).
@@ -166,7 +166,7 @@ Keep `--depth 1` (`wpt` alone is ~161k files). `--remote` changes the recorded c
166166
- `examples/` — usage examples (`yarn build:examples`).
167167
- `.changeset/` — pending changesets for the next release.
168168

169-
**Hand-maintained type declarations (editable)** — `declarations.d.ts`, `declarations.test.d.ts`, `module.d.ts`. The loader context is not one of them: `LoaderContext` and the loader-definition types are JSDoc in `lib/`, declared where the code adding each part lives (`lib/module/NormalModule.js`, `lib/loaders/LoaderRunner.js`, `lib/dependencies/LoaderPlugin.js`, `lib/hmr/HotModuleReplacementPlugin.js`) and re-exported from `lib/index.js`, the file `generate-types.js` reads the public type surface from.
169+
**Hand-maintained type declarations (editable)** — `declarations.d.ts`, `declarations.test.d.ts`, `module.d.ts`. The loader context is not one of them: `LoaderContext` and the loader-definition types are JSDoc in `lib/`, declared where the code adding each part lives (`lib/module/NormalModule.js`, `lib/loaders/LoaderRunner.js`, `lib/loaders/LoaderPlugin.js`, `lib/hmr/HotModuleReplacementPlugin.js`) and re-exported from `lib/index.js`, the file `generate-types.js` reads the public type surface from.
170170

171171
**Configuration**
172172

‎lib/config/WebpackOptionsApply.js‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,16 @@ const InferAsyncModulesPlugin = require("../async-modules/InferAsyncModulesPlugi
1111

1212
const ResolverCachePlugin = require("../cache/ResolverCachePlugin");
1313

14-
const ImportMetaContextPlugin = require("../dependencies/ImportMetaContextPlugin");
1514
const ImportMetaPlugin = require("../dependencies/ImportMetaPlugin");
1615

17-
const ImportPlugin = require("../dependencies/ImportPlugin");
18-
const LoaderPlugin = require("../dependencies/LoaderPlugin");
19-
20-
const RequireContextPlugin = require("../dependencies/RequireContextPlugin");
2116
const URLPlugin = require("../dependencies/URLPlugin");
2217
const CommonJsPlugin = require("../dependencies/commonjs/CommonJsPlugin");
2318
const RequireEnsurePlugin = require("../dependencies/commonjs/RequireEnsurePlugin");
2419
const RequireIncludePlugin = require("../dependencies/commonjs/RequireIncludePlugin");
20+
const ImportMetaContextPlugin = require("../dependencies/context/ImportMetaContextPlugin");
21+
const RequireContextPlugin = require("../dependencies/context/RequireContextPlugin");
2522
const ESMModulesPlugin = require("../dependencies/esm/ESMModulesPlugin");
23+
const ImportPlugin = require("../dependencies/import/ImportPlugin");
2624

2725
const SystemPlugin = require("../dependencies/system/SystemPlugin");
2826

@@ -41,6 +39,7 @@ const UseStrictPlugin = require("../javascript/UseStrictPlugin");
4139
const WebpackIsIncludedPlugin = require("../javascript/WebpackIsIncludedPlugin");
4240

4341
const JsonModulesPlugin = require("../json/JsonModulesPlugin");
42+
const LoaderPlugin = require("../loaders/LoaderPlugin");
4443
const NodeStuffPlugin = require("../node/NodeStuffPlugin");
4544
const FlagDependencyExportsPlugin = require("../optimize/FlagDependencyExportsPlugin");
4645

‎lib/context/ContextModule.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ const { registerLegacyRequest } = require("../util/serialization");
7474
/** @import RequestShortener from "../util/RequestShortener" */
7575
/** @import { ResolverWithOptions } from "../resolve/ResolverFactory" */
7676
/** @import RuntimeTemplate from "../template/RuntimeTemplate" */
77-
/** @import ContextElementDependency from "../dependencies/ContextElementDependency" */
77+
/** @import ContextElementDependency from "../dependencies/context/ContextElementDependency" */
7878
/** @import { ImportAttributes } from "../javascript/JavascriptParser" */
7979
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext<[string, boolean]>} ObjectDeserializerContext */
8080
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext<[string, boolean]>} ObjectSerializerContext */
@@ -1479,7 +1479,7 @@ module.exports = webpackEmptyAsyncContext;`;
14791479
const returnModuleObject = this.getReturnModuleObjectSource(fakeMap);
14801480
const globImportAccess = this.getImportPropertyAccess();
14811481
const sortedDependencies =
1482-
/** @type {import("../dependencies/ContextElementDependency")[]} */
1482+
/** @type {import("../dependencies/context/ContextElementDependency")[]} */
14831483
(dependencies).sort((a, b) =>
14841484
a.userRequest < b.userRequest
14851485
? -1

‎lib/context/ContextModuleFactory.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"use strict";
77

88
const { AsyncSeriesWaterfallHook, SyncWaterfallHook } = require("tapable");
9-
const ContextElementDependency = require("../dependencies/ContextElementDependency");
9+
const ContextElementDependency = require("../dependencies/context/ContextElementDependency");
1010
const { join } = require("../fs/fs");
1111
const ModuleFactory = require("../module/ModuleFactory");
1212
const LazySet = require("../util/LazySet");
@@ -39,7 +39,7 @@ const ContextModule = require("./ContextModule");
3939
* } from "../module/ModuleFactory"
4040
*/
4141
/** @import ResolverFactory from "../resolve/ResolverFactory" */
42-
/** @import ContextDependency from "../dependencies/ContextDependency" */
42+
/** @import ContextDependency from "../dependencies/context/ContextDependency" */
4343

4444
/**
4545
* Defines the shared type used by this module.

‎lib/context/ContextReplacementPlugin.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
"use strict";
77

8-
const ContextElementDependency = require("../dependencies/ContextElementDependency");
8+
const ContextElementDependency = require("../dependencies/context/ContextElementDependency");
99
const { isAbsolute, join } = require("../fs/fs");
1010

1111
/** @import Compiler from "../Compiler" */

‎lib/css/CssGenerator.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ const {
1212
ReplaceSource,
1313
SourceMapSource
1414
} = require("webpack-sources");
15-
const LoaderImportDependency = require("../dependencies/LoaderImportDependency");
1615
const CssImportDependency = require("../dependencies/css/CssImportDependency");
1716
const ESMImportSideEffectDependency = require("../dependencies/esm/ESMImportSideEffectDependency");
1817
const ModuleFilenameHelpers = require("../devtool/ModuleFilenameHelpers");
1918
const { UsageState } = require("../graph/ExportsInfo");
19+
const LoaderImportDependency = require("../loaders/LoaderImportDependency");
2020
const Generator = require("../module/Generator");
2121
const {
2222
CSS_TEXT_TYPE,

0 commit comments

Comments
 (0)