webpack 5.110.2 → 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 -2
- 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/ChunkGraph.js +20 -18
- package/lib/CircularModulesPlugin.js +157 -55
- package/lib/CleanPlugin.js +2 -2
- package/lib/Compilation.js +321 -303
- package/lib/Compiler.js +209 -46
- package/lib/ConcatenationScope.js +25 -35
- 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/DotenvPlugin.js +41 -13
- package/lib/ExternalModule.js +41 -14
- package/lib/FileSystemInfo.js +17 -14
- package/lib/FlagDependencyExportsPlugin.js +45 -21
- package/lib/FlagDependencyUsagePlugin.js +8 -2
- 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 +58 -32
- package/lib/NormalModuleFactory.js +1 -1
- package/lib/RuntimeGlobals.js +21 -7
- package/lib/RuntimeModule.js +28 -12
- package/lib/RuntimePlugin.js +33 -3
- package/lib/RuntimeTemplate.js +794 -477
- 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/async-modules/AsyncModuleHelpers.js +10 -4
- 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 +110 -64
- package/lib/config/normalization.js +100 -20
- 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 +32 -9
- package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +20 -7
- 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 +171 -32
- 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 +99 -41
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +20 -3
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +24 -1
- package/lib/dependencies/HarmonyModulesPlugin.js +20 -0
- package/lib/dependencies/HtmlEntryDependency.js +62 -2
- package/lib/dependencies/ImportContextDependency.js +43 -3
- package/lib/dependencies/ImportDependency.js +8 -29
- package/lib/dependencies/ImportMetaMainDependency.js +104 -0
- package/lib/dependencies/ImportMetaPlugin.js +59 -15
- package/lib/dependencies/ImportParserPlugin.js +24 -14
- package/lib/dependencies/RequireHeaderDependency.js +20 -21
- package/lib/dependencies/SystemRuntimeModule.js +9 -0
- package/lib/dependencies/WorkerDependency.js +1 -2
- package/lib/dependencies/WorkletDependency.js +1 -2
- package/lib/dependencies/importOptionsCheck.js +47 -0
- 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/DotenvFileError.js +29 -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/ImportedBindingAssignmentError.js +30 -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 +360 -84
- 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 +1067 -569
- 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 -22
- 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 +133 -25
- 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 +7 -3
- 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 +105 -67
- 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 +338 -217
- 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/schemes/HttpUriPlugin.js +22 -5
- package/lib/serialization/FileMiddleware.js +15 -2
- 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/ArrayQueue.js +3 -3
- package/lib/util/SourceProcessor.js +76 -69
- package/lib/util/URLAbsoluteSpecifier.js +3 -1
- package/lib/util/async.js +292 -0
- package/lib/util/buildDiagnostics.js +69 -0
- package/lib/util/conventions.js +5 -1
- 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 +6 -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 +388 -76
- 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 +1440 -331
- package/lib/dependencies/ExportBindingInitFragment.js +0 -191
- package/lib/errors/EntrypointOverlapWarning.js +0 -45
- package/lib/performance/EntrypointOverlapPlugin.js +0 -122
|
@@ -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
|
}
|
|
@@ -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 { SourceMapSource } = require("webpack-sources");
|
|
9
|
+
const NormalModule = require("../NormalModule");
|
|
10
|
+
const MissingSourceMapsWarning = require("../errors/MissingSourceMapsWarning");
|
|
11
|
+
const { compareStrings } = require("../util/comparators");
|
|
12
|
+
const getSourceModules = require("./getSourceModules");
|
|
13
|
+
|
|
14
|
+
/** @import { PerformanceOptions } from "../../declarations/WebpackOptions" */
|
|
15
|
+
/** @import Compiler from "../Compiler" */
|
|
16
|
+
/** @import Module from "../Module" */
|
|
17
|
+
/** @import RequestShortener from "../RequestShortener" */
|
|
18
|
+
/** @import { MissingSourceMapDetails } from "../errors/MissingSourceMapsWarning" */
|
|
19
|
+
|
|
20
|
+
const PLUGIN_NAME = "MissingSourceMapsPlugin";
|
|
21
|
+
|
|
22
|
+
// Enough to name the offenders without listing every module a loader touched.
|
|
23
|
+
const MAX_REPORTED_MODULES = 5;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The loaders that ran on a module, shortened for reading.
|
|
27
|
+
* @param {NormalModule} module the module
|
|
28
|
+
* @param {RequestShortener} requestShortener the request shortener
|
|
29
|
+
* @returns {string[]} what to call them
|
|
30
|
+
*/
|
|
31
|
+
const loaderNames = (module, requestShortener) =>
|
|
32
|
+
module.loaders.map((it) => requestShortener.shorten(it.loader) || it.loader);
|
|
33
|
+
|
|
34
|
+
class MissingSourceMapsPlugin {
|
|
35
|
+
/**
|
|
36
|
+
* Creates an instance of MissingSourceMapsPlugin.
|
|
37
|
+
* @param {PerformanceOptions} options the plugin options
|
|
38
|
+
*/
|
|
39
|
+
constructor(options) {
|
|
40
|
+
/** @type {PerformanceOptions["hints"]} */
|
|
41
|
+
this.hints = options.hints;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Applies the plugin by registering its hooks on the compiler.
|
|
46
|
+
* @param {Compiler} compiler the compiler instance
|
|
47
|
+
* @returns {void}
|
|
48
|
+
*/
|
|
49
|
+
apply(compiler) {
|
|
50
|
+
const hints = this.hints;
|
|
51
|
+
|
|
52
|
+
if (!hints) return;
|
|
53
|
+
|
|
54
|
+
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
55
|
+
// `afterSeal` is past the hash, which folds every message into it — a
|
|
56
|
+
// hint reported earlier would change the build's identity.
|
|
57
|
+
compilation.hooks.afterSeal.tap(PLUGIN_NAME, () => {
|
|
58
|
+
const { requestShortener } = compilation;
|
|
59
|
+
/** @type {MissingSourceMapDetails[]} */
|
|
60
|
+
const found = [];
|
|
61
|
+
|
|
62
|
+
// A module can be reached both on its own and inside a
|
|
63
|
+
// concatenation, so it is only counted the first time.
|
|
64
|
+
/** @type {Set<Module>} */
|
|
65
|
+
const seen = new Set();
|
|
66
|
+
|
|
67
|
+
for (const parent of compilation.modules) {
|
|
68
|
+
// Scope hoisting makes several modules into one, and each of them
|
|
69
|
+
// kept the source its own loaders produced.
|
|
70
|
+
for (const module of getSourceModules(parent)) {
|
|
71
|
+
if (seen.has(module)) continue;
|
|
72
|
+
|
|
73
|
+
seen.add(module);
|
|
74
|
+
|
|
75
|
+
if (!(module instanceof NormalModule)) continue;
|
|
76
|
+
|
|
77
|
+
// Only where a real map was asked for: the cheap devtools map to
|
|
78
|
+
// the loader output by design, so nothing is lost there.
|
|
79
|
+
if (!module.useSourceMap) continue;
|
|
80
|
+
if (module.loaders.length === 0) continue;
|
|
81
|
+
|
|
82
|
+
// A loader that returned a map produces a `SourceMapSource`;
|
|
83
|
+
// falling back to any other source is the map being dropped.
|
|
84
|
+
if (module.originalSource() instanceof SourceMapSource) continue;
|
|
85
|
+
|
|
86
|
+
found.push({
|
|
87
|
+
name: module.readableIdentifier(requestShortener),
|
|
88
|
+
loaders: loaderNames(module, requestShortener)
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (found.length === 0) return;
|
|
94
|
+
|
|
95
|
+
// By name: module order is not stable across runs.
|
|
96
|
+
found.sort((a, b) => compareStrings(a.name, b.name));
|
|
97
|
+
|
|
98
|
+
const warning = new MissingSourceMapsWarning(
|
|
99
|
+
found.slice(0, MAX_REPORTED_MODULES),
|
|
100
|
+
found.length
|
|
101
|
+
);
|
|
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 = MissingSourceMapsPlugin;
|
|
@@ -11,6 +11,7 @@ const {
|
|
|
11
11
|
JAVASCRIPT_MODULE_TYPE_ESM
|
|
12
12
|
} = require("../ModuleTypeConstants");
|
|
13
13
|
const PureAnnotationsWarning = require("../errors/PureAnnotationsWarning");
|
|
14
|
+
const { getBuildDiagnostics } = require("../util/buildDiagnostics");
|
|
14
15
|
const { compareStrings } = require("../util/comparators");
|
|
15
16
|
const { CompilerHintNotationRegExp } = require("../util/magicComment");
|
|
16
17
|
|
|
@@ -154,7 +155,7 @@ class PureAnnotationsPlugin {
|
|
|
154
155
|
parser.state.module.buildInfo
|
|
155
156
|
);
|
|
156
157
|
|
|
157
|
-
buildInfo.ineffectivePureAnnotations = wasted;
|
|
158
|
+
getBuildDiagnostics(buildInfo).ineffectivePureAnnotations = wasted;
|
|
158
159
|
});
|
|
159
160
|
};
|
|
160
161
|
|
|
@@ -180,9 +181,11 @@ class PureAnnotationsPlugin {
|
|
|
180
181
|
// Every built module carries one, so only the field is in question.
|
|
181
182
|
const buildInfo = /** @type {BuildInfo} */ (module.buildInfo);
|
|
182
183
|
|
|
183
|
-
|
|
184
|
+
const count =
|
|
185
|
+
buildInfo.diagnostics &&
|
|
186
|
+
buildInfo.diagnostics.ineffectivePureAnnotations;
|
|
184
187
|
|
|
185
|
-
|
|
188
|
+
if (!count) continue;
|
|
186
189
|
|
|
187
190
|
total += count;
|
|
188
191
|
wasteful.push({
|
|
@@ -11,14 +11,14 @@ const {
|
|
|
11
11
|
JAVASCRIPT_MODULE_TYPE_ESM
|
|
12
12
|
} = require("../ModuleTypeConstants");
|
|
13
13
|
const TopLevelThisWarning = require("../errors/TopLevelThisWarning");
|
|
14
|
+
const { getBuildDiagnostics } = require("../util/buildDiagnostics");
|
|
14
15
|
const { compareStrings } = require("../util/comparators");
|
|
15
16
|
const getSourceModules = require("./getSourceModules");
|
|
16
17
|
|
|
17
18
|
/** @import { Program } from "estree" */
|
|
18
19
|
/** @import { PerformanceOptions } from "../../declarations/WebpackOptions" */
|
|
19
20
|
/** @import Compiler from "../Compiler" */
|
|
20
|
-
/** @import Module from "../Module" */
|
|
21
|
-
/** @import { BuildInfo } from "../Module" */
|
|
21
|
+
/** @import Module, { BuildInfo } from "../Module" */
|
|
22
22
|
/** @import JavascriptParser from "../javascript/JavascriptParser" */
|
|
23
23
|
/** @import { TopLevelThisDetails } from "../errors/TopLevelThisWarning" */
|
|
24
24
|
|
|
@@ -133,7 +133,7 @@ class TopLevelThisPlugin {
|
|
|
133
133
|
/** @type {BuildInfo} */
|
|
134
134
|
(parser.state.module.buildInfo);
|
|
135
135
|
|
|
136
|
-
buildInfo.topLevelThis = count;
|
|
136
|
+
getBuildDiagnostics(buildInfo).topLevelThis = count;
|
|
137
137
|
});
|
|
138
138
|
};
|
|
139
139
|
|
|
@@ -168,7 +168,8 @@ class TopLevelThisPlugin {
|
|
|
168
168
|
seen.add(module);
|
|
169
169
|
|
|
170
170
|
const buildInfo = /** @type {BuildInfo} */ (module.buildInfo);
|
|
171
|
-
const count =
|
|
171
|
+
const count =
|
|
172
|
+
buildInfo.diagnostics && buildInfo.diagnostics.topLevelThis;
|
|
172
173
|
|
|
173
174
|
if (!count) continue;
|
|
174
175
|
|
|
@@ -0,0 +1,109 @@
|
|
|
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 { ASSET_TYPE } = require("../ModuleSourceTypeConstants");
|
|
9
|
+
const HarmonyImportBareSideEffectDependency = require("../dependencies/HarmonyImportBareSideEffectDependency");
|
|
10
|
+
const HarmonyImportSideEffectDependency = require("../dependencies/HarmonyImportSideEffectDependency");
|
|
11
|
+
const UnusedAssetsWarning = require("../errors/UnusedAssetsWarning");
|
|
12
|
+
const { compareStrings } = require("../util/comparators");
|
|
13
|
+
const getModuleSize = require("./getModuleSize");
|
|
14
|
+
|
|
15
|
+
/** @import { PerformanceOptions } from "../../declarations/WebpackOptions" */
|
|
16
|
+
/** @import Compiler from "../Compiler" */
|
|
17
|
+
/** @import { UnusedAssetDetails } from "../errors/UnusedAssetsWarning" */
|
|
18
|
+
|
|
19
|
+
const PLUGIN_NAME = "UnusedAssetsPlugin";
|
|
20
|
+
|
|
21
|
+
// Enough to name the offenders without listing every asset in the build.
|
|
22
|
+
const MAX_REPORTED_ASSETS = 5;
|
|
23
|
+
|
|
24
|
+
class UnusedAssetsPlugin {
|
|
25
|
+
/**
|
|
26
|
+
* Creates an instance of UnusedAssetsPlugin.
|
|
27
|
+
* @param {PerformanceOptions} options the plugin options
|
|
28
|
+
*/
|
|
29
|
+
constructor(options) {
|
|
30
|
+
/** @type {PerformanceOptions["hints"]} */
|
|
31
|
+
this.hints = options.hints;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Applies the plugin by registering its hooks on the compiler.
|
|
36
|
+
* @param {Compiler} compiler the compiler instance
|
|
37
|
+
* @returns {void}
|
|
38
|
+
*/
|
|
39
|
+
apply(compiler) {
|
|
40
|
+
const hints = this.hints;
|
|
41
|
+
|
|
42
|
+
if (!hints) return;
|
|
43
|
+
|
|
44
|
+
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
45
|
+
// `afterSeal` is past the hash, which folds every message into it — a
|
|
46
|
+
// hint reported earlier would change the build's identity.
|
|
47
|
+
compilation.hooks.afterSeal.tap(PLUGIN_NAME, () => {
|
|
48
|
+
const { moduleGraph, requestShortener } = compilation;
|
|
49
|
+
/** @type {UnusedAssetDetails[]} */
|
|
50
|
+
const found = [];
|
|
51
|
+
let total = 0;
|
|
52
|
+
|
|
53
|
+
for (const module of compilation.modules) {
|
|
54
|
+
// An inlined one carries no asset type: it is a data url in the
|
|
55
|
+
// importer, whose bytes `inlinedAssets` is the check for.
|
|
56
|
+
if (!module.getSourceTypes().has(ASSET_TYPE)) continue;
|
|
57
|
+
|
|
58
|
+
let onlyUnread = false;
|
|
59
|
+
|
|
60
|
+
for (const connection of moduleGraph.getIncomingConnections(module)) {
|
|
61
|
+
const dependency = connection.dependency;
|
|
62
|
+
|
|
63
|
+
// Anything else — a `url()`, a `new URL()`, an html `src` — reads
|
|
64
|
+
// the file, and a bare import asks for it on purpose.
|
|
65
|
+
if (
|
|
66
|
+
!(dependency instanceof HarmonyImportSideEffectDependency) ||
|
|
67
|
+
dependency instanceof HarmonyImportBareSideEffectDependency
|
|
68
|
+
) {
|
|
69
|
+
onlyUnread = false;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
onlyUnread = true;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!onlyUnread) continue;
|
|
77
|
+
|
|
78
|
+
const size = Math.round(getModuleSize(module));
|
|
79
|
+
|
|
80
|
+
total += size;
|
|
81
|
+
found.push({
|
|
82
|
+
name: module.readableIdentifier(requestShortener),
|
|
83
|
+
size
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (found.length === 0) return;
|
|
88
|
+
|
|
89
|
+
// Largest first; ties break by name, module order is not stable.
|
|
90
|
+
found.sort((a, b) => b.size - a.size || compareStrings(a.name, b.name));
|
|
91
|
+
|
|
92
|
+
const warning = new UnusedAssetsWarning(
|
|
93
|
+
found.slice(0, MAX_REPORTED_ASSETS),
|
|
94
|
+
total
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
if (hints === "error") {
|
|
98
|
+
compilation.errors.push(warning);
|
|
99
|
+
} else if (hints === "stats") {
|
|
100
|
+
compilation.hints.push(warning);
|
|
101
|
+
} else {
|
|
102
|
+
compilation.warnings.push(warning);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = UnusedAssetsPlugin;
|
|
@@ -0,0 +1,147 @@
|
|
|
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 RemoteModule = require("../container/RemoteModule");
|
|
9
|
+
const { getDeclaredRemotes } = require("../container/declaredRemotes");
|
|
10
|
+
const UnusedFederationWarning = require("../errors/UnusedFederationWarning");
|
|
11
|
+
const ConsumeSharedModule = require("../sharing/ConsumeSharedModule");
|
|
12
|
+
const { getDeclaredShared } = require("../sharing/declaredShared");
|
|
13
|
+
const { compareStrings } = require("../util/comparators");
|
|
14
|
+
|
|
15
|
+
/** @import { PerformanceOptions } from "../../declarations/WebpackOptions" */
|
|
16
|
+
/** @import Compiler from "../Compiler" */
|
|
17
|
+
/** @import { UnusedFederationDetails } from "../errors/UnusedFederationWarning" */
|
|
18
|
+
|
|
19
|
+
const PLUGIN_NAME = "UnusedFederationPlugin";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {Set<string>} used the share keys modules were created for
|
|
23
|
+
* @param {string} shareKey the declared share key
|
|
24
|
+
* @returns {boolean} whether anything under the share key was used
|
|
25
|
+
*/
|
|
26
|
+
const someUsedStartsWith = (used, shareKey) => {
|
|
27
|
+
for (const usedKey of used) {
|
|
28
|
+
if (usedKey.startsWith(shareKey)) return true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return false;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Applies the rule `ContainerReferencePlugin` factorizes by, so that a remote
|
|
36
|
+
* name holding slashes is told apart from an exposed path holding them too.
|
|
37
|
+
* @param {string} request the request a remote module was created for
|
|
38
|
+
* @param {string} name the declared remote name
|
|
39
|
+
* @returns {boolean} whether the request names this remote
|
|
40
|
+
*/
|
|
41
|
+
const isRequestFor = (request, name) =>
|
|
42
|
+
request.startsWith(name) &&
|
|
43
|
+
(request.length === name.length || request[name.length] === "/");
|
|
44
|
+
|
|
45
|
+
class UnusedFederationPlugin {
|
|
46
|
+
/**
|
|
47
|
+
* Creates an instance of UnusedFederationPlugin.
|
|
48
|
+
* @param {PerformanceOptions} options the plugin options
|
|
49
|
+
*/
|
|
50
|
+
constructor(options) {
|
|
51
|
+
/** @type {PerformanceOptions["hints"]} */
|
|
52
|
+
this.hints = options.hints;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Applies the plugin by registering its hooks on the compiler.
|
|
57
|
+
* @param {Compiler} compiler the compiler instance
|
|
58
|
+
* @returns {void}
|
|
59
|
+
*/
|
|
60
|
+
apply(compiler) {
|
|
61
|
+
const hints = this.hints;
|
|
62
|
+
|
|
63
|
+
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
64
|
+
// Reported past the hash, which folds every message into it, so a hint
|
|
65
|
+
// pushed earlier would change the build's identity.
|
|
66
|
+
compilation.hooks.afterSeal.tap(PLUGIN_NAME, () => {
|
|
67
|
+
const declaredShared = getDeclaredShared(compilation);
|
|
68
|
+
const declaredRemotes = getDeclaredRemotes(compilation);
|
|
69
|
+
|
|
70
|
+
if (declaredShared === undefined && declaredRemotes === undefined) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Nothing was factorized, so no shared or remote module could exist.
|
|
75
|
+
if (compilation.modules.size === 0) return;
|
|
76
|
+
|
|
77
|
+
/** @type {Set<string>} */
|
|
78
|
+
const usedShared = new Set();
|
|
79
|
+
/** @type {Set<string>} */
|
|
80
|
+
const remoteRequests = new Set();
|
|
81
|
+
|
|
82
|
+
for (const module of compilation.modules) {
|
|
83
|
+
if (module instanceof ConsumeSharedModule) {
|
|
84
|
+
usedShared.add(module.options.shareKey);
|
|
85
|
+
} else if (module instanceof RemoteModule) {
|
|
86
|
+
remoteRequests.add(module.request);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** @type {UnusedFederationDetails[]} */
|
|
91
|
+
const unused = [];
|
|
92
|
+
|
|
93
|
+
if (declaredShared !== undefined) {
|
|
94
|
+
// Matched on the share key, since that is what the module carries,
|
|
95
|
+
// but reported by the config key, which is what the config spells.
|
|
96
|
+
for (const { name, shareKey, prefix } of declaredShared) {
|
|
97
|
+
const used = prefix
|
|
98
|
+
? someUsedStartsWith(usedShared, shareKey)
|
|
99
|
+
: usedShared.has(shareKey);
|
|
100
|
+
|
|
101
|
+
if (!used) unused.push({ name, kind: "shared" });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (declaredRemotes !== undefined) {
|
|
106
|
+
/** @type {Set<string>} */
|
|
107
|
+
const usedRemotes = new Set();
|
|
108
|
+
|
|
109
|
+
// Declaration order is precedence: `factorize` takes the first
|
|
110
|
+
// name a request matches, so a later one it also matches is dead.
|
|
111
|
+
for (const request of remoteRequests) {
|
|
112
|
+
for (const name of declaredRemotes) {
|
|
113
|
+
if (isRequestFor(request, name)) {
|
|
114
|
+
usedRemotes.add(name);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
for (const name of declaredRemotes) {
|
|
121
|
+
if (!usedRemotes.has(name)) unused.push({ name, kind: "remote" });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (unused.length === 0) return;
|
|
126
|
+
|
|
127
|
+
// Ties break by name: declaration order is not worth preserving here.
|
|
128
|
+
unused.sort(
|
|
129
|
+
(a, b) =>
|
|
130
|
+
compareStrings(a.kind, b.kind) || compareStrings(a.name, b.name)
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const warning = new UnusedFederationWarning(unused);
|
|
134
|
+
|
|
135
|
+
if (hints === "error") {
|
|
136
|
+
compilation.errors.push(warning);
|
|
137
|
+
} else if (hints === "stats") {
|
|
138
|
+
compilation.hints.push(warning);
|
|
139
|
+
} else {
|
|
140
|
+
compilation.warnings.push(warning);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
module.exports = UnusedFederationPlugin;
|