webpack 5.110.3 → 5.111.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 +5 -0
- package/lib/APIPlugin.js +23 -7
- package/lib/AutomaticPrefetchPlugin.js +1 -1
- package/lib/Cache.js +8 -3
- package/lib/CacheFacade.js +1 -1
- package/lib/CircularModulesPlugin.js +157 -55
- package/lib/CleanPlugin.js +2 -2
- package/lib/Compilation.js +320 -302
- package/lib/Compiler.js +209 -46
- package/lib/ContextModule.js +17 -81
- package/lib/ContextModuleFactory.js +1 -1
- package/lib/CopyPlugin.js +1054 -0
- package/lib/DefinePlugin.js +24 -8
- package/lib/ExternalModule.js +41 -14
- package/lib/FileSystemInfo.js +17 -14
- package/lib/FlagDependencyExportsPlugin.js +45 -21
- package/lib/HotModuleReplacementPlugin.js +53 -7
- package/lib/JavascriptMetaInfoPlugin.js +5 -3
- package/lib/MainTemplate.js +5 -1
- package/lib/Module.js +16 -7
- package/lib/MultiCompiler.js +1 -1
- package/lib/MultiWatching.js +1 -1
- package/lib/NormalModule.js +45 -12
- package/lib/NormalModuleFactory.js +1 -1
- package/lib/RuntimeGlobals.js +21 -7
- package/lib/RuntimeModule.js +28 -12
- package/lib/RuntimePlugin.js +30 -3
- package/lib/RuntimeTemplate.js +780 -475
- package/lib/SourceMapDevToolPlugin.js +1 -1
- package/lib/Watching.js +9 -0
- package/lib/WebpackOptionsApply.js +84 -91
- package/lib/asset/AssetGenerator.js +25 -8
- package/lib/asset/AssetModule.js +3 -0
- package/lib/asset/WebManifestParser.js +7 -5
- package/lib/cache/AddBuildDependenciesPlugin.js +33 -4
- package/lib/cache/IdleFileCachePlugin.js +2 -2
- package/lib/cache/PackFileCacheStrategy.js +14 -1
- package/lib/config/browserslistTargetHandler.js +19 -0
- package/lib/config/defaults.js +86 -50
- package/lib/config/normalization.js +82 -12
- package/lib/config/target.js +10 -0
- package/lib/container/ContainerReferencePlugin.js +6 -0
- package/lib/container/RemoteRuntimeModule.js +9 -0
- package/lib/container/declaredRemotes.js +39 -0
- package/lib/css/CssGenerator.js +8 -0
- package/lib/css/CssInjectStyleRuntimeModule.js +9 -0
- package/lib/css/CssLoadingRuntimeModule.js +94 -36
- package/lib/css/CssModule.js +1 -1
- package/lib/css/CssModulesPlugin.js +7 -6
- package/lib/css/CssParser.js +144 -11
- package/lib/css/CssServerStylesRuntimeModule.js +9 -0
- package/lib/css/cssMinify.js +11 -3
- package/lib/css/data.js +2814 -678
- package/lib/css/syntax.js +4082 -248
- package/lib/debug/ProfilingPlugin.js +4 -0
- package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -3
- package/lib/dependencies/AMDRuntimeModules.js +18 -0
- package/lib/dependencies/CommonJsExportRequireDependency.js +3 -1
- package/lib/dependencies/CommonJsExportsParserPlugin.js +12 -13
- package/lib/dependencies/CommonJsImportsParserPlugin.js +1 -0
- package/lib/dependencies/CommonJsPlugin.js +19 -3
- package/lib/dependencies/CommonJsRequireDependency.js +14 -5
- package/lib/dependencies/CssIcssExportDependency.js +7 -1
- package/lib/dependencies/HarmonyCompatibilityDependency.js +58 -4
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +8 -3
- package/lib/dependencies/HarmonyExportExpressionDependency.js +44 -29
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +71 -13
- package/lib/dependencies/HarmonyExportInitFragment.js +99 -19
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +18 -30
- package/lib/dependencies/HarmonyImportBareSideEffectDependency.js +59 -0
- package/lib/dependencies/HarmonyImportDependency.js +6 -1
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +8 -1
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +24 -1
- package/lib/dependencies/HarmonyModulesPlugin.js +20 -0
- package/lib/dependencies/HtmlEntryDependency.js +50 -0
- package/lib/dependencies/ImportMetaMainDependency.js +104 -0
- package/lib/dependencies/ImportMetaPlugin.js +59 -15
- package/lib/dependencies/SystemRuntimeModule.js +9 -0
- package/lib/dependencies/WorkerDependency.js +1 -2
- package/lib/dependencies/WorkletDependency.js +1 -2
- package/lib/dll/DelegatedModule.js +18 -1
- package/lib/dll/DllReferencePlugin.js +11 -8
- package/lib/dll/LibManifestPlugin.js +1 -1
- package/lib/errors/AnalyzableBailoutsWarning.js +41 -0
- package/lib/errors/DuplicateModulesWarning.js +12 -7
- package/lib/errors/EmptyCopyPatternWarning.js +26 -0
- package/lib/errors/ExternalStarReexportError.js +44 -0
- package/lib/errors/MissingSourceMapsWarning.js +36 -0
- package/lib/errors/ModuleParseError.js +2 -1
- package/lib/errors/UnusedAssetsWarning.js +36 -0
- package/lib/errors/UnusedFederationWarning.js +35 -0
- package/lib/errors/UnusedModulesWarning.js +38 -0
- package/lib/esm/ExportWebpackRequireRuntimeModule.js +9 -0
- package/lib/esm/ModuleChunkFormatPlugin.js +28 -3
- package/lib/esm/ModuleChunkLoadingPlugin.js +30 -11
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +92 -60
- package/lib/hmr/HotModuleReplacement.runtime.js +8 -2
- package/lib/hmr/HotModuleReplacementRuntimeModule.js +9 -0
- package/lib/html/HtmlGenerator.js +11 -5
- package/lib/html/HtmlModulesPlugin.js +331 -62
- package/lib/html/HtmlParser.js +13 -6
- package/lib/html/builtinEmbeddedRenderer.js +107 -0
- package/lib/html/data.js +121 -7
- package/lib/html/htmlMinify.js +84 -113
- package/lib/html/syntax.js +763 -426
- package/lib/ids/HashedModuleIdsPlugin.js +2 -1
- package/lib/index.js +3 -0
- package/lib/javascript/JavascriptModule.js +1 -0
- package/lib/javascript/JavascriptModulesPlugin.js +52 -24
- package/lib/javascript/JavascriptParser.js +1255 -728
- package/lib/javascript/StartupHelpers.js +27 -3
- package/lib/javascript/data.js +172 -0
- package/lib/javascript/grammar.js +5546 -0
- package/lib/javascript/parser.js +1494 -0
- package/lib/javascript/regexp.js +1762 -0
- package/lib/javascript/regexpData.js +51 -0
- package/lib/javascript/syntax.js +8696 -5225
- package/lib/library/ModuleLibraryPlugin.js +116 -5
- package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -0
- package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -0
- package/lib/optimize/ConcatenatedModule.js +97 -20
- package/lib/optimize/ConstExportsPlugin.js +50 -39
- package/lib/optimize/InlineExports.js +20 -123
- package/lib/optimize/MangleExportsPlugin.js +10 -0
- package/lib/optimize/ModuleConcatenationPlugin.js +24 -1
- package/lib/optimize/RealContentHashPlugin.js +68 -9
- package/lib/optimize/SideEffectsFlagPlugin.js +17 -9
- package/lib/performance/AnalyzableBailoutsPlugin.js +115 -0
- package/lib/performance/CacheEffectivenessPlugin.js +4 -3
- package/lib/performance/DuplicateModulesPlugin.js +57 -13
- package/lib/performance/EvalUsagePlugin.js +5 -2
- package/lib/performance/MissingSourceMapsPlugin.js +115 -0
- package/lib/performance/PureAnnotationsPlugin.js +6 -3
- package/lib/performance/TopLevelThisPlugin.js +5 -4
- package/lib/performance/UnusedAssetsPlugin.js +109 -0
- package/lib/performance/UnusedFederationPlugin.js +147 -0
- package/lib/performance/UnusedModulesPlugin.js +141 -0
- package/lib/performance/UnusedReexportsPlugin.js +1 -55
- package/lib/performance/isOnlyReexported.js +65 -0
- package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +25 -5
- package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +2 -0
- package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +9 -0
- package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +9 -0
- package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +9 -0
- package/lib/prefetch/ResourceHintPlugin.js +1 -2
- package/lib/prefetch/ResourceHintRuntimeModule.js +9 -0
- package/lib/prefetch/StartupAssetHintRuntimeModule.js +9 -0
- package/lib/rules/RuleSetCompiler.js +211 -4
- package/lib/runtime/AsyncModuleRuntimeModule.js +100 -66
- package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -0
- package/lib/runtime/BaseUriRuntimeModule.js +9 -0
- package/lib/runtime/ChunkNameRuntimeModule.js +9 -0
- package/lib/runtime/EnsureChunkRuntimeModule.js +35 -16
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +9 -0
- package/lib/runtime/GetFullHashRuntimeModule.js +9 -0
- package/lib/runtime/GetMainFilenameRuntimeModule.js +9 -0
- package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +9 -0
- package/lib/runtime/GlobalRuntimeModule.js +9 -0
- package/lib/runtime/HasOwnPropertyRuntimeModule.js +9 -0
- package/lib/runtime/HelperRuntimeModule.js +10 -0
- package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +330 -219
- package/lib/runtime/NonceRuntimeModule.js +9 -0
- package/lib/runtime/OnChunksLoadedRuntimeModule.js +67 -20
- package/lib/runtime/PublicPathRuntimeModule.js +9 -0
- package/lib/runtime/RuntimeIdRuntimeModule.js +9 -0
- package/lib/runtime/SpecNamespaceObjectRuntimeModule.js +90 -0
- package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +9 -0
- package/lib/runtime/StartupEntrypointRuntimeModule.js +9 -0
- package/lib/runtime/SystemContextRuntimeModule.js +9 -0
- package/lib/runtime/ToBinaryRuntimeModule.js +9 -0
- package/lib/serialization/ObjectMiddleware.js +138 -106
- package/lib/sharing/ConsumeSharedPlugin.js +12 -0
- package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -0
- package/lib/sharing/ShareRuntimeModule.js +9 -0
- package/lib/sharing/declaredShared.js +47 -0
- package/lib/stats/DefaultStatsFactoryPlugin.js +3 -1
- package/lib/stats/DefaultStatsPrinterPlugin.js +3 -0
- package/lib/util/SourceProcessor.js +76 -69
- package/lib/util/async.js +292 -0
- package/lib/util/buildDiagnostics.js +69 -0
- package/lib/util/fs.js +27 -1
- package/lib/util/handlerKeys.js +40 -0
- package/lib/util/identifier.js +20 -0
- package/lib/util/internalSerializables.js +4 -0
- package/lib/util/registerExternalSerializer.js +6 -45
- package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +9 -0
- package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +9 -0
- package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +9 -0
- package/lib/web/JsonpChunkLoadingRuntimeModule.js +36 -0
- package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +19 -0
- package/package.json +22 -16
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +379 -66
- package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
- package/schemas/plugins/ManifestPlugin.check.js +1 -1
- package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
- package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
- package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
- package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
- package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
- package/schemas/plugins/dll/DllReferencePlugin.check.js +1 -1
- package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +1 -1
- package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
- package/types.d.ts +1414 -314
- package/lib/dependencies/ExportBindingInitFragment.js +0 -191
- package/lib/errors/EntrypointOverlapWarning.js +0 -45
- package/lib/performance/EntrypointOverlapPlugin.js +0 -122
|
@@ -17,6 +17,7 @@ const { propertyAccess } = require("../util/property");
|
|
|
17
17
|
/** @import ModuleGraph from "../ModuleGraph" */
|
|
18
18
|
/** @import Module from "../Module" */
|
|
19
19
|
/** @import { RuntimeSpec } from "../util/runtime" */
|
|
20
|
+
/** @import Hash from "../util/Hash" */
|
|
20
21
|
|
|
21
22
|
const MAX_INLINE_BYTES = 6;
|
|
22
23
|
|
|
@@ -60,6 +61,14 @@ class InlinedValue {
|
|
|
60
61
|
return `(${comment}${this.renderLiteral()})`;
|
|
61
62
|
}
|
|
62
63
|
|
|
64
|
+
/**
|
|
65
|
+
* @param {InlinedValue} other other inlined value
|
|
66
|
+
* @returns {boolean} true when kind and value match
|
|
67
|
+
*/
|
|
68
|
+
equals(other) {
|
|
69
|
+
return this.kind === other.kind && this.value === other.value;
|
|
70
|
+
}
|
|
71
|
+
|
|
63
72
|
/**
|
|
64
73
|
* @param {ObjectSerializerContext} context context
|
|
65
74
|
*/
|
|
@@ -96,12 +105,21 @@ class InlinedUsedName {
|
|
|
96
105
|
}
|
|
97
106
|
|
|
98
107
|
/**
|
|
99
|
-
* @param {string} comment leading comment text
|
|
108
|
+
* @param {string=} comment leading comment text
|
|
100
109
|
* @returns {string} rendered literal with property access suffix
|
|
101
110
|
*/
|
|
102
|
-
render(comment) {
|
|
111
|
+
render(comment = "") {
|
|
103
112
|
return this.value.render(comment) + propertyAccess(this.suffix);
|
|
104
113
|
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Updates the hash with the data contributed by this instance.
|
|
117
|
+
* @param {Hash} hash the hash used to track dependencies
|
|
118
|
+
* @returns {void}
|
|
119
|
+
*/
|
|
120
|
+
updateHash(hash) {
|
|
121
|
+
hash.update(this.render());
|
|
122
|
+
}
|
|
105
123
|
}
|
|
106
124
|
|
|
107
125
|
/**
|
|
@@ -172,131 +190,10 @@ const isExportInlined = (moduleGraph, module, ids, runtime) => {
|
|
|
172
190
|
return moduleGraph.getExportsInfo(module).hasInlinedUsedName(ids, runtime);
|
|
173
191
|
};
|
|
174
192
|
|
|
175
|
-
/**
|
|
176
|
-
* Collects, by an iterative Tarjan pass, the modules a cycle peer may read in
|
|
177
|
-
* their dead zone. A cycle of bare side-effect imports still inlines.
|
|
178
|
-
* @param {ModuleGraph} moduleGraph module graph
|
|
179
|
-
* @param {Iterable<Module>} modules all modules of the compilation
|
|
180
|
-
* @returns {Set<Module>} modules whose exports must not be inlined
|
|
181
|
-
*/
|
|
182
|
-
const findModulesInCycles = (moduleGraph, modules) => {
|
|
183
|
-
const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
|
|
184
|
-
const HarmonyImportSideEffectDependency = require("../dependencies/HarmonyImportSideEffectDependency");
|
|
185
|
-
|
|
186
|
-
/** @type {Set<Module>} */
|
|
187
|
-
const inCycle = new Set();
|
|
188
|
-
/** @type {[Module, Module][]} */
|
|
189
|
-
const bindingReads = [];
|
|
190
|
-
/** @type {Map<Module, number>} */
|
|
191
|
-
const componentOf = new Map();
|
|
192
|
-
let nextComponent = 0;
|
|
193
|
-
/** @type {Map<Module, number>} */
|
|
194
|
-
const index = new Map();
|
|
195
|
-
/** @type {Map<Module, number>} */
|
|
196
|
-
const low = new Map();
|
|
197
|
-
/** @type {Set<Module>} */
|
|
198
|
-
const onStack = new Set();
|
|
199
|
-
/** @type {Module[]} */
|
|
200
|
-
const componentStack = [];
|
|
201
|
-
let counter = 0;
|
|
202
|
-
/**
|
|
203
|
-
* @param {Module} module the module
|
|
204
|
-
* @returns {Module[]} modules it imports, self included when self-importing
|
|
205
|
-
*/
|
|
206
|
-
const targetsOf = (module) => {
|
|
207
|
-
const connections = moduleGraph.getOutgoingConnectionsByModule(module);
|
|
208
|
-
if (!connections) return [];
|
|
209
|
-
/** @type {Module[]} */
|
|
210
|
-
const targets = [];
|
|
211
|
-
for (const [target, moduleConnections] of connections) {
|
|
212
|
-
if (
|
|
213
|
-
!target ||
|
|
214
|
-
!moduleConnections.some(
|
|
215
|
-
(c) => c.dependency instanceof HarmonyImportDependency
|
|
216
|
-
)
|
|
217
|
-
) {
|
|
218
|
-
continue;
|
|
219
|
-
}
|
|
220
|
-
// Anything but a bare side-effect import may observe the binding.
|
|
221
|
-
if (
|
|
222
|
-
moduleConnections.some(
|
|
223
|
-
(c) =>
|
|
224
|
-
c.dependency instanceof HarmonyImportDependency &&
|
|
225
|
-
!(c.dependency instanceof HarmonyImportSideEffectDependency)
|
|
226
|
-
)
|
|
227
|
-
) {
|
|
228
|
-
bindingReads.push([module, target]);
|
|
229
|
-
}
|
|
230
|
-
targets.push(target);
|
|
231
|
-
}
|
|
232
|
-
return targets;
|
|
233
|
-
};
|
|
234
|
-
/** @type {{ node: Module, targets: Module[], i: number }[]} */
|
|
235
|
-
const work = [];
|
|
236
|
-
/**
|
|
237
|
-
* @param {Module} node node to open
|
|
238
|
-
*/
|
|
239
|
-
const open = (node) => {
|
|
240
|
-
index.set(node, counter);
|
|
241
|
-
low.set(node, counter);
|
|
242
|
-
counter++;
|
|
243
|
-
componentStack.push(node);
|
|
244
|
-
onStack.add(node);
|
|
245
|
-
work.push({ node, targets: targetsOf(node), i: 0 });
|
|
246
|
-
};
|
|
247
|
-
for (const seed of modules) {
|
|
248
|
-
if (index.has(seed)) continue;
|
|
249
|
-
open(seed);
|
|
250
|
-
while (work.length > 0) {
|
|
251
|
-
const frame = work[work.length - 1];
|
|
252
|
-
if (frame.i < frame.targets.length) {
|
|
253
|
-
const next = frame.targets[frame.i++];
|
|
254
|
-
if (!index.has(next)) {
|
|
255
|
-
open(next);
|
|
256
|
-
} else if (onStack.has(next)) {
|
|
257
|
-
const nodeLow = /** @type {number} */ (low.get(frame.node));
|
|
258
|
-
const nextIndex = /** @type {number} */ (index.get(next));
|
|
259
|
-
if (nextIndex < nodeLow) low.set(frame.node, nextIndex);
|
|
260
|
-
}
|
|
261
|
-
continue;
|
|
262
|
-
}
|
|
263
|
-
work.pop();
|
|
264
|
-
const node = frame.node;
|
|
265
|
-
const nodeLow = /** @type {number} */ (low.get(node));
|
|
266
|
-
if (work.length > 0) {
|
|
267
|
-
const parent = work[work.length - 1].node;
|
|
268
|
-
if (nodeLow < /** @type {number} */ (low.get(parent))) {
|
|
269
|
-
low.set(parent, nodeLow);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
if (nodeLow === index.get(node)) {
|
|
273
|
-
const id = nextComponent++;
|
|
274
|
-
let member;
|
|
275
|
-
do {
|
|
276
|
-
member = /** @type {Module} */ (componentStack.pop());
|
|
277
|
-
onStack.delete(member);
|
|
278
|
-
componentOf.set(member, id);
|
|
279
|
-
} while (member !== node);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
// Reader and target evaluate together exactly when they share a component.
|
|
284
|
-
for (const [origin, target] of bindingReads) {
|
|
285
|
-
if (
|
|
286
|
-
origin === target ||
|
|
287
|
-
componentOf.get(origin) === componentOf.get(target)
|
|
288
|
-
) {
|
|
289
|
-
inCycle.add(target);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
return inCycle;
|
|
293
|
-
};
|
|
294
|
-
|
|
295
193
|
module.exports.InlinedUsedName = InlinedUsedName;
|
|
296
194
|
module.exports.InlinedValue = InlinedValue;
|
|
297
195
|
module.exports.MAX_INLINE_BYTES = MAX_INLINE_BYTES;
|
|
298
196
|
module.exports.enableInlineExports = enableInlineExports;
|
|
299
|
-
module.exports.findModulesInCycles = findModulesInCycles;
|
|
300
197
|
module.exports.isExportInlined = isExportInlined;
|
|
301
198
|
module.exports.isInlineEnabled = isInlineEnabled;
|
|
302
199
|
module.exports.isInlineExportsEnabled = isInlineExportsEnabled;
|
|
@@ -15,6 +15,7 @@ const { assignDeterministicIds } = require("../ids/IdHelpers");
|
|
|
15
15
|
const { compareSelect, compareStringsNumeric } = require("../util/comparators");
|
|
16
16
|
|
|
17
17
|
/** @import Compiler from "../Compiler" */
|
|
18
|
+
/** @import { BuildInfo } from "../Module" */
|
|
18
19
|
/** @import ExportsInfo, { ExportInfo } from "../ExportsInfo" */
|
|
19
20
|
/** @import { UsedNames } from "../util/concatenate" */
|
|
20
21
|
|
|
@@ -184,6 +185,15 @@ class MangleExportsPlugin {
|
|
|
184
185
|
);
|
|
185
186
|
}
|
|
186
187
|
for (const module of modules) {
|
|
188
|
+
// A spec namespace reports the names the module exports, so a
|
|
189
|
+
// module handing one out cannot have them renamed.
|
|
190
|
+
if (
|
|
191
|
+
/** @type {BuildInfo} */
|
|
192
|
+
(module.buildInfo).specNamespaceObject
|
|
193
|
+
) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
|
|
187
197
|
const isNamespace =
|
|
188
198
|
module.buildMeta && module.buildMeta.exportsType === "namespace";
|
|
189
199
|
const exportsInfo = moduleGraph.getExportsInfo(module);
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
8
|
-
const asyncLib = require("neo-async");
|
|
9
8
|
const ChunkGraph = require("../ChunkGraph");
|
|
10
9
|
const Dependency = require("../Dependency");
|
|
11
10
|
const Module = require("../Module");
|
|
@@ -14,6 +13,7 @@ const { JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
|
|
|
14
13
|
const { STAGE_DEFAULT } = require("../OptimizationStages");
|
|
15
14
|
const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
|
|
16
15
|
const { ImportPhaseUtils } = require("../dependencies/ImportPhase");
|
|
16
|
+
const asyncLib = require("../util/async");
|
|
17
17
|
const { compareModulesByIdentifier } = require("../util/comparators");
|
|
18
18
|
const { isCommonJsConcatenationEnabled } = require("../util/concatenate");
|
|
19
19
|
const {
|
|
@@ -28,6 +28,7 @@ const ConcatenatedModule = require("./ConcatenatedModule");
|
|
|
28
28
|
/** @import Chunk from "../Chunk" */
|
|
29
29
|
/** @import Compilation from "../Compilation" */
|
|
30
30
|
/** @import Compiler from "../Compiler" */
|
|
31
|
+
/** @import { JavascriptModuleBuildInfo } from "../javascript/JavascriptModule" */
|
|
31
32
|
/** @import { BuildInfo, BuildMeta } from "../Module" */
|
|
32
33
|
/** @import RequestShortener from "../RequestShortener" */
|
|
33
34
|
/** @import { RuntimeSpec } from "../util/runtime" */
|
|
@@ -235,6 +236,19 @@ class ModuleConcatenationPlugin {
|
|
|
235
236
|
continue;
|
|
236
237
|
}
|
|
237
238
|
|
|
239
|
+
// Concatenation materializes the namespace inline, which would
|
|
240
|
+
// silently drop the spec exotic object the module asked for.
|
|
241
|
+
if (
|
|
242
|
+
/** @type {BuildInfo} */
|
|
243
|
+
(module.buildInfo).specNamespaceObject
|
|
244
|
+
) {
|
|
245
|
+
setBailoutReason(
|
|
246
|
+
module,
|
|
247
|
+
"Module hands out a spec namespace object"
|
|
248
|
+
);
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
|
|
238
252
|
// Module must be in any chunk (we don't want to do useless work)
|
|
239
253
|
if (chunkGraph.getNumberOfModuleChunks(module) === 0) {
|
|
240
254
|
setBailoutReason(module, "Module is not in any chunk");
|
|
@@ -302,6 +316,15 @@ class ModuleConcatenationPlugin {
|
|
|
302
316
|
canBeInner = false;
|
|
303
317
|
}
|
|
304
318
|
|
|
319
|
+
// The root stands in for the whole concatenation, so an
|
|
320
|
+
// expression only an inner module can answer statically rules it out
|
|
321
|
+
if (
|
|
322
|
+
/** @type {JavascriptModuleBuildInfo} */
|
|
323
|
+
(module.buildInfo).moduleConcatenationRootBailout
|
|
324
|
+
) {
|
|
325
|
+
canBeRoot = false;
|
|
326
|
+
}
|
|
327
|
+
|
|
305
328
|
if (deferEnabled && moduleGraph.isDeferred(module)) {
|
|
306
329
|
setInnerBailoutReason(module, "Module is deferred");
|
|
307
330
|
canBeInner = false;
|
|
@@ -187,6 +187,7 @@ const createCompilationHooks = () => ({
|
|
|
187
187
|
* @typedef {object} RealContentHashPluginOptions
|
|
188
188
|
* @property {HashFunction} hashFunction the hash function to use
|
|
189
189
|
* @property {HashDigest} hashDigest the hash digest to use
|
|
190
|
+
* @property {boolean=} onDemand run only where analyzable output marked a name for repair
|
|
190
191
|
*/
|
|
191
192
|
|
|
192
193
|
const PLUGIN_NAME = "RealContentHashPlugin";
|
|
@@ -196,11 +197,13 @@ class RealContentHashPlugin {
|
|
|
196
197
|
* Creates an instance of RealContentHashPlugin.
|
|
197
198
|
* @param {RealContentHashPluginOptions} options options
|
|
198
199
|
*/
|
|
199
|
-
constructor({ hashFunction, hashDigest }) {
|
|
200
|
+
constructor({ hashFunction, hashDigest, onDemand }) {
|
|
200
201
|
/** @type {HashFunction} */
|
|
201
202
|
this._hashFunction = hashFunction;
|
|
202
203
|
/** @type {HashDigest} */
|
|
203
204
|
this._hashDigest = hashDigest;
|
|
205
|
+
/** @type {boolean} */
|
|
206
|
+
this._onDemand = Boolean(onDemand);
|
|
204
207
|
}
|
|
205
208
|
|
|
206
209
|
/**
|
|
@@ -223,6 +226,14 @@ class RealContentHashPlugin {
|
|
|
223
226
|
stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_HASH
|
|
224
227
|
},
|
|
225
228
|
async () => {
|
|
229
|
+
// Set by the deferred fill where a baked name would leave a hashed name
|
|
230
|
+
// stale; only then is `[chunkhash]` repaired rather than left as named.
|
|
231
|
+
const repairing = compilation.runtimeTemplate.needsAnalyzableRepair();
|
|
232
|
+
if (this._onDemand && !repairing) return;
|
|
233
|
+
// On demand, only a name the fill left stale moves, and whatever names it.
|
|
234
|
+
const repairedAssets = this._onDemand
|
|
235
|
+
? compilation.runtimeTemplate.analyzableRepairedAssets()
|
|
236
|
+
: undefined;
|
|
226
237
|
const assets = compilation.getAssets();
|
|
227
238
|
/** @type {AssetInfoForRealContentHash[]} */
|
|
228
239
|
const assetsWithInfo = [];
|
|
@@ -238,6 +249,7 @@ class RealContentHashPlugin {
|
|
|
238
249
|
/** @type {Hashes} */
|
|
239
250
|
const hashes = new Set();
|
|
240
251
|
addToList(info.contenthash, hashes);
|
|
252
|
+
if (repairing) addToList(info.chunkhash, hashes);
|
|
241
253
|
if (info.contenthashDigest) {
|
|
242
254
|
for (const hash of Object.keys(info.contenthashDigest)) {
|
|
243
255
|
hashToDigest.set(hash, info.contenthashDigest[hash]);
|
|
@@ -495,7 +507,44 @@ ${referencingAssets
|
|
|
495
507
|
};
|
|
496
508
|
/** @type {Comparator<AssetInfoForRealContentHash>} */
|
|
497
509
|
const comparator = compareSelect((a) => a.name, compareStrings);
|
|
510
|
+
/**
|
|
511
|
+
* Whether a group's names went stale: the fill rewrote an asset of theirs, or
|
|
512
|
+
* one names a hash that already moved (groups arrive dependencies first).
|
|
513
|
+
* @param {string[]} group the hashes assigned together
|
|
514
|
+
* @returns {boolean} true when they have to be recomputed
|
|
515
|
+
*/
|
|
516
|
+
const staleOnDemand = (group) => {
|
|
517
|
+
const own = new Set(group);
|
|
518
|
+
for (const hash of group) {
|
|
519
|
+
for (const asset of /** @type {AssetInfoForRealContentHash[]} */ (
|
|
520
|
+
hashToAssets.get(hash)
|
|
521
|
+
)) {
|
|
522
|
+
if (
|
|
523
|
+
/** @type {ReadonlySet<string>} */ (repairedAssets).has(
|
|
524
|
+
asset.name
|
|
525
|
+
)
|
|
526
|
+
) {
|
|
527
|
+
return true;
|
|
528
|
+
}
|
|
529
|
+
for (const referenced of /** @type {Hashes} */ (
|
|
530
|
+
asset.referencedHashes
|
|
531
|
+
)) {
|
|
532
|
+
if (
|
|
533
|
+
!own.has(referenced) &&
|
|
534
|
+
hashToNewHash.get(referenced) !== referenced
|
|
535
|
+
) {
|
|
536
|
+
return true;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
return false;
|
|
542
|
+
};
|
|
498
543
|
for (const group of groupsInOrder) {
|
|
544
|
+
if (repairedAssets !== undefined && !staleOnDemand(group)) {
|
|
545
|
+
for (const hash of group) hashToNewHash.set(hash, hash);
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
499
548
|
// A cycle is assigned as one group: members are told apart by stable
|
|
500
549
|
// markers, so the group hashes to a fixed point instead of chasing one.
|
|
501
550
|
if (group.length > 1) {
|
|
@@ -608,15 +657,25 @@ ${referencingAssets
|
|
|
608
657
|
(hash) => /** @type {string} */ (hashToNewHash.get(hash))
|
|
609
658
|
);
|
|
610
659
|
|
|
660
|
+
/**
|
|
661
|
+
* @param {string | string[]} hash what the asset was named with
|
|
662
|
+
* @returns {string | string[]} the same, repaired
|
|
663
|
+
*/
|
|
664
|
+
const repaired = (hash) =>
|
|
665
|
+
Array.isArray(hash)
|
|
666
|
+
? hash.map(
|
|
667
|
+
(hash) => /** @type {string} */ (hashToNewHash.get(hash))
|
|
668
|
+
)
|
|
669
|
+
: /** @type {string} */ (hashToNewHash.get(hash));
|
|
670
|
+
/** @type {AssetInfo} */
|
|
611
671
|
const infoUpdate = {};
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
: /** @type {string} */ (hashToNewHash.get(hash));
|
|
672
|
+
if (asset.info.contenthash) {
|
|
673
|
+
infoUpdate.contenthash = repaired(asset.info.contenthash);
|
|
674
|
+
}
|
|
675
|
+
// Tracked only while repairing, so only then does it move with the name.
|
|
676
|
+
if (repairing && asset.info.chunkhash) {
|
|
677
|
+
infoUpdate.chunkhash = repaired(asset.info.chunkhash);
|
|
678
|
+
}
|
|
620
679
|
|
|
621
680
|
if (asset.newSource !== undefined) {
|
|
622
681
|
compilation.updateAsset(
|
|
@@ -15,6 +15,10 @@ const HarmonyExportImportedSpecifierDependency = require("../dependencies/Harmon
|
|
|
15
15
|
const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
|
|
16
16
|
const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency");
|
|
17
17
|
const { ImportPhaseUtils } = require("../dependencies/ImportPhase");
|
|
18
|
+
const {
|
|
19
|
+
getBuildDiagnostics,
|
|
20
|
+
recordOptimizationBailout
|
|
21
|
+
} = require("../util/buildDiagnostics");
|
|
18
22
|
const formatLocation = require("../util/formatLocation");
|
|
19
23
|
const { dirname, join, readJson, relative } = require("../util/fs");
|
|
20
24
|
const { getGlobToRegExpSource } = require("../util/globUtils");
|
|
@@ -35,7 +39,7 @@ const { CompilerHintNotationRegExp } = require("../util/magicComment");
|
|
|
35
39
|
* } from "estree"
|
|
36
40
|
*/
|
|
37
41
|
/** @import Compiler from "../Compiler" */
|
|
38
|
-
/** @import Module, { BuildMeta } from "../Module" */
|
|
42
|
+
/** @import Module, { BuildMeta, BuildInfo } from "../Module" */
|
|
39
43
|
/**
|
|
40
44
|
* @import {
|
|
41
45
|
* JavascriptModuleBuildInfo
|
|
@@ -546,14 +550,18 @@ class SideEffectsFlagPlugin {
|
|
|
546
550
|
} else {
|
|
547
551
|
const type = sideEffectsStatement.type;
|
|
548
552
|
const loc = parser.getLocation(sideEffectsStatement);
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
)
|
|
553
|
+
const at = formatLocation(loc);
|
|
554
|
+
|
|
555
|
+
const buildInfo = /** @type {BuildInfo} */ (
|
|
556
|
+
parser.state.module.buildInfo
|
|
557
|
+
);
|
|
558
|
+
recordOptimizationBailout(
|
|
559
|
+
buildInfo,
|
|
560
|
+
`Statement (${type}) with side effects in source code at ${at}`
|
|
561
|
+
);
|
|
562
|
+
// `performance.unusedModules` names the statement, so it is kept typed too.
|
|
563
|
+
getBuildDiagnostics(buildInfo).sideEffectStatement =
|
|
564
|
+
`${type} at ${at}`;
|
|
557
565
|
}
|
|
558
566
|
});
|
|
559
567
|
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/*
|
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
3
|
+
Author Alexander Akait @alexander-akait
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
const AnalyzableBailoutsWarning = require("../errors/AnalyzableBailoutsWarning");
|
|
9
|
+
|
|
10
|
+
/** @import { PerformanceOptions } from "../../declarations/WebpackOptions" */
|
|
11
|
+
/** @import Compiler from "../Compiler" */
|
|
12
|
+
/** @import Module from "../Module" */
|
|
13
|
+
/** @import { BailoutDetails } from "../errors/AnalyzableBailoutsWarning" */
|
|
14
|
+
|
|
15
|
+
const PLUGIN_NAME = "AnalyzableBailoutsPlugin";
|
|
16
|
+
|
|
17
|
+
// Enough to point at the offenders without listing every module of a build.
|
|
18
|
+
const MAX_REPORTED_MODULES = 5;
|
|
19
|
+
|
|
20
|
+
class AnalyzableBailoutsPlugin {
|
|
21
|
+
/**
|
|
22
|
+
* Creates an instance of AnalyzableBailoutsPlugin.
|
|
23
|
+
* @param {PerformanceOptions} options the plugin options
|
|
24
|
+
*/
|
|
25
|
+
constructor(options) {
|
|
26
|
+
/** @type {PerformanceOptions["hints"]} */
|
|
27
|
+
this.hints = options.hints;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Applies the plugin by registering its hooks on the compiler.
|
|
32
|
+
* @param {Compiler} compiler the compiler instance
|
|
33
|
+
* @returns {void}
|
|
34
|
+
*/
|
|
35
|
+
apply(compiler) {
|
|
36
|
+
const hints = this.hints;
|
|
37
|
+
|
|
38
|
+
if (!hints) return;
|
|
39
|
+
|
|
40
|
+
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
41
|
+
// `afterSeal` is past the hash, which folds every message into it — and
|
|
42
|
+
// past the runtime modules, which record their reasons while being hashed.
|
|
43
|
+
compilation.hooks.afterSeal.tap(PLUGIN_NAME, () => {
|
|
44
|
+
const { chunkGraph, runtimeTemplate, requestShortener } = compilation;
|
|
45
|
+
|
|
46
|
+
// Nothing is recorded outside ESM output, so there is nothing to walk.
|
|
47
|
+
if (!runtimeTemplate.isModule()) return;
|
|
48
|
+
|
|
49
|
+
/** @type {Map<string, Set<string>>} */
|
|
50
|
+
const modulesByReason = new Map();
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Files the reasons recorded on a module under its printed name.
|
|
54
|
+
* @param {Module} module the module, a runtime module included
|
|
55
|
+
* @returns {void}
|
|
56
|
+
*/
|
|
57
|
+
const collect = (module) => {
|
|
58
|
+
const reasons = runtimeTemplate.analyzableBailoutsOf(module);
|
|
59
|
+
if (reasons.length === 0) return;
|
|
60
|
+
const name = module.readableIdentifier(requestShortener);
|
|
61
|
+
for (const reason of reasons) {
|
|
62
|
+
let modules = modulesByReason.get(reason);
|
|
63
|
+
if (modules === undefined) {
|
|
64
|
+
modules = new Set();
|
|
65
|
+
modulesByReason.set(reason, modules);
|
|
66
|
+
}
|
|
67
|
+
modules.add(name);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
for (const module of compilation.modules) collect(module);
|
|
72
|
+
for (const chunk of compilation.chunks) {
|
|
73
|
+
for (const module of chunkGraph.getChunkRuntimeModulesIterable(
|
|
74
|
+
chunk
|
|
75
|
+
)) {
|
|
76
|
+
collect(module);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (modulesByReason.size === 0) return;
|
|
81
|
+
|
|
82
|
+
/** @type {BailoutDetails[]} */
|
|
83
|
+
const bailouts = [];
|
|
84
|
+
let references = 0;
|
|
85
|
+
|
|
86
|
+
for (const [reason, modules] of modulesByReason) {
|
|
87
|
+
const names = [...modules].sort();
|
|
88
|
+
references += names.length;
|
|
89
|
+
bailouts.push({
|
|
90
|
+
reason,
|
|
91
|
+
modules: names.slice(0, MAX_REPORTED_MODULES),
|
|
92
|
+
count: names.length
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// The reason holding the most modules leads; ties read in one order.
|
|
97
|
+
bailouts.sort(
|
|
98
|
+
(a, b) => b.count - a.count || (a.reason < b.reason ? -1 : 1)
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const warning = new AnalyzableBailoutsWarning(bailouts, references);
|
|
102
|
+
|
|
103
|
+
if (hints === "error") {
|
|
104
|
+
compilation.errors.push(warning);
|
|
105
|
+
} else if (hints === "stats") {
|
|
106
|
+
compilation.hints.push(warning);
|
|
107
|
+
} else {
|
|
108
|
+
compilation.warnings.push(warning);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
module.exports = AnalyzableBailoutsPlugin;
|
|
@@ -65,10 +65,11 @@ class CacheEffectivenessPlugin {
|
|
|
65
65
|
|
|
66
66
|
uncacheable++;
|
|
67
67
|
|
|
68
|
+
const notCacheableReasons =
|
|
69
|
+
buildInfo.diagnostics && buildInfo.diagnostics.notCacheableReasons;
|
|
68
70
|
const reasons =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
? buildInfo.notCacheableReasons
|
|
71
|
+
notCacheableReasons && notCacheableReasons.length > 0
|
|
72
|
+
? notCacheableReasons
|
|
72
73
|
: [UNSPECIFIED_REASON];
|
|
73
74
|
|
|
74
75
|
for (const reason of reasons) {
|
|
@@ -8,18 +8,17 @@
|
|
|
8
8
|
const DuplicateModulesWarning = require("../errors/DuplicateModulesWarning");
|
|
9
9
|
const { compareStrings } = require("../util/comparators");
|
|
10
10
|
const getModuleSize = require("./getModuleSize");
|
|
11
|
+
const getSourceModules = require("./getSourceModules");
|
|
11
12
|
|
|
12
13
|
/** @import { PerformanceOptions } from "../../declarations/WebpackOptions" */
|
|
14
|
+
/** @import Chunk from "../Chunk" */
|
|
13
15
|
/** @import Compiler from "../Compiler" */
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
* DuplicateModuleDetails
|
|
17
|
-
* } from "../errors/DuplicateModulesWarning"
|
|
18
|
-
*/
|
|
16
|
+
/** @import Module from "../Module" */
|
|
17
|
+
/** @import { DuplicateModuleDetails } from "../errors/DuplicateModulesWarning" */
|
|
19
18
|
|
|
20
19
|
const PLUGIN_NAME = "DuplicateModulesPlugin";
|
|
21
20
|
|
|
22
|
-
// Enough to name the
|
|
21
|
+
// Enough to name the costliest without listing every shared module.
|
|
23
22
|
const MAX_REPORTED_MODULES = 5;
|
|
24
23
|
|
|
25
24
|
class DuplicateModulesPlugin {
|
|
@@ -44,24 +43,69 @@ class DuplicateModulesPlugin {
|
|
|
44
43
|
|
|
45
44
|
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
46
45
|
compilation.hooks.afterSeal.tap(PLUGIN_NAME, () => {
|
|
47
|
-
const { chunkGraph, requestShortener } = compilation;
|
|
46
|
+
const { chunkGraph, entrypoints, requestShortener } = compilation;
|
|
47
|
+
|
|
48
|
+
// The entrypoints a chunk is reached from, so a copy can be blamed on
|
|
49
|
+
// the pages that pay for it.
|
|
50
|
+
/** @type {Map<Chunk, Set<string>>} */
|
|
51
|
+
const chunkEntrypoints = new Map();
|
|
52
|
+
|
|
53
|
+
for (const [name, entrypoint] of entrypoints) {
|
|
54
|
+
for (const chunk of entrypoint.chunks) {
|
|
55
|
+
const names = chunkEntrypoints.get(chunk);
|
|
56
|
+
|
|
57
|
+
if (names === undefined) {
|
|
58
|
+
chunkEntrypoints.set(chunk, new Set([name]));
|
|
59
|
+
} else {
|
|
60
|
+
names.add(name);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** @type {Map<Module, { chunks: Set<Chunk>, entrypoints: Set<string> }>} */
|
|
66
|
+
const copies = new Map();
|
|
67
|
+
|
|
68
|
+
for (const chunk of compilation.chunks) {
|
|
69
|
+
const names = chunkEntrypoints.get(chunk);
|
|
70
|
+
|
|
71
|
+
for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
|
|
72
|
+
// Scope hoisting makes several modules into one, so a module
|
|
73
|
+
// concatenated into two chunks is in neither on its own.
|
|
74
|
+
for (const inner of getSourceModules(module)) {
|
|
75
|
+
let entry = copies.get(inner);
|
|
76
|
+
|
|
77
|
+
if (entry === undefined) {
|
|
78
|
+
copies.set(
|
|
79
|
+
inner,
|
|
80
|
+
(entry = { chunks: new Set(), entrypoints: new Set() })
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
entry.chunks.add(chunk);
|
|
85
|
+
|
|
86
|
+
if (names !== undefined) {
|
|
87
|
+
for (const name of names) entry.entrypoints.add(name);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
48
93
|
/** @type {DuplicateModuleDetails[]} */
|
|
49
94
|
const duplicated = [];
|
|
50
95
|
let wasted = 0;
|
|
51
96
|
|
|
52
|
-
for (const module of
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (chunks < 2) continue;
|
|
97
|
+
for (const [module, { chunks, entrypoints: names }] of copies) {
|
|
98
|
+
if (chunks.size < 2) continue;
|
|
56
99
|
|
|
57
100
|
// The first copy is the one that had to be emitted; the rest are
|
|
58
101
|
// what a shared chunk would save.
|
|
59
|
-
const extra = getModuleSize(module) * (chunks - 1);
|
|
102
|
+
const extra = getModuleSize(module) * (chunks.size - 1);
|
|
60
103
|
|
|
61
104
|
wasted += extra;
|
|
62
105
|
duplicated.push({
|
|
63
106
|
name: module.readableIdentifier(requestShortener),
|
|
64
|
-
chunks,
|
|
107
|
+
chunks: chunks.size,
|
|
108
|
+
entrypoints: [...names].sort(compareStrings),
|
|
65
109
|
wasted: extra
|
|
66
110
|
});
|
|
67
111
|
}
|
|
@@ -11,6 +11,7 @@ const {
|
|
|
11
11
|
JAVASCRIPT_MODULE_TYPE_ESM
|
|
12
12
|
} = require("../ModuleTypeConstants");
|
|
13
13
|
const EvalUsageWarning = require("../errors/EvalUsageWarning");
|
|
14
|
+
const { getBuildDiagnostics } = require("../util/buildDiagnostics");
|
|
14
15
|
const { compareStrings } = require("../util/comparators");
|
|
15
16
|
|
|
16
17
|
/** @import { PerformanceOptions } from "../../declarations/WebpackOptions" */
|
|
@@ -59,7 +60,7 @@ class EvalUsagePlugin {
|
|
|
59
60
|
parser.state.module.buildInfo
|
|
60
61
|
);
|
|
61
62
|
|
|
62
|
-
buildInfo.usesEval = true;
|
|
63
|
+
getBuildDiagnostics(buildInfo).usesEval = true;
|
|
63
64
|
});
|
|
64
65
|
};
|
|
65
66
|
|
|
@@ -84,7 +85,9 @@ class EvalUsagePlugin {
|
|
|
84
85
|
// Every built module carries one, so only the field is in question.
|
|
85
86
|
const buildInfo = /** @type {BuildInfo} */ (module.buildInfo);
|
|
86
87
|
|
|
87
|
-
if (!buildInfo.usesEval)
|
|
88
|
+
if (!buildInfo.diagnostics || !buildInfo.diagnostics.usesEval) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
88
91
|
|
|
89
92
|
callers.push(module.readableIdentifier(requestShortener));
|
|
90
93
|
}
|