@depup/webpack 5.109.0-depup.0 → 5.109.2-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/bin/webpack.js +12 -0
- package/changes.json +4 -4
- package/lib/ChunkGraph.js +17 -15
- package/lib/CleanPlugin.js +11 -9
- package/lib/CompatibilityPlugin.js +31 -0
- package/lib/Compilation.js +21 -5
- package/lib/Compiler.js +16 -4
- package/lib/DefinePlugin.js +47 -20
- package/lib/ExportsInfo.js +22 -5
- package/lib/ExternalModule.js +10 -7
- package/lib/FileSystemInfo.js +126 -26
- package/lib/FlagDependencyUsagePlugin.js +33 -12
- package/lib/InitFragment.js +20 -32
- package/lib/ModuleFilenameHelpers.js +13 -2
- package/lib/NormalModule.js +80 -71
- package/lib/NormalModuleFactory.js +8 -2
- package/lib/RuntimePlugin.js +40 -113
- package/lib/Template.js +23 -3
- package/lib/cache/PackFileCacheStrategy.js +259 -5
- package/lib/config/defaults.js +21 -2
- package/lib/container/HoistContainerReferencesPlugin.js +47 -55
- package/lib/container/ModuleFederationPlugin.js +15 -9
- package/lib/css/CssGenerator.js +8 -2
- package/lib/css/CssLoadingRuntimeModule.js +25 -12
- package/lib/css/CssModulesPlugin.js +29 -18
- package/lib/css/CssParser.js +135 -50
- package/lib/css/syntax.js +862 -765
- package/lib/dependencies/CommonJsExportRequireDependency.js +19 -0
- package/lib/dependencies/CommonJsFullRequireDependency.js +33 -4
- package/lib/dependencies/CommonJsImportsParserPlugin.js +2 -0
- package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +2 -1
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +17 -9
- package/lib/dependencies/HarmonyImportDependency.js +1 -1
- package/lib/dependencies/HarmonyImportGuard.js +2 -1
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -7
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +15 -9
- package/lib/hmr/lazyCompilationBackend.js +19 -4
- package/lib/html/HtmlGenerator.js +23 -3
- package/lib/html/HtmlModulesPlugin.js +30 -12
- package/lib/html/syntax.js +2485 -2399
- package/lib/ids/IdHelpers.js +24 -10
- package/lib/javascript/JavascriptModulesPlugin.js +83 -49
- package/lib/javascript/JavascriptParser.js +49 -13
- package/lib/javascript/syntax.js +700 -43
- package/lib/node/ReadFileCompileAsyncWasmPlugin.js +10 -2
- package/lib/node/ReadFileCompileWasmPlugin.js +10 -2
- package/lib/optimize/AggressiveMergingPlugin.js +19 -15
- package/lib/optimize/ConcatenatedModule.js +19 -15
- package/lib/optimize/ModuleConcatenationPlugin.js +73 -24
- package/lib/optimize/RealContentHashPlugin.js +10 -7
- package/lib/optimize/SplitChunksPlugin.js +146 -44
- package/lib/prefetch/ResourceHintPlugin.js +96 -72
- package/lib/serialization/BinaryMiddleware.js +270 -938
- package/lib/serialization/FileMiddleware.js +299 -60
- package/lib/stats/DefaultStatsFactoryPlugin.js +204 -198
- package/lib/stats/DefaultStatsPrinterPlugin.js +24 -166
- package/lib/stats/StatsFactory.js +31 -9
- package/lib/util/identifier.js +21 -1
- package/package.json +10 -10
- package/schemas/WebpackOptions.json +110 -55
- package/types.d.ts +832 -247
|
@@ -240,6 +240,25 @@ class CommonJsExportRequireDependency extends ModuleDependency {
|
|
|
240
240
|
dependencies: [from.module]
|
|
241
241
|
};
|
|
242
242
|
}
|
|
243
|
+
// The imported namespace ESM hasn't been flagged by
|
|
244
|
+
// FlagDependencyExportsPlugin yet (no exports determined), so its
|
|
245
|
+
// `"module.exports"` unwrap eligibility is still unknown. Star-reexporting
|
|
246
|
+
// now would add `__esModule` (and names) the monotonic merge can't retract
|
|
247
|
+
// once the module turns out to unwrap, making the result order-dependent
|
|
248
|
+
// across runtimes; defer — the `from.module` dependency re-queues us once
|
|
249
|
+
// its exports (owned names, or dynamic `other`) become known.
|
|
250
|
+
if (
|
|
251
|
+
importedModule &&
|
|
252
|
+
importedModule.getExportsType(moduleGraph, false) === "namespace"
|
|
253
|
+
) {
|
|
254
|
+
const importedExportsInfo = moduleGraph.getExportsInfo(importedModule);
|
|
255
|
+
if (
|
|
256
|
+
importedExportsInfo.otherExportsInfo.provided === false &&
|
|
257
|
+
importedExportsInfo.ownedExports[Symbol.iterator]().next().done
|
|
258
|
+
) {
|
|
259
|
+
return { exports: [], dependencies: [from.module] };
|
|
260
|
+
}
|
|
261
|
+
}
|
|
243
262
|
const reexportInfo = this.getStarReexports(
|
|
244
263
|
moduleGraph,
|
|
245
264
|
undefined,
|
|
@@ -9,6 +9,7 @@ const Template = require("../Template");
|
|
|
9
9
|
const { equals } = require("../util/ArrayHelpers");
|
|
10
10
|
const { getTrimmedIdsAndRange } = require("../util/chainedImports");
|
|
11
11
|
const makeSerializable = require("../util/makeSerializable");
|
|
12
|
+
const memoize = require("../util/memoize");
|
|
12
13
|
const { propertyAccess } = require("../util/property");
|
|
13
14
|
const {
|
|
14
15
|
ESM_MODULE_EXPORTS_NAME,
|
|
@@ -19,6 +20,7 @@ const ModuleDependency = require("./ModuleDependency");
|
|
|
19
20
|
|
|
20
21
|
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
|
|
21
22
|
/** @typedef {import("../Dependency")} Dependency */
|
|
23
|
+
/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */
|
|
22
24
|
/** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
|
|
23
25
|
/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
|
|
24
26
|
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
|
@@ -26,8 +28,11 @@ const ModuleDependency = require("./ModuleDependency");
|
|
|
26
28
|
/** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
|
|
27
29
|
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
|
|
28
30
|
/** @typedef {import("../util/chainedImports").IdRanges} IdRanges */
|
|
29
|
-
/** @typedef {import("
|
|
30
|
-
/** @typedef {import("../serialization/ObjectMiddleware").
|
|
31
|
+
/** @typedef {import("./HarmonyImportGuard").DependencyGuard} DependencyGuard */
|
|
32
|
+
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext<[ExportInfoName[], IdRanges | undefined, boolean, undefined | boolean, DependencyGuard[] | undefined]>} ObjectDeserializerContext */
|
|
33
|
+
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext<[ExportInfoName[], IdRanges | undefined, boolean, undefined | boolean, DependencyGuard[] | undefined]>} ObjectSerializerContext */
|
|
34
|
+
|
|
35
|
+
const getHarmonyImportGuard = memoize(() => require("./HarmonyImportGuard"));
|
|
31
36
|
|
|
32
37
|
class CommonJsFullRequireDependency extends ModuleDependency {
|
|
33
38
|
/**
|
|
@@ -53,6 +58,20 @@ class CommonJsFullRequireDependency extends ModuleDependency {
|
|
|
53
58
|
this.call = false;
|
|
54
59
|
/** @type {undefined | boolean} */
|
|
55
60
|
this.asiSafe = undefined;
|
|
61
|
+
/** @type {DependencyGuard[] | undefined} */
|
|
62
|
+
this.branchGuards = undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Returns function to determine if the connection is active.
|
|
67
|
+
* @param {ModuleGraph} moduleGraph module graph
|
|
68
|
+
* @returns {null | false | GetConditionFn} function to determine if the connection is active
|
|
69
|
+
*/
|
|
70
|
+
getCondition(moduleGraph) {
|
|
71
|
+
const guards = this.branchGuards;
|
|
72
|
+
if (guards === undefined) return null;
|
|
73
|
+
return (connection, runtime) =>
|
|
74
|
+
!getHarmonyImportGuard().isDeadByGuards(guards, moduleGraph, runtime);
|
|
56
75
|
}
|
|
57
76
|
|
|
58
77
|
/**
|
|
@@ -92,7 +111,8 @@ class CommonJsFullRequireDependency extends ModuleDependency {
|
|
|
92
111
|
.write(this.names)
|
|
93
112
|
.write(this.idRanges)
|
|
94
113
|
.write(this.call)
|
|
95
|
-
.write(this.asiSafe)
|
|
114
|
+
.write(this.asiSafe)
|
|
115
|
+
.write(this.branchGuards);
|
|
96
116
|
super.serialize(context);
|
|
97
117
|
}
|
|
98
118
|
|
|
@@ -108,7 +128,9 @@ class CommonJsFullRequireDependency extends ModuleDependency {
|
|
|
108
128
|
this.call = c2.read();
|
|
109
129
|
const c3 = c2.rest;
|
|
110
130
|
this.asiSafe = c3.read();
|
|
111
|
-
|
|
131
|
+
const c4 = c3.rest;
|
|
132
|
+
this.branchGuards = c4.read();
|
|
133
|
+
super.deserialize(c4.rest);
|
|
112
134
|
}
|
|
113
135
|
|
|
114
136
|
get type() {
|
|
@@ -137,6 +159,13 @@ CommonJsFullRequireDependency.Template = class CommonJsFullRequireDependencyTemp
|
|
|
137
159
|
) {
|
|
138
160
|
const dep = /** @type {CommonJsFullRequireDependency} */ (dependency);
|
|
139
161
|
if (!dep.range) return;
|
|
162
|
+
const connection = moduleGraph.getConnection(dep);
|
|
163
|
+
// Dead branch: module is excluded and has no id; code is never executed.
|
|
164
|
+
if (connection && !connection.isTargetActive(runtime)) {
|
|
165
|
+
// Replaces the whole member chain, so no property access is left dangling
|
|
166
|
+
source.replace(dep.range[0], dep.range[1] - 1, "null /* dead branch */");
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
140
169
|
const importedModule = moduleGraph.getModule(dep);
|
|
141
170
|
let requireExpr = runtimeTemplate.moduleExports({
|
|
142
171
|
module: importedModule,
|
|
@@ -642,6 +642,7 @@ class CommonJsImportsParserPlugin {
|
|
|
642
642
|
dep.optional = Boolean(parser.scope.inTry);
|
|
643
643
|
dep.loc = parser.getLocation(expr);
|
|
644
644
|
parser.state.current.addDependency(dep);
|
|
645
|
+
getHarmonyImportGuard().attachDependencyGuards(parser, dep);
|
|
645
646
|
return true;
|
|
646
647
|
}
|
|
647
648
|
};
|
|
@@ -680,6 +681,7 @@ class CommonJsImportsParserPlugin {
|
|
|
680
681
|
dep.optional = Boolean(parser.scope.inTry);
|
|
681
682
|
dep.loc = parser.getLocation(expr.callee);
|
|
682
683
|
parser.state.current.addDependency(dep);
|
|
684
|
+
getHarmonyImportGuard().attachDependencyGuards(parser, dep);
|
|
683
685
|
parser.walkExpressions(expr.arguments);
|
|
684
686
|
return true;
|
|
685
687
|
}
|
|
@@ -191,8 +191,11 @@ const isStarReexportBackToParent = (moduleGraph, exportInfo, parentModule) => {
|
|
|
191
191
|
let current = moduleGraph
|
|
192
192
|
.getExportsInfo(firstTarget.module)
|
|
193
193
|
.getReadOnlyExportInfo(firstTarget.export[0]);
|
|
194
|
-
|
|
195
|
-
|
|
194
|
+
// Allocated lazily: a single-extra-hop chain that terminates (the common
|
|
195
|
+
// `barrel -> leaf local binding` case) returns before `next` is ever
|
|
196
|
+
// computed, so the visited set is pure waste there.
|
|
197
|
+
/** @type {Set<ExportInfo> | undefined} */
|
|
198
|
+
let visited;
|
|
196
199
|
for (;;) {
|
|
197
200
|
const target = current.findTarget(moduleGraph, RETURNS_TRUE);
|
|
198
201
|
if (!target || typeof target !== "object") return false;
|
|
@@ -210,6 +213,7 @@ const isStarReexportBackToParent = (moduleGraph, exportInfo, parentModule) => {
|
|
|
210
213
|
const next = moduleGraph
|
|
211
214
|
.getExportsInfo(target.module)
|
|
212
215
|
.getReadOnlyExportInfo(target.export[0]);
|
|
216
|
+
if (visited === undefined) visited = new Set([exportInfo, current]);
|
|
213
217
|
if (visited.has(next)) return false;
|
|
214
218
|
visited.add(next);
|
|
215
219
|
current = next;
|
|
@@ -635,7 +639,8 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|
|
635
639
|
exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused;
|
|
636
640
|
|
|
637
641
|
/** @type {IgnoredExports} */
|
|
638
|
-
const ignoredExports = new Set(
|
|
642
|
+
const ignoredExports = new Set(this.activeExports);
|
|
643
|
+
ignoredExports.add("default");
|
|
639
644
|
|
|
640
645
|
/** @type {Hidden | undefined} */
|
|
641
646
|
let hiddenExports;
|
|
@@ -1387,7 +1392,12 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
|
|
|
1387
1392
|
);
|
|
1388
1393
|
break;
|
|
1389
1394
|
|
|
1390
|
-
case "normal-reexport":
|
|
1395
|
+
case "normal-reexport": {
|
|
1396
|
+
// loop-invariants hoisted out of the per-item loop below (a barrel
|
|
1397
|
+
// re-exporting N names otherwise repeats these lookups N times)
|
|
1398
|
+
const connection = moduleGraph.getConnection(dep);
|
|
1399
|
+
const selfExportsInfo = moduleGraph.getExportsInfo(module);
|
|
1400
|
+
const importedExportsInfo = moduleGraph.getExportsInfo(importedModule);
|
|
1391
1401
|
for (const {
|
|
1392
1402
|
name,
|
|
1393
1403
|
ids,
|
|
@@ -1396,7 +1406,6 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
|
|
|
1396
1406
|
} of /** @type {NormalReexportItem[]} */ (mode.items)) {
|
|
1397
1407
|
if (hidden) continue;
|
|
1398
1408
|
if (checked) {
|
|
1399
|
-
const connection = moduleGraph.getConnection(dep);
|
|
1400
1409
|
const key = `harmony reexport (checked) ${importVar} ${name}`;
|
|
1401
1410
|
const runtimeCondition = dep.weak
|
|
1402
1411
|
? false
|
|
@@ -1425,11 +1434,9 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
|
|
|
1425
1434
|
this.getReexportFragment(
|
|
1426
1435
|
module,
|
|
1427
1436
|
"reexport safe",
|
|
1428
|
-
|
|
1437
|
+
selfExportsInfo.getUsedName(name, runtime),
|
|
1429
1438
|
importVar,
|
|
1430
|
-
|
|
1431
|
-
.getExportsInfo(importedModule)
|
|
1432
|
-
.getUsedName(ids, runtime),
|
|
1439
|
+
importedExportsInfo.getUsedName(ids, runtime),
|
|
1433
1440
|
runtimeRequirements,
|
|
1434
1441
|
ids
|
|
1435
1442
|
)
|
|
@@ -1437,6 +1444,7 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
|
|
|
1437
1444
|
}
|
|
1438
1445
|
}
|
|
1439
1446
|
break;
|
|
1447
|
+
}
|
|
1440
1448
|
|
|
1441
1449
|
case "dynamic-reexport": {
|
|
1442
1450
|
const ignored = mode.hidden
|
|
@@ -191,7 +191,7 @@ class HarmonyImportDependency extends ModuleDependency {
|
|
|
191
191
|
|
|
192
192
|
let importVar = importVarMap.get(importedModule);
|
|
193
193
|
if (importVar) return importVar;
|
|
194
|
-
importVar = `${Template.toIdentifier(
|
|
194
|
+
importVar = `${Template.toIdentifier(this.userRequest)}__WEBPACK_${
|
|
195
195
|
isDeferred ? "DEFERRED_" : ""
|
|
196
196
|
}IMPORTED_MODULE_${importVarMap.size}__`;
|
|
197
197
|
importVarMap.set(importedModule, importVar);
|
|
@@ -14,6 +14,7 @@ const memoize = require("../util/memoize");
|
|
|
14
14
|
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
|
15
15
|
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
|
|
16
16
|
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
|
|
17
|
+
/** @typedef {import("./CommonJsFullRequireDependency")} CommonJsFullRequireDependency */
|
|
17
18
|
/** @typedef {import("./CommonJsRequireDependency")} CommonJsRequireDependency */
|
|
18
19
|
/** @typedef {import("./HarmonyEvaluatedImportSpecifierDependency")} HarmonyEvaluatedImportSpecifierDependency */
|
|
19
20
|
/** @typedef {import("./HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */
|
|
@@ -29,7 +30,7 @@ const memoize = require("../util/memoize");
|
|
|
29
30
|
/** @typedef {["&&" | "||" | "??", GuardFormula, GuardFormula]} GuardLogical */
|
|
30
31
|
/** @typedef {GuardAtom | GuardPresenceAtom | GuardUnknown | GuardNot | GuardLogical} GuardFormula */
|
|
31
32
|
/** @typedef {{ formula: GuardFormula, value: boolean }} DependencyGuard branch guard: the dependency is live only when the formula evaluates to `value` */
|
|
32
|
-
/** @typedef {HarmonyImportSpecifierDependency | CommonJsRequireDependency | ImportDependency} GuardableDependency */
|
|
33
|
+
/** @typedef {HarmonyImportSpecifierDependency | CommonJsRequireDependency | CommonJsFullRequireDependency | ImportDependency} GuardableDependency */
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* A guard frame pushed onto `parser.state.guardStack` for the duration of one
|
|
@@ -32,6 +32,7 @@ const { ImportPhaseUtils } = require("./ImportPhase");
|
|
|
32
32
|
/** @typedef {import("../Module")} Module */
|
|
33
33
|
/** @typedef {import("../Module").BuildMeta} BuildMeta */
|
|
34
34
|
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
|
35
|
+
/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
|
|
35
36
|
/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
|
|
36
37
|
/** @typedef {import("../errors/WebpackError")} WebpackError */
|
|
37
38
|
/** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperties} DestructuringAssignmentProperties */
|
|
@@ -475,7 +476,8 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
|
|
|
475
476
|
dep,
|
|
476
477
|
source,
|
|
477
478
|
templateContext,
|
|
478
|
-
trimmedIds
|
|
479
|
+
trimmedIds,
|
|
480
|
+
connection
|
|
479
481
|
);
|
|
480
482
|
if (dep.shorthand) {
|
|
481
483
|
source.insert(trimmedRangeEnd, `: ${exportExpr}`);
|
|
@@ -521,13 +523,14 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
|
|
|
521
523
|
});
|
|
522
524
|
}
|
|
523
525
|
);
|
|
526
|
+
// loop-invariant: resolve the imported module's exports info once
|
|
527
|
+
const destructuredExportsInfo = moduleGraph.getExportsInfo(
|
|
528
|
+
/** @type {Module} */ (moduleGraph.getModule(dep))
|
|
529
|
+
);
|
|
524
530
|
for (const { ids, shorthand, range } of replacementsInDestructuring) {
|
|
525
531
|
/** @type {Ids} */
|
|
526
532
|
const concatedIds = [...prefixedIds, ...ids];
|
|
527
|
-
const
|
|
528
|
-
const used = moduleGraph
|
|
529
|
-
.getExportsInfo(module)
|
|
530
|
-
.getUsedName(concatedIds, runtime);
|
|
533
|
+
const used = destructuredExportsInfo.getUsedName(concatedIds, runtime);
|
|
531
534
|
if (!used) {
|
|
532
535
|
return;
|
|
533
536
|
} else if (used instanceof InlinedUsedName) {
|
|
@@ -559,12 +562,12 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
|
|
|
559
562
|
* @param {ReplaceSource} source source
|
|
560
563
|
* @param {DependencyTemplateContext} templateContext context
|
|
561
564
|
* @param {Ids} ids ids
|
|
565
|
+
* @param {ModuleGraphConnection | undefined} connection the resolved connection for dep
|
|
562
566
|
* @returns {string} generated code
|
|
563
567
|
*/
|
|
564
|
-
_getCodeForIds(dep, source, templateContext, ids) {
|
|
568
|
+
_getCodeForIds(dep, source, templateContext, ids, connection) {
|
|
565
569
|
const { moduleGraph, module, runtime, concatenationScope } =
|
|
566
570
|
templateContext;
|
|
567
|
-
const connection = moduleGraph.getConnection(dep);
|
|
568
571
|
/** @type {string} */
|
|
569
572
|
let exportExpr;
|
|
570
573
|
|
|
@@ -25,11 +25,21 @@ const { getUndoPath } = require("../util/identifier");
|
|
|
25
25
|
/** @typedef {import("../ChunkGraph")} ChunkGraph */
|
|
26
26
|
/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
|
|
27
27
|
|
|
28
|
+
const createCompilationHooks = () => ({
|
|
29
|
+
/**
|
|
30
|
+
* @type {SyncWaterfallHook<[string, Chunk]>}
|
|
31
|
+
* @since 5.41.0
|
|
32
|
+
*/
|
|
33
|
+
linkPreload: new SyncWaterfallHook(["source", "chunk"]),
|
|
34
|
+
/**
|
|
35
|
+
* @type {SyncWaterfallHook<[string, Chunk]>}
|
|
36
|
+
* @since 5.41.0
|
|
37
|
+
*/
|
|
38
|
+
linkPrefetch: new SyncWaterfallHook(["source", "chunk"])
|
|
39
|
+
});
|
|
40
|
+
|
|
28
41
|
/**
|
|
29
|
-
*
|
|
30
|
-
* @typedef {object} JsonpCompilationPluginHooks
|
|
31
|
-
* @property {SyncWaterfallHook<[string, Chunk]>} linkPreload
|
|
32
|
-
* @property {SyncWaterfallHook<[string, Chunk]>} linkPrefetch
|
|
42
|
+
* @typedef {ReturnType<typeof createCompilationHooks>} JsonpCompilationPluginHooks
|
|
33
43
|
*/
|
|
34
44
|
|
|
35
45
|
class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
|
|
@@ -438,11 +448,7 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
|
|
|
438
448
|
}
|
|
439
449
|
|
|
440
450
|
ModuleChunkLoadingRuntimeModule.getCompilationHooks = createHooksRegistry(
|
|
441
|
-
|
|
442
|
-
/** @type {JsonpCompilationPluginHooks} */ ({
|
|
443
|
-
linkPreload: new SyncWaterfallHook(["source", "chunk"]),
|
|
444
|
-
linkPrefetch: new SyncWaterfallHook(["source", "chunk"])
|
|
445
|
-
})
|
|
451
|
+
createCompilationHooks
|
|
446
452
|
);
|
|
447
453
|
|
|
448
454
|
module.exports = ModuleChunkLoadingRuntimeModule;
|
|
@@ -94,7 +94,9 @@ module.exports = (options) => (compiler, callback) => {
|
|
|
94
94
|
if (timer.unref) timer.unref();
|
|
95
95
|
idleTimers.add(timer);
|
|
96
96
|
});
|
|
97
|
-
|
|
97
|
+
// Not all runtimes expose `setNoDelay` on the request socket (e.g. Deno's
|
|
98
|
+
// HTTP server); it's only a latency optimization, so skip it when absent.
|
|
99
|
+
if (req.socket.setNoDelay) req.socket.setNoDelay(true);
|
|
98
100
|
res.writeHead(200, {
|
|
99
101
|
"content-type": "text/event-stream",
|
|
100
102
|
"Access-Control-Allow-Origin": "*",
|
|
@@ -168,12 +170,25 @@ module.exports = (options) => (compiler, callback) => {
|
|
|
168
170
|
idleTimers.clear();
|
|
169
171
|
// Removing the listener is a workaround for a memory leak in node.js
|
|
170
172
|
server.off("request", requestListener);
|
|
171
|
-
server.close((err) => {
|
|
172
|
-
callback(err);
|
|
173
|
-
});
|
|
174
173
|
for (const socket of sockets) {
|
|
175
174
|
socket.destroy(new Error("Server is disposing"));
|
|
176
175
|
}
|
|
176
|
+
// Some runtimes (e.g. Deno) don't emit "connection", so `sockets`
|
|
177
|
+
// misses the open SSE connections and `server.close` would hang;
|
|
178
|
+
// force-close everything before waiting for it.
|
|
179
|
+
if (server.closeAllConnections) server.closeAllConnections();
|
|
180
|
+
server.close((err) => {
|
|
181
|
+
// `closeAllConnections()` already stops the server on some runtimes
|
|
182
|
+
// (e.g. Bun), so `close` then reports ERR_SERVER_NOT_RUNNING; the
|
|
183
|
+
// server is closed either way, so that's not a dispose failure.
|
|
184
|
+
callback(
|
|
185
|
+
err &&
|
|
186
|
+
/** @type {NodeJS.ErrnoException} */ (err).code !==
|
|
187
|
+
"ERR_SERVER_NOT_RUNNING"
|
|
188
|
+
? err
|
|
189
|
+
: null
|
|
190
|
+
);
|
|
191
|
+
});
|
|
177
192
|
},
|
|
178
193
|
module(originalModule) {
|
|
179
194
|
const key = `${encodeURIComponent(
|
|
@@ -161,6 +161,7 @@ const metaIsCsp = (attrs) => {
|
|
|
161
161
|
/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
|
|
162
162
|
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
|
|
163
163
|
/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
|
|
164
|
+
/** @typedef {import("../Module")} Module */
|
|
164
165
|
/** @typedef {import("../Module").SourceType} SourceType */
|
|
165
166
|
/** @typedef {import("../Module").SourceTypes} SourceTypes */
|
|
166
167
|
/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
|
|
@@ -201,6 +202,27 @@ const getChunksById = (compilation) => {
|
|
|
201
202
|
return chunksById;
|
|
202
203
|
};
|
|
203
204
|
|
|
205
|
+
/** @type {WeakMap<Compilation, Map<string, Module>>} */
|
|
206
|
+
const modulesByIdentifierCache = new WeakMap();
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* `module.identifier()` → module lookup, memoized per compilation so the asset
|
|
210
|
+
* URL sentinel resolver doesn't re-scan the whole module graph per HTML module.
|
|
211
|
+
* @param {Compilation} compilation compilation
|
|
212
|
+
* @returns {Map<string, Module>} modules keyed by identifier
|
|
213
|
+
*/
|
|
214
|
+
const getModulesByIdentifier = (compilation) => {
|
|
215
|
+
let modulesByIdentifier = modulesByIdentifierCache.get(compilation);
|
|
216
|
+
if (modulesByIdentifier === undefined) {
|
|
217
|
+
modulesByIdentifier = new Map();
|
|
218
|
+
for (const module of compilation.modules) {
|
|
219
|
+
modulesByIdentifier.set(module.identifier(), module);
|
|
220
|
+
}
|
|
221
|
+
modulesByIdentifierCache.set(compilation, modulesByIdentifier);
|
|
222
|
+
}
|
|
223
|
+
return modulesByIdentifier;
|
|
224
|
+
};
|
|
225
|
+
|
|
204
226
|
// Hoisted so `resolveChunkUrlSentinels` (per chunk × module) doesn't allocate a
|
|
205
227
|
// fresh `RegExp` each call. `String#replace` resets `lastIndex`, so sharing the
|
|
206
228
|
// global-flag instance is safe under these synchronous, non-reentrant calls.
|
|
@@ -413,9 +435,7 @@ class HtmlGenerator extends Generator {
|
|
|
413
435
|
*/
|
|
414
436
|
static resolveAssetUrlSentinels(content, compilation) {
|
|
415
437
|
if (!content.includes("__WEBPACK_HTML_ASSET_URL__")) return content;
|
|
416
|
-
|
|
417
|
-
const byIdentifier = new Map();
|
|
418
|
-
for (const m of compilation.modules) byIdentifier.set(m.identifier(), m);
|
|
438
|
+
const byIdentifier = getModulesByIdentifier(compilation);
|
|
419
439
|
const codeGenerationResults =
|
|
420
440
|
/** @type {import("../CodeGenerationResults")} */
|
|
421
441
|
(compilation.codeGenerationResults);
|
|
@@ -72,12 +72,36 @@ const { escapeAttribute } = require("./syntax");
|
|
|
72
72
|
* @property {boolean=} remove set true to delete the whole element
|
|
73
73
|
*/
|
|
74
74
|
/** @typedef {{ outputName: string, html: string }} HtmlTransformTagsContext */
|
|
75
|
+
|
|
76
|
+
const createCompilationHooks = () => ({
|
|
77
|
+
/**
|
|
78
|
+
* Called with the list of extra tags to inject into each page (initially empty) plus the current HTML; push `HtmlTagDescriptor`s and return the list — webpack serializes and places them by `injectTo`. A structured alternative to the string-level `transformHtml` for adding tags; runs before CSP so injected inline tags are hashed.
|
|
79
|
+
* @type {AsyncSeriesWaterfallHook<[HtmlTagDescriptor[], HtmlInjectTagsContext]>}
|
|
80
|
+
* @since 5.109.0
|
|
81
|
+
*/
|
|
82
|
+
injectTags: new AsyncSeriesWaterfallHook(["tags", "context"]),
|
|
83
|
+
/**
|
|
84
|
+
* Called with the page's `<script>`/`<link>`/`<style>`/`<meta>` tags (webpack's own and any injected) as mutable descriptors; mutate `attrs` (add a `nonce`/`data-*`, switch `defer`↔`async`, …), set `remove: true`, or change `injectTo` to move a tag between `<head>` and `<body>`, and webpack rewrites the changed tags. Add new tags with `injectTags` instead.
|
|
85
|
+
* @type {AsyncSeriesHook<[HtmlMutableTag[], HtmlTransformTagsContext]>}
|
|
86
|
+
* @since 5.109.0
|
|
87
|
+
*/
|
|
88
|
+
transformTags: new AsyncSeriesHook(["tags", "context"]),
|
|
89
|
+
/**
|
|
90
|
+
* Called with each emitted page's final HTML (all sentinels resolved) just before it is written; return the (possibly transformed) HTML — e.g. to minify, inject a CSP meta, or rewrite tags.
|
|
91
|
+
* @type {AsyncSeriesWaterfallHook<[string, HtmlTransformHtmlContext]>}
|
|
92
|
+
* @since 5.109.0
|
|
93
|
+
*/
|
|
94
|
+
transformHtml: new AsyncSeriesWaterfallHook(["html", "context"]),
|
|
95
|
+
/**
|
|
96
|
+
* Called once each page's HTML asset has been finalized — a post-emit notification (nothing to return).
|
|
97
|
+
* @type {AsyncSeriesHook<[HtmlEmittedContext]>}
|
|
98
|
+
* @since 5.109.0
|
|
99
|
+
*/
|
|
100
|
+
htmlEmitted: new AsyncSeriesHook(["context"])
|
|
101
|
+
});
|
|
102
|
+
|
|
75
103
|
/**
|
|
76
|
-
* @typedef {
|
|
77
|
-
* @property {AsyncSeriesWaterfallHook<[HtmlTagDescriptor[], HtmlInjectTagsContext]>} injectTags called with the list of extra tags to inject into each page (initially empty) plus the current HTML; push `HtmlTagDescriptor`s and return the list — webpack serializes and places them by `injectTo`. A structured alternative to the string-level `transformHtml` for adding tags; runs before CSP so injected inline tags are hashed
|
|
78
|
-
* @property {AsyncSeriesHook<[HtmlMutableTag[], HtmlTransformTagsContext]>} transformTags called with the page's `<script>`/`<link>`/`<style>`/`<meta>` tags (webpack's own and any injected) as mutable descriptors; mutate `attrs` (add a `nonce`/`data-*`, switch `defer`↔`async`, …), set `remove: true`, or change `injectTo` to move a tag between `<head>` and `<body>`, and webpack rewrites the changed tags. Add new tags with `injectTags` instead
|
|
79
|
-
* @property {AsyncSeriesWaterfallHook<[string, HtmlTransformHtmlContext]>} transformHtml called with each emitted page's final HTML (all sentinels resolved) just before it is written; return the (possibly transformed) HTML — e.g. to minify, inject a CSP meta, or rewrite tags
|
|
80
|
-
* @property {AsyncSeriesHook<[HtmlEmittedContext]>} htmlEmitted called once each page's HTML asset has been finalized — a post-emit notification (nothing to return)
|
|
104
|
+
* @typedef {ReturnType<typeof createCompilationHooks>} HtmlCompilationHooks
|
|
81
105
|
*/
|
|
82
106
|
|
|
83
107
|
const PLUGIN_NAME = "HtmlModulesPlugin";
|
|
@@ -1099,13 +1123,7 @@ class HtmlModulesPlugin {
|
|
|
1099
1123
|
* @returns {HtmlCompilationHooks} the hooks
|
|
1100
1124
|
*/
|
|
1101
1125
|
HtmlModulesPlugin.getCompilationHooks = createHooksRegistry(
|
|
1102
|
-
|
|
1103
|
-
/** @type {HtmlCompilationHooks} */ ({
|
|
1104
|
-
injectTags: new AsyncSeriesWaterfallHook(["tags", "context"]),
|
|
1105
|
-
transformTags: new AsyncSeriesHook(["tags", "context"]),
|
|
1106
|
-
transformHtml: new AsyncSeriesWaterfallHook(["html", "context"]),
|
|
1107
|
-
htmlEmitted: new AsyncSeriesHook(["context"])
|
|
1108
|
-
})
|
|
1126
|
+
createCompilationHooks
|
|
1109
1127
|
);
|
|
1110
1128
|
|
|
1111
1129
|
module.exports = HtmlModulesPlugin;
|