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.
Files changed (226) hide show
  1. package/README.md +5 -2
  2. package/lib/APIPlugin.js +23 -7
  3. package/lib/AutomaticPrefetchPlugin.js +1 -1
  4. package/lib/Cache.js +8 -3
  5. package/lib/CacheFacade.js +1 -1
  6. package/lib/ChunkGraph.js +20 -18
  7. package/lib/CircularModulesPlugin.js +157 -55
  8. package/lib/CleanPlugin.js +2 -2
  9. package/lib/Compilation.js +321 -303
  10. package/lib/Compiler.js +209 -46
  11. package/lib/ConcatenationScope.js +25 -35
  12. package/lib/ContextModule.js +17 -81
  13. package/lib/ContextModuleFactory.js +1 -1
  14. package/lib/CopyPlugin.js +1054 -0
  15. package/lib/DefinePlugin.js +24 -8
  16. package/lib/DotenvPlugin.js +41 -13
  17. package/lib/ExternalModule.js +41 -14
  18. package/lib/FileSystemInfo.js +17 -14
  19. package/lib/FlagDependencyExportsPlugin.js +45 -21
  20. package/lib/FlagDependencyUsagePlugin.js +8 -2
  21. package/lib/HotModuleReplacementPlugin.js +53 -7
  22. package/lib/JavascriptMetaInfoPlugin.js +5 -3
  23. package/lib/MainTemplate.js +5 -1
  24. package/lib/Module.js +16 -7
  25. package/lib/MultiCompiler.js +1 -1
  26. package/lib/MultiWatching.js +1 -1
  27. package/lib/NormalModule.js +58 -32
  28. package/lib/NormalModuleFactory.js +1 -1
  29. package/lib/RuntimeGlobals.js +21 -7
  30. package/lib/RuntimeModule.js +28 -12
  31. package/lib/RuntimePlugin.js +33 -3
  32. package/lib/RuntimeTemplate.js +794 -477
  33. package/lib/SourceMapDevToolPlugin.js +1 -1
  34. package/lib/Watching.js +9 -0
  35. package/lib/WebpackOptionsApply.js +84 -91
  36. package/lib/asset/AssetGenerator.js +25 -8
  37. package/lib/asset/AssetModule.js +3 -0
  38. package/lib/asset/WebManifestParser.js +7 -5
  39. package/lib/async-modules/AsyncModuleHelpers.js +10 -4
  40. package/lib/cache/AddBuildDependenciesPlugin.js +33 -4
  41. package/lib/cache/IdleFileCachePlugin.js +2 -2
  42. package/lib/cache/PackFileCacheStrategy.js +14 -1
  43. package/lib/config/browserslistTargetHandler.js +19 -0
  44. package/lib/config/defaults.js +110 -64
  45. package/lib/config/normalization.js +100 -20
  46. package/lib/config/target.js +10 -0
  47. package/lib/container/ContainerReferencePlugin.js +6 -0
  48. package/lib/container/RemoteRuntimeModule.js +9 -0
  49. package/lib/container/declaredRemotes.js +39 -0
  50. package/lib/css/CssGenerator.js +8 -0
  51. package/lib/css/CssInjectStyleRuntimeModule.js +9 -0
  52. package/lib/css/CssLoadingRuntimeModule.js +94 -36
  53. package/lib/css/CssModule.js +1 -1
  54. package/lib/css/CssModulesPlugin.js +7 -6
  55. package/lib/css/CssParser.js +144 -11
  56. package/lib/css/CssServerStylesRuntimeModule.js +9 -0
  57. package/lib/css/cssMinify.js +11 -3
  58. package/lib/css/data.js +2814 -678
  59. package/lib/css/syntax.js +4082 -248
  60. package/lib/debug/ProfilingPlugin.js +4 -0
  61. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -3
  62. package/lib/dependencies/AMDRuntimeModules.js +18 -0
  63. package/lib/dependencies/CommonJsExportRequireDependency.js +3 -1
  64. package/lib/dependencies/CommonJsExportsParserPlugin.js +12 -13
  65. package/lib/dependencies/CommonJsImportsParserPlugin.js +1 -0
  66. package/lib/dependencies/CommonJsPlugin.js +19 -3
  67. package/lib/dependencies/CommonJsRequireDependency.js +32 -9
  68. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +20 -7
  69. package/lib/dependencies/CssIcssExportDependency.js +7 -1
  70. package/lib/dependencies/HarmonyCompatibilityDependency.js +58 -4
  71. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +8 -3
  72. package/lib/dependencies/HarmonyExportExpressionDependency.js +44 -29
  73. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +171 -32
  74. package/lib/dependencies/HarmonyExportInitFragment.js +99 -19
  75. package/lib/dependencies/HarmonyExportSpecifierDependency.js +18 -30
  76. package/lib/dependencies/HarmonyImportBareSideEffectDependency.js +59 -0
  77. package/lib/dependencies/HarmonyImportDependency.js +99 -41
  78. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +20 -3
  79. package/lib/dependencies/HarmonyImportSpecifierDependency.js +24 -1
  80. package/lib/dependencies/HarmonyModulesPlugin.js +20 -0
  81. package/lib/dependencies/HtmlEntryDependency.js +62 -2
  82. package/lib/dependencies/ImportContextDependency.js +43 -3
  83. package/lib/dependencies/ImportDependency.js +8 -29
  84. package/lib/dependencies/ImportMetaMainDependency.js +104 -0
  85. package/lib/dependencies/ImportMetaPlugin.js +59 -15
  86. package/lib/dependencies/ImportParserPlugin.js +24 -14
  87. package/lib/dependencies/RequireHeaderDependency.js +20 -21
  88. package/lib/dependencies/SystemRuntimeModule.js +9 -0
  89. package/lib/dependencies/WorkerDependency.js +1 -2
  90. package/lib/dependencies/WorkletDependency.js +1 -2
  91. package/lib/dependencies/importOptionsCheck.js +47 -0
  92. package/lib/dll/DelegatedModule.js +18 -1
  93. package/lib/dll/DllReferencePlugin.js +11 -8
  94. package/lib/dll/LibManifestPlugin.js +1 -1
  95. package/lib/errors/AnalyzableBailoutsWarning.js +41 -0
  96. package/lib/errors/DotenvFileError.js +29 -0
  97. package/lib/errors/DuplicateModulesWarning.js +12 -7
  98. package/lib/errors/EmptyCopyPatternWarning.js +26 -0
  99. package/lib/errors/ExternalStarReexportError.js +44 -0
  100. package/lib/errors/ImportedBindingAssignmentError.js +30 -0
  101. package/lib/errors/MissingSourceMapsWarning.js +36 -0
  102. package/lib/errors/ModuleParseError.js +2 -1
  103. package/lib/errors/UnusedAssetsWarning.js +36 -0
  104. package/lib/errors/UnusedFederationWarning.js +35 -0
  105. package/lib/errors/UnusedModulesWarning.js +38 -0
  106. package/lib/esm/ExportWebpackRequireRuntimeModule.js +9 -0
  107. package/lib/esm/ModuleChunkFormatPlugin.js +28 -3
  108. package/lib/esm/ModuleChunkLoadingPlugin.js +30 -11
  109. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +92 -60
  110. package/lib/hmr/HotModuleReplacement.runtime.js +8 -2
  111. package/lib/hmr/HotModuleReplacementRuntimeModule.js +9 -0
  112. package/lib/html/HtmlGenerator.js +11 -5
  113. package/lib/html/HtmlModulesPlugin.js +360 -84
  114. package/lib/html/HtmlParser.js +13 -6
  115. package/lib/html/builtinEmbeddedRenderer.js +107 -0
  116. package/lib/html/data.js +121 -7
  117. package/lib/html/htmlMinify.js +84 -113
  118. package/lib/html/syntax.js +1067 -569
  119. package/lib/ids/HashedModuleIdsPlugin.js +2 -1
  120. package/lib/index.js +3 -0
  121. package/lib/javascript/JavascriptModule.js +1 -0
  122. package/lib/javascript/JavascriptModulesPlugin.js +52 -22
  123. package/lib/javascript/JavascriptParser.js +1255 -728
  124. package/lib/javascript/StartupHelpers.js +27 -3
  125. package/lib/javascript/data.js +172 -0
  126. package/lib/javascript/grammar.js +5546 -0
  127. package/lib/javascript/parser.js +1494 -0
  128. package/lib/javascript/regexp.js +1762 -0
  129. package/lib/javascript/regexpData.js +51 -0
  130. package/lib/javascript/syntax.js +8696 -5225
  131. package/lib/library/ModuleLibraryPlugin.js +116 -5
  132. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -0
  133. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -0
  134. package/lib/optimize/ConcatenatedModule.js +133 -25
  135. package/lib/optimize/ConstExportsPlugin.js +50 -39
  136. package/lib/optimize/InlineExports.js +20 -123
  137. package/lib/optimize/MangleExportsPlugin.js +10 -0
  138. package/lib/optimize/ModuleConcatenationPlugin.js +24 -1
  139. package/lib/optimize/RealContentHashPlugin.js +68 -9
  140. package/lib/optimize/SideEffectsFlagPlugin.js +17 -9
  141. package/lib/performance/AnalyzableBailoutsPlugin.js +115 -0
  142. package/lib/performance/CacheEffectivenessPlugin.js +4 -3
  143. package/lib/performance/DuplicateModulesPlugin.js +57 -13
  144. package/lib/performance/EvalUsagePlugin.js +5 -2
  145. package/lib/performance/MissingSourceMapsPlugin.js +115 -0
  146. package/lib/performance/PureAnnotationsPlugin.js +6 -3
  147. package/lib/performance/TopLevelThisPlugin.js +5 -4
  148. package/lib/performance/UnusedAssetsPlugin.js +109 -0
  149. package/lib/performance/UnusedFederationPlugin.js +147 -0
  150. package/lib/performance/UnusedModulesPlugin.js +141 -0
  151. package/lib/performance/UnusedReexportsPlugin.js +1 -55
  152. package/lib/performance/isOnlyReexported.js +65 -0
  153. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +25 -5
  154. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +2 -0
  155. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +9 -0
  156. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +9 -0
  157. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +9 -0
  158. package/lib/prefetch/ResourceHintPlugin.js +7 -3
  159. package/lib/prefetch/ResourceHintRuntimeModule.js +9 -0
  160. package/lib/prefetch/StartupAssetHintRuntimeModule.js +9 -0
  161. package/lib/rules/RuleSetCompiler.js +211 -4
  162. package/lib/runtime/AsyncModuleRuntimeModule.js +105 -67
  163. package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -0
  164. package/lib/runtime/BaseUriRuntimeModule.js +9 -0
  165. package/lib/runtime/ChunkNameRuntimeModule.js +9 -0
  166. package/lib/runtime/EnsureChunkRuntimeModule.js +35 -16
  167. package/lib/runtime/GetChunkFilenameRuntimeModule.js +9 -0
  168. package/lib/runtime/GetFullHashRuntimeModule.js +9 -0
  169. package/lib/runtime/GetMainFilenameRuntimeModule.js +9 -0
  170. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +9 -0
  171. package/lib/runtime/GlobalRuntimeModule.js +9 -0
  172. package/lib/runtime/HasOwnPropertyRuntimeModule.js +9 -0
  173. package/lib/runtime/HelperRuntimeModule.js +10 -0
  174. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +338 -217
  175. package/lib/runtime/NonceRuntimeModule.js +9 -0
  176. package/lib/runtime/OnChunksLoadedRuntimeModule.js +67 -20
  177. package/lib/runtime/PublicPathRuntimeModule.js +9 -0
  178. package/lib/runtime/RuntimeIdRuntimeModule.js +9 -0
  179. package/lib/runtime/SpecNamespaceObjectRuntimeModule.js +90 -0
  180. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +9 -0
  181. package/lib/runtime/StartupEntrypointRuntimeModule.js +9 -0
  182. package/lib/runtime/SystemContextRuntimeModule.js +9 -0
  183. package/lib/runtime/ToBinaryRuntimeModule.js +9 -0
  184. package/lib/schemes/HttpUriPlugin.js +22 -5
  185. package/lib/serialization/FileMiddleware.js +15 -2
  186. package/lib/serialization/ObjectMiddleware.js +138 -106
  187. package/lib/sharing/ConsumeSharedPlugin.js +12 -0
  188. package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -0
  189. package/lib/sharing/ShareRuntimeModule.js +9 -0
  190. package/lib/sharing/declaredShared.js +47 -0
  191. package/lib/stats/DefaultStatsFactoryPlugin.js +3 -1
  192. package/lib/stats/DefaultStatsPrinterPlugin.js +3 -0
  193. package/lib/util/ArrayQueue.js +3 -3
  194. package/lib/util/SourceProcessor.js +76 -69
  195. package/lib/util/URLAbsoluteSpecifier.js +3 -1
  196. package/lib/util/async.js +292 -0
  197. package/lib/util/buildDiagnostics.js +69 -0
  198. package/lib/util/conventions.js +5 -1
  199. package/lib/util/fs.js +27 -1
  200. package/lib/util/handlerKeys.js +40 -0
  201. package/lib/util/identifier.js +20 -0
  202. package/lib/util/internalSerializables.js +6 -0
  203. package/lib/util/registerExternalSerializer.js +6 -45
  204. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +9 -0
  205. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +9 -0
  206. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +9 -0
  207. package/lib/web/JsonpChunkLoadingRuntimeModule.js +36 -0
  208. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +19 -0
  209. package/package.json +22 -16
  210. package/schemas/WebpackOptions.check.js +1 -1
  211. package/schemas/WebpackOptions.json +388 -76
  212. package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
  213. package/schemas/plugins/ManifestPlugin.check.js +1 -1
  214. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  215. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  216. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  217. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  218. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  219. package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
  220. package/schemas/plugins/dll/DllReferencePlugin.check.js +1 -1
  221. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +1 -1
  222. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  223. package/types.d.ts +1440 -331
  224. package/lib/dependencies/ExportBindingInitFragment.js +0 -191
  225. package/lib/errors/EntrypointOverlapWarning.js +0 -45
  226. package/lib/performance/EntrypointOverlapPlugin.js +0 -122
@@ -0,0 +1,141 @@
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 HarmonyImportBareSideEffectDependency = require("../dependencies/HarmonyImportBareSideEffectDependency");
9
+ const UnusedModulesWarning = require("../errors/UnusedModulesWarning");
10
+ const { compareStrings } = require("../util/comparators");
11
+ const getModuleSize = require("./getModuleSize");
12
+ const hasOnlyUnusedExports = require("./hasOnlyUnusedExports");
13
+ const isOnlyReexported = require("./isOnlyReexported");
14
+
15
+ /** @import { PerformanceOptions } from "../../declarations/WebpackOptions" */
16
+ /** @import Compiler from "../Compiler" */
17
+ /** @import Module, { BuildInfo } from "../Module" */
18
+ /** @import ModuleGraph from "../ModuleGraph" */
19
+ /** @import { UnusedModuleDetails } from "../errors/UnusedModulesWarning" */
20
+
21
+ const PLUGIN_NAME = "UnusedModulesPlugin";
22
+
23
+ // Enough to name the offenders without listing every module kept this way.
24
+ const MAX_REPORTED_MODULES = 5;
25
+
26
+ /**
27
+ * Whether some importer bound a name from this module. A bare `import "..."`
28
+ * binds nothing, so it can only have been written for what importing does —
29
+ * that is deliberate, and not what this hint is about.
30
+ * @param {Module} module the module to look up
31
+ * @param {ModuleGraph} moduleGraph the module graph
32
+ * @returns {boolean} true when every importer bound something
33
+ */
34
+ const everyImportBinds = (module, moduleGraph) => {
35
+ for (const connection of moduleGraph.getIncomingConnections(module)) {
36
+ if (
37
+ connection.dependency instanceof HarmonyImportBareSideEffectDependency
38
+ ) {
39
+ return false;
40
+ }
41
+ }
42
+
43
+ return true;
44
+ };
45
+
46
+ class UnusedModulesPlugin {
47
+ /**
48
+ * Creates an instance of UnusedModulesPlugin.
49
+ * @param {PerformanceOptions} options the plugin options
50
+ */
51
+ constructor(options) {
52
+ /** @type {PerformanceOptions["hints"]} */
53
+ this.hints = options.hints;
54
+ }
55
+
56
+ /**
57
+ * Applies the plugin by registering its hooks on the compiler.
58
+ * @param {Compiler} compiler the compiler instance
59
+ * @returns {void}
60
+ */
61
+ apply(compiler) {
62
+ const hints = this.hints;
63
+
64
+ if (!hints) return;
65
+
66
+ compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
67
+ /** @type {UnusedModulesWarning | undefined} */
68
+ let warning;
69
+
70
+ // Usage is final here, and concatenation has not merged the modules
71
+ // away yet, so each one can still be measured and attributed.
72
+ compilation.hooks.optimizeModules.tap(PLUGIN_NAME, (modules) => {
73
+ const { chunkGraph, moduleGraph, requestShortener } = compilation;
74
+ /** @type {UnusedModuleDetails[]} */
75
+ const found = [];
76
+ let size = 0;
77
+
78
+ for (const module of modules) {
79
+ // One webpack already left out costs nothing — and with no chunk it
80
+ // has no runtime, which is all `hasOnlyUnusedExports` reads usage in.
81
+ if (chunkGraph.getNumberOfModuleChunks(module) === 0) continue;
82
+ if (!hasOnlyUnusedExports(module, moduleGraph, chunkGraph)) continue;
83
+
84
+ // A barrel's leftover is the same finding with a different cause,
85
+ // and `UnusedReexportsPlugin` states it with the re-export named.
86
+ if (isOnlyReexported(module, moduleGraph)) continue;
87
+
88
+ if (!everyImportBinds(module, moduleGraph)) continue;
89
+
90
+ // Recorded while parsing, so a module restored from the cache still has it.
91
+ // Absent means the module is kept for a reason this hint cannot name.
92
+ const diagnostics =
93
+ /** @type {BuildInfo} */
94
+ (module.buildInfo).diagnostics;
95
+ const statement =
96
+ diagnostics === undefined
97
+ ? undefined
98
+ : diagnostics.sideEffectStatement;
99
+
100
+ if (statement === undefined) continue;
101
+
102
+ const bytes = Math.round(getModuleSize(module));
103
+
104
+ size += bytes;
105
+ found.push({
106
+ name: module.readableIdentifier(requestShortener),
107
+ size: bytes,
108
+ statement
109
+ });
110
+ }
111
+
112
+ if (found.length === 0) return;
113
+
114
+ // Largest first; ties break by name, module order is not stable.
115
+ found.sort((a, b) => b.size - a.size || compareStrings(a.name, b.name));
116
+
117
+ warning = new UnusedModulesWarning(
118
+ found.slice(0, MAX_REPORTED_MODULES),
119
+ found.length,
120
+ size
121
+ );
122
+ });
123
+
124
+ // Reported past the hash: `createHash` folds every message into it, so
125
+ // a hint pushed earlier would change the build's identity.
126
+ compilation.hooks.afterSeal.tap(PLUGIN_NAME, () => {
127
+ if (warning === undefined) return;
128
+
129
+ if (hints === "error") {
130
+ compilation.errors.push(warning);
131
+ } else if (hints === "stats") {
132
+ compilation.hints.push(warning);
133
+ } else {
134
+ compilation.warnings.push(warning);
135
+ }
136
+ });
137
+ });
138
+ }
139
+ }
140
+
141
+ module.exports = UnusedModulesPlugin;
@@ -5,17 +5,14 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
9
- const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
10
8
  const UnusedReexportsWarning = require("../errors/UnusedReexportsWarning");
11
9
  const { compareStrings } = require("../util/comparators");
12
10
  const getModuleSize = require("./getModuleSize");
13
11
  const hasOnlyUnusedExports = require("./hasOnlyUnusedExports");
12
+ const isOnlyReexported = require("./isOnlyReexported");
14
13
 
15
14
  /** @import { PerformanceOptions } from "../../declarations/WebpackOptions" */
16
15
  /** @import Compiler from "../Compiler" */
17
- /** @import Module from "../Module" */
18
- /** @import ModuleGraph from "../ModuleGraph" */
19
16
  /** @import { UnusedReexportDetails } from "../errors/UnusedReexportsWarning" */
20
17
 
21
18
  const PLUGIN_NAME = "UnusedReexportsPlugin";
@@ -23,57 +20,6 @@ const PLUGIN_NAME = "UnusedReexportsPlugin";
23
20
  // Enough to name the offenders without listing the barrel.
24
21
  const MAX_REPORTED_MODULES = 5;
25
22
 
26
- /**
27
- * Tells whether every module pulling this one in does so by re-exporting it.
28
- * One an importer wants for its side effects alone is deliberate, not a
29
- * barrel's leftover.
30
- * @param {Module} module the module to look up
31
- * @param {ModuleGraph} moduleGraph the module graph
32
- * @returns {boolean} true when only re-exports pull it in
33
- */
34
- const isOnlyReexported = (module, moduleGraph) => {
35
- // A re-export emits a side-effect edge of its own, so edges are grouped by
36
- // the statement they come from — `sourceOrder` — rather than by their type.
37
- /** @type {Map<Module, Set<number | undefined>>} */
38
- const reexportedStatements = new Map();
39
- /** @type {[Module, number | undefined][]} */
40
- const edges = [];
41
-
42
- for (const connection of moduleGraph.getIncomingConnections(module)) {
43
- const origin = connection.originModule;
44
-
45
- // An entry has no origin: it is in the build because it was asked for.
46
- if (!origin) return false;
47
-
48
- const dependency = connection.dependency;
49
-
50
- // Only an ESM import statement can carry a re-export.
51
- if (!(dependency instanceof HarmonyImportDependency)) return false;
52
-
53
- if (dependency instanceof HarmonyExportImportedSpecifierDependency) {
54
- const statements = reexportedStatements.get(origin);
55
-
56
- if (statements === undefined) {
57
- reexportedStatements.set(origin, new Set([dependency.sourceOrder]));
58
- } else {
59
- statements.add(dependency.sourceOrder);
60
- }
61
- }
62
-
63
- edges.push([origin, dependency.sourceOrder]);
64
- }
65
-
66
- if (edges.length === 0) return false;
67
-
68
- for (const [origin, sourceOrder] of edges) {
69
- const statements = reexportedStatements.get(origin);
70
-
71
- if (statements === undefined || !statements.has(sourceOrder)) return false;
72
- }
73
-
74
- return true;
75
- };
76
-
77
23
  class UnusedReexportsPlugin {
78
24
  /**
79
25
  * Creates an instance of UnusedReexportsPlugin.
@@ -0,0 +1,65 @@
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 HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
9
+ const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
10
+
11
+ /** @import Module from "../Module" */
12
+ /** @import ModuleGraph from "../ModuleGraph" */
13
+
14
+ /**
15
+ * Tells whether every module pulling this one in does so by re-exporting it.
16
+ * One an importer wants for its side effects alone is deliberate, not a
17
+ * barrel's leftover.
18
+ * @param {Module} module the module to look up
19
+ * @param {ModuleGraph} moduleGraph the module graph
20
+ * @returns {boolean} true when only re-exports pull it in
21
+ */
22
+ const isOnlyReexported = (module, moduleGraph) => {
23
+ // A re-export emits a side-effect edge of its own, so edges are grouped by
24
+ // the statement they come from — `sourceOrder` — rather than by their type.
25
+ /** @type {Map<Module, Set<number | undefined>>} */
26
+ const reexportedStatements = new Map();
27
+ /** @type {[Module, number | undefined][]} */
28
+ const edges = [];
29
+
30
+ for (const connection of moduleGraph.getIncomingConnections(module)) {
31
+ const origin = connection.originModule;
32
+
33
+ // An entry has no origin: it is in the build because it was asked for.
34
+ if (!origin) return false;
35
+
36
+ const dependency = connection.dependency;
37
+
38
+ // Only an ESM import statement can carry a re-export.
39
+ if (!(dependency instanceof HarmonyImportDependency)) return false;
40
+
41
+ if (dependency instanceof HarmonyExportImportedSpecifierDependency) {
42
+ const statements = reexportedStatements.get(origin);
43
+
44
+ if (statements === undefined) {
45
+ reexportedStatements.set(origin, new Set([dependency.sourceOrder]));
46
+ } else {
47
+ statements.add(dependency.sourceOrder);
48
+ }
49
+ }
50
+
51
+ edges.push([origin, dependency.sourceOrder]);
52
+ }
53
+
54
+ if (edges.length === 0) return false;
55
+
56
+ for (const [origin, sourceOrder] of edges) {
57
+ const statements = reexportedStatements.get(origin);
58
+
59
+ if (statements === undefined || !statements.has(sourceOrder)) return false;
60
+ }
61
+
62
+ return true;
63
+ };
64
+
65
+ module.exports = isOnlyReexported;
@@ -6,6 +6,8 @@
6
6
 
7
7
  const RuntimeModule = require("../RuntimeModule");
8
8
  const Template = require("../Template");
9
+ const { getOnlyHandlerKey } = require("../util/handlerKeys");
10
+ const { propertyAccess } = require("../util/property");
9
11
 
10
12
  /** @import Compilation from "../Compilation" */
11
13
 
@@ -33,6 +35,17 @@ class ChunkPrefetchFunctionRuntimeModule extends RuntimeModule {
33
35
  this.runtimeHandlers = runtimeHandlers;
34
36
  }
35
37
 
38
+ /**
39
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
40
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
41
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
42
+ */
43
+ getInstalledChunkHandlers() {
44
+ // Reads a map rather than installing onto one, so reading its code back would
45
+ // render it in a cycle.
46
+ return RuntimeModule.NO_CHUNK_HANDLERS;
47
+ }
48
+
36
49
  /**
37
50
  * Generates runtime code for this runtime module.
38
51
  * @returns {string | null} runtime code
@@ -41,17 +54,24 @@ class ChunkPrefetchFunctionRuntimeModule extends RuntimeModule {
41
54
  const { runtimeFunction, runtimeHandlers } = this;
42
55
  const compilation = /** @type {Compilation} */ (this.compilation);
43
56
  const { runtimeTemplate } = compilation;
57
+ const only =
58
+ runtimeFunction === null
59
+ ? null
60
+ : getOnlyHandlerKey(this, runtimeHandlers);
44
61
  return Template.asString([
45
62
  `${runtimeHandlers} = {};`,
46
63
  ...(runtimeFunction === null
47
64
  ? []
48
65
  : [
49
66
  `${runtimeFunction} = ${runtimeTemplate.basicFunction("chunkId", [
50
- // map is shorter than forEach
51
- `Object.keys(${runtimeHandlers}).map(${runtimeTemplate.basicFunction(
52
- "key",
53
- `${runtimeHandlers}[key](chunkId);`
54
- )});`
67
+ // One handler needs no walk over the others, and most chunks carry one.
68
+ only === null
69
+ ? // map is shorter than forEach
70
+ `Object.keys(${runtimeHandlers}).map(${runtimeTemplate.basicFunction(
71
+ "key",
72
+ `${runtimeHandlers}[key](chunkId);`
73
+ )});`
74
+ : `${runtimeHandlers}${propertyAccess([only])}(chunkId);`
55
75
  ])};`
56
76
  ])
57
77
  ]);
@@ -50,6 +50,8 @@ class ChunkPrefetchPreloadPlugin {
50
50
  if (startupChildChunks) {
51
51
  set.add(RuntimeGlobals.prefetchChunk);
52
52
  set.add(RuntimeGlobals.onChunksLoaded);
53
+ // This is the one startup callback that is queued behind a priority.
54
+ set.add(RuntimeGlobals.hasChunkPriority);
53
55
  set.add(RuntimeGlobals.exports);
54
56
  compilation.addLazyRuntimeModule(
55
57
  chunk,
@@ -21,6 +21,15 @@ class ChunkPrefetchStartupRuntimeModule extends RuntimeModule {
21
21
  this.startupChunks = startupChunks;
22
22
  }
23
23
 
24
+ /**
25
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
26
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
27
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
28
+ */
29
+ getInstalledChunkHandlers() {
30
+ return RuntimeModule.NO_CHUNK_HANDLERS;
31
+ }
32
+
24
33
  /**
25
34
  * Generates runtime code for this runtime module.
26
35
  * @returns {string | null} runtime code
@@ -21,6 +21,15 @@ class ChunkPrefetchTriggerRuntimeModule extends RuntimeModule {
21
21
  this.chunkMap = chunkMap;
22
22
  }
23
23
 
24
+ /**
25
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
26
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
27
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
28
+ */
29
+ getInstalledChunkHandlers() {
30
+ return [[RuntimeGlobals.ensureChunkHandlers, "prefetch"]];
31
+ }
32
+
24
33
  /**
25
34
  * Generates runtime code for this runtime module.
26
35
  * @returns {string | null} runtime code
@@ -24,6 +24,15 @@ class ChunkPreloadTriggerRuntimeModule extends RuntimeModule {
24
24
  this.handlerKey = handlerKey;
25
25
  }
26
26
 
27
+ /**
28
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
29
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
30
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
31
+ */
32
+ getInstalledChunkHandlers() {
33
+ return [[RuntimeGlobals.ensureChunkHandlers, this.handlerKey]];
34
+ }
35
+
27
36
  /**
28
37
  * Generates runtime code for this runtime module.
29
38
  * @returns {string | null} runtime code
@@ -300,7 +300,12 @@ const collectEntrypointHints = (compilation, entryName, hints) => {
300
300
  const out = [];
301
301
  /** @type {Set<string>} */
302
302
  const seenKeys = new Set();
303
- const push = (/** @type {EntrypointHint} */ h) => {
303
+ /**
304
+ * Appends a hint, dropping one already emitted for the same rel + href.
305
+ * @param {EntrypointHint} h hint to append
306
+ * @returns {void}
307
+ */
308
+ const push = (h) => {
304
309
  const key = `${h.rel}\0${h.href}`;
305
310
  if (seenKeys.has(key)) return;
306
311
  seenKeys.add(key);
@@ -485,8 +490,7 @@ const collectStartupAssetHintLines = (
485
490
  dep.options.publicPath,
486
491
  workerChunk,
487
492
  module,
488
- chunkGraph,
489
- set
493
+ chunkGraph
490
494
  );
491
495
  // Without one the call site keeps the runtime form, where it wraps its own
492
496
  // href — firing the `<link>` here too would emit the call twice.
@@ -50,6 +50,15 @@ class ResourceHintRuntimeModule extends RuntimeModule {
50
50
  this._rel = rel;
51
51
  }
52
52
 
53
+ /**
54
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
55
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
56
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
57
+ */
58
+ getInstalledChunkHandlers() {
59
+ return RuntimeModule.NO_CHUNK_HANDLERS;
60
+ }
61
+
53
62
  /**
54
63
  * Generates runtime code for this runtime module.
55
64
  * @returns {string | null} runtime code
@@ -30,6 +30,15 @@ class StartupAssetHintRuntimeModule extends RuntimeModule {
30
30
  this._lines = lines;
31
31
  }
32
32
 
33
+ /**
34
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
35
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
36
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
37
+ */
38
+ getInstalledChunkHandlers() {
39
+ return RuntimeModule.NO_CHUNK_HANDLERS;
40
+ }
41
+
33
42
  /**
34
43
  * Generates runtime code for this runtime module.
35
44
  * @returns {string | null} runtime code