webpack 5.108.4 → 5.109.1

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 (200) hide show
  1. package/bin/webpack.js +12 -0
  2. package/lib/APIPlugin.js +48 -29
  3. package/lib/CacheFacade.js +8 -0
  4. package/lib/ChunkGraph.js +17 -15
  5. package/lib/ChunkGroup.js +1 -0
  6. package/lib/CompatibilityPlugin.js +62 -29
  7. package/lib/Compilation.js +58 -6
  8. package/lib/ConstPlugin.js +11 -11
  9. package/lib/ContextModule.js +239 -6
  10. package/lib/ContextModuleFactory.js +139 -14
  11. package/lib/DefinePlugin.js +433 -112
  12. package/lib/Entrypoint.js +1 -1
  13. package/lib/ExportsInfo.js +22 -5
  14. package/lib/ExportsInfoApiPlugin.js +2 -2
  15. package/lib/ExternalModule.js +107 -5
  16. package/lib/ExternalModuleFactoryPlugin.js +20 -1
  17. package/lib/FileSystemInfo.js +256 -100
  18. package/lib/FlagDependencyUsagePlugin.js +33 -12
  19. package/lib/HotModuleReplacementPlugin.js +18 -15
  20. package/lib/InitFragment.js +20 -32
  21. package/lib/Module.js +3 -0
  22. package/lib/ModuleFilenameHelpers.js +2 -2
  23. package/lib/ModuleTypeConstants.js +8 -1
  24. package/lib/MultiCompiler.js +13 -2
  25. package/lib/MultiWatching.js +1 -0
  26. package/lib/NodeStuffPlugin.js +51 -33
  27. package/lib/NormalModule.js +175 -401
  28. package/lib/NormalModuleFactory.js +76 -2
  29. package/lib/ProgressPlugin.js +211 -119
  30. package/lib/ProvidePlugin.js +2 -2
  31. package/lib/RuntimeGlobals.js +47 -0
  32. package/lib/RuntimePlugin.js +67 -107
  33. package/lib/RuntimeTemplate.js +304 -16
  34. package/lib/Template.js +23 -3
  35. package/lib/UseStrictPlugin.js +1 -1
  36. package/lib/WebpackIsIncludedPlugin.js +1 -1
  37. package/lib/WebpackOptionsApply.js +24 -19
  38. package/lib/asset/AssetGenerator.js +110 -28
  39. package/lib/asset/AssetModulesPlugin.js +92 -2
  40. package/lib/asset/WebManifestGenerator.js +164 -0
  41. package/lib/asset/WebManifestParser.js +130 -0
  42. package/lib/async-modules/AwaitDependenciesInitFragment.js +14 -4
  43. package/lib/async-modules/isGeneratorLowered.js +26 -0
  44. package/lib/cache/PackFileCacheStrategy.js +9 -3
  45. package/lib/config/browserslistTargetHandler.js +40 -0
  46. package/lib/config/defaults.js +219 -29
  47. package/lib/config/normalization.js +26 -0
  48. package/lib/config/target.js +9 -1
  49. package/lib/container/HoistContainerReferencesPlugin.js +47 -55
  50. package/lib/css/CssGenerator.js +40 -31
  51. package/lib/css/CssLoadingRuntimeModule.js +5 -1
  52. package/lib/css/CssModulesPlugin.js +13 -0
  53. package/lib/css/CssParser.js +729 -313
  54. package/lib/css/syntax.js +1371 -861
  55. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -6
  56. package/lib/dependencies/AMDPlugin.js +2 -2
  57. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +13 -13
  58. package/lib/dependencies/CommonJsDependencyHelpers.js +39 -0
  59. package/lib/dependencies/CommonJsExportRequireDependency.js +19 -0
  60. package/lib/dependencies/CommonJsExportsDependency.js +47 -2
  61. package/lib/dependencies/CommonJsExportsParserPlugin.js +10 -10
  62. package/lib/dependencies/CommonJsImportsParserPlugin.js +18 -18
  63. package/lib/dependencies/CommonJsPlugin.js +2 -2
  64. package/lib/dependencies/CommonJsRequireDependency.js +26 -1
  65. package/lib/dependencies/CommonJsSelfReferenceDependency.js +32 -1
  66. package/lib/dependencies/ContextDependencyHelpers.js +3 -3
  67. package/lib/dependencies/CreateRequireParserPlugin.js +6 -6
  68. package/lib/dependencies/CssIcssExportDependency.js +162 -71
  69. package/lib/dependencies/CssUrlDependency.js +35 -4
  70. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +2 -2
  71. package/lib/dependencies/HarmonyCompatibilityDependency.js +32 -14
  72. package/lib/dependencies/HarmonyDetectionParserPlugin.js +43 -13
  73. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +2 -1
  74. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +7 -19
  75. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +17 -9
  76. package/lib/dependencies/HarmonyImportDependency.js +13 -2
  77. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +11 -11
  78. package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -7
  79. package/lib/dependencies/HarmonyModulesPlugin.js +6 -0
  80. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +1 -1
  81. package/lib/dependencies/HtmlEntryDependency.js +797 -172
  82. package/lib/dependencies/HtmlSourceDependency.js +26 -0
  83. package/lib/dependencies/ImportDependency.js +43 -1
  84. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +31 -18
  85. package/lib/dependencies/ImportMetaContextPlugin.js +38 -7
  86. package/lib/dependencies/ImportMetaGlobDependency.js +81 -0
  87. package/lib/dependencies/ImportMetaGlobDependencyParserPlugin.js +78 -0
  88. package/lib/dependencies/ImportMetaGlobHelpers.js +660 -0
  89. package/lib/dependencies/ImportMetaPlugin.js +532 -180
  90. package/lib/dependencies/ImportMetaResolveDependency.js +90 -0
  91. package/lib/dependencies/ImportParserPlugin.js +80 -17
  92. package/lib/dependencies/ImportPhase.js +10 -8
  93. package/lib/dependencies/LoaderPlugin.js +5 -1
  94. package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
  95. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +3 -6
  96. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +4 -11
  97. package/lib/dependencies/SystemPlugin.js +2 -4
  98. package/lib/dependencies/TopLevelAwaitDependency.js +93 -0
  99. package/lib/dependencies/URLDependency.js +141 -21
  100. package/lib/dependencies/{WorkerPlugin.js → WorkerAndWorkletPlugin.js} +324 -112
  101. package/lib/dependencies/WorkerDependency.js +86 -18
  102. package/lib/dependencies/WorkletDependency.js +278 -0
  103. package/lib/dll/DelegatedModuleFactoryPlugin.js +19 -0
  104. package/lib/errors/EnvironmentNotSupportAsyncWarning.js +1 -1
  105. package/lib/errors/LoaderLoadingError.js +20 -0
  106. package/lib/errors/ModuleParseError.js +39 -22
  107. package/lib/errors/NodeStuffInWebError.js +1 -1
  108. package/lib/esm/ModuleChunkFormatPlugin.js +47 -14
  109. package/lib/esm/ModuleChunkLoadingPlugin.js +8 -1
  110. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +29 -1
  111. package/lib/hmr/lazyCompilationBackend.js +51 -12
  112. package/lib/html/HtmlGenerator.js +907 -15
  113. package/lib/html/HtmlModule.js +2 -2
  114. package/lib/html/HtmlModulesPlugin.js +610 -166
  115. package/lib/html/HtmlParser.js +603 -247
  116. package/lib/html/favicon.svg +1 -0
  117. package/lib/html/syntax.js +3451 -2762
  118. package/lib/ids/IdHelpers.js +25 -11
  119. package/lib/index.js +6 -0
  120. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +4 -5
  121. package/lib/javascript/BasicEvaluatedExpression.js +366 -48
  122. package/lib/javascript/JavascriptGenerator.js +197 -49
  123. package/lib/javascript/JavascriptModulesPlugin.js +178 -24
  124. package/lib/javascript/JavascriptParser.js +704 -355
  125. package/lib/javascript/JavascriptParserHelpers.js +3 -6
  126. package/lib/javascript/syntax.js +5037 -0
  127. package/lib/library/ModuleLibraryPlugin.js +38 -1
  128. package/lib/loaders/LoaderRunner.js +714 -0
  129. package/lib/loaders/loadLoader.js +100 -0
  130. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +29 -2
  131. package/lib/node/ReadFileCompileWasmPlugin.js +24 -2
  132. package/lib/optimize/AggressiveMergingPlugin.js +19 -15
  133. package/lib/optimize/ConcatenatedModule.js +139 -31
  134. package/lib/optimize/FlagIncludedChunksPlugin.js +13 -3
  135. package/lib/optimize/InnerGraphPlugin.js +50 -30
  136. package/lib/optimize/ModuleConcatenationPlugin.js +139 -24
  137. package/lib/optimize/SideEffectsFlagPlugin.js +86 -43
  138. package/lib/optimize/SplitChunksPlugin.js +146 -44
  139. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +15 -0
  140. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +24 -13
  141. package/lib/prefetch/ResourceHintPlugin.js +687 -0
  142. package/lib/prefetch/ResourceHintRuntimeModule.js +149 -0
  143. package/lib/prefetch/StartupAssetHintRuntimeModule.js +210 -0
  144. package/lib/prefetch/parseResourceHintOptions.js +103 -0
  145. package/lib/rules/RuleSetCompiler.js +114 -0
  146. package/lib/runtime/AsyncModuleGeneratorRuntimeModule.js +56 -0
  147. package/lib/runtime/AsyncModuleRuntimeModule.js +24 -8
  148. package/lib/runtime/AutoPublicPathRuntimeModule.js +7 -1
  149. package/lib/runtime/CommonJsWrapRuntimeModule.js +37 -0
  150. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +59 -0
  151. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +204 -8
  152. package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +4 -1
  153. package/lib/schemes/HttpUriPlugin.js +40 -1
  154. package/lib/schemes/VirtualUrlPlugin.js +1 -2
  155. package/lib/serialization/BinaryMiddleware.js +270 -938
  156. package/lib/serialization/FileMiddleware.js +29 -3
  157. package/lib/stats/DefaultStatsFactoryPlugin.js +229 -194
  158. package/lib/stats/DefaultStatsPresetPlugin.js +2 -0
  159. package/lib/stats/DefaultStatsPrinterPlugin.js +36 -168
  160. package/lib/stats/StatsFactory.js +46 -17
  161. package/lib/url/URLParserPlugin.js +66 -13
  162. package/lib/util/AsyncQueue.js +122 -72
  163. package/lib/util/SetHelpers.js +1 -1
  164. package/lib/util/StackedMap.js +122 -48
  165. package/lib/util/binarySearchBounds.js +2 -2
  166. package/lib/util/concatenate.js +40 -14
  167. package/lib/util/createHooksRegistry.js +13 -5
  168. package/lib/util/dataURL.js +2 -2
  169. package/lib/util/deterministicGrouping.js +7 -5
  170. package/lib/util/formatSize.js +6 -2
  171. package/lib/util/globUtils.js +710 -0
  172. package/lib/util/identifier.js +23 -6
  173. package/lib/util/implicitTypeLoaderFallback.js +62 -0
  174. package/lib/util/internalSerializables.js +88 -71
  175. package/lib/util/magicComment.js +121 -25
  176. package/lib/util/numberHash.js +2 -2
  177. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +24 -18
  178. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +33 -22
  179. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +79 -16
  180. package/lib/web/FetchCompileAsyncWasmPlugin.js +19 -0
  181. package/lib/web/FetchCompileWasmPlugin.js +14 -0
  182. package/lib/web/JsonpChunkLoadingRuntimeModule.js +2 -0
  183. package/lib/webpack.js +65 -0
  184. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +3 -0
  185. package/module.d.ts +21 -0
  186. package/package.json +12 -11
  187. package/schemas/WebpackOptions.check.js +1 -1
  188. package/schemas/WebpackOptions.json +759 -36
  189. package/schemas/plugins/HtmlParserOptions.check.js +1 -1
  190. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  191. package/schemas/plugins/ProgressPlugin.json +17 -1
  192. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  193. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  194. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  195. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  196. package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
  197. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +1 -1
  198. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  199. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  200. package/types.d.ts +1212 -99
@@ -0,0 +1,100 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const { pathToFileURL } = require("url");
9
+ const LoaderLoadingError = require("../errors/LoaderLoadingError");
10
+
11
+ /** @typedef {import("./LoaderRunner").LoaderObject} LoaderObject */
12
+
13
+ /**
14
+ * Lazily-compiled dynamic `import()`. Built on first use so this file still
15
+ * parses on Node versions without native `import()` (<13.2), then reused.
16
+ * @type {((url: URL) => Promise<EXPECTED_ANY>) | undefined}
17
+ */
18
+ let importModule;
19
+
20
+ /**
21
+ * @param {LoaderObject} loader the loader to load into
22
+ * @param {EXPECTED_ANY} module the loaded module
23
+ * @param {(err?: Error) => void} callback callback
24
+ * @returns {void}
25
+ */
26
+ function handleResult(loader, module, callback) {
27
+ if (typeof module !== "function" && typeof module !== "object") {
28
+ return callback(
29
+ new LoaderLoadingError(
30
+ `Module '${loader.path}' is not a loader (export function or es6 module)`
31
+ )
32
+ );
33
+ }
34
+
35
+ loader.normal = typeof module === "function" ? module : module.default;
36
+ loader.pitch = module.pitch;
37
+ loader.raw = module.raw;
38
+
39
+ if (
40
+ typeof loader.normal !== "function" &&
41
+ typeof loader.pitch !== "function"
42
+ ) {
43
+ return callback(
44
+ new LoaderLoadingError(
45
+ `Module '${loader.path}' is not a loader (must have normal or pitch function)`
46
+ )
47
+ );
48
+ }
49
+ callback();
50
+ }
51
+
52
+ /**
53
+ * @param {LoaderObject} loader the loader to load
54
+ * @param {(err?: Error) => void} callback callback
55
+ * @returns {void}
56
+ */
57
+ function loadLoader(loader, callback) {
58
+ if (loader.type === "module") {
59
+ try {
60
+ if (importModule === undefined) {
61
+ // `eval` defers parsing `import()` to runtime, so this file stays
62
+ // loadable on Node versions that can't parse it (<13.2).
63
+ // eslint-disable-next-line no-eval
64
+ const dynamicImport = eval("(url) => import(url)");
65
+ importModule = /** @type {(url: URL) => Promise<EXPECTED_ANY>} */ (
66
+ dynamicImport
67
+ );
68
+ }
69
+
70
+ importModule(pathToFileURL(loader.path)).then(
71
+ (/** @type {EXPECTED_ANY} */ module) => {
72
+ handleResult(loader, module, callback);
73
+ },
74
+ callback
75
+ );
76
+ } catch (err) {
77
+ callback(/** @type {Error} */ (err));
78
+ }
79
+ return;
80
+ }
81
+
82
+ let loadedModule;
83
+ try {
84
+ loadedModule = require(loader.path);
85
+ } catch (err) {
86
+ // node can choke on require when the FD limit is hit; defer to recover.
87
+ if (
88
+ err instanceof Error &&
89
+ /** @type {NodeJS.ErrnoException} */ (err).code === "EMFILE"
90
+ ) {
91
+ setImmediate(loadLoader, loader, callback);
92
+ return;
93
+ }
94
+ return callback(/** @type {Error} */ (err));
95
+ }
96
+
97
+ return handleResult(loader, loadedModule, callback);
98
+ }
99
+
100
+ module.exports = loadLoader;
@@ -8,12 +8,21 @@
8
8
  const { WEBASSEMBLY_MODULE_TYPE_ASYNC } = require("../ModuleTypeConstants");
9
9
  const RuntimeGlobals = require("../RuntimeGlobals");
10
10
  const Template = require("../Template");
11
+ const { getPresentKinds } = require("../TemplatedPathPlugin");
11
12
  const AsyncWasmCompileRuntimeModule = require("../wasm-async/AsyncWasmCompileRuntimeModule");
12
13
  const AsyncWasmLoadingRuntimeModule = require("../wasm-async/AsyncWasmLoadingRuntimeModule");
13
14
 
14
15
  /** @typedef {import("../Chunk")} Chunk */
15
16
  /** @typedef {import("../Compiler")} Compiler */
16
17
 
18
+ /**
19
+ * The wasm runtime inlines `[fullhash]` as a runtime `getFullHash()` call, so
20
+ * that runtime module must be requested (`[hash]` is the per-module hash here).
21
+ * @param {string} filename `output.webassemblyModuleFilename`
22
+ * @returns {boolean} whether it references the compilation `[fullhash]`
23
+ */
24
+ const usesFullHash = (filename) => getPresentKinds(filename).has("fullhash");
25
+
17
26
  /**
18
27
  * Defines the read file compile async wasm plugin options type used by this module.
19
28
  * @typedef {object} ReadFileCompileAsyncWasmPluginOptions
@@ -68,7 +77,11 @@ class ReadFileCompileAsyncWasmPlugin {
68
77
  "",
69
78
  "// Fake fetch response",
70
79
  "resolve({",
71
- Template.indent(["arrayBuffer() { return buffer; }"]),
80
+ Template.indent([
81
+ // Return a real ArrayBuffer: some runtimes (e.g. Deno)
82
+ // reject a Node Buffer view here as "not a buffer source".
83
+ "arrayBuffer() { return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength); }"
84
+ ]),
72
85
  "});"
73
86
  ]),
74
87
  "});"
@@ -90,7 +103,11 @@ class ReadFileCompileAsyncWasmPlugin {
90
103
  "",
91
104
  "// Fake fetch response",
92
105
  "resolve({",
93
- Template.indent(["arrayBuffer() { return buffer; }"]),
106
+ Template.indent([
107
+ // Return a real ArrayBuffer: some runtimes (e.g. Deno)
108
+ // reject a Node Buffer view here as "not a buffer source".
109
+ "arrayBuffer() { return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength); }"
110
+ ]),
94
111
  "});"
95
112
  ]),
96
113
  "});"
@@ -112,6 +129,11 @@ class ReadFileCompileAsyncWasmPlugin {
112
129
  ) {
113
130
  return;
114
131
  }
132
+ if (
133
+ usesFullHash(compilation.outputOptions.webassemblyModuleFilename)
134
+ ) {
135
+ set.add(RuntimeGlobals.getFullHash);
136
+ }
115
137
  compilation.addRuntimeModule(
116
138
  chunk,
117
139
  new AsyncWasmLoadingRuntimeModule({
@@ -133,6 +155,11 @@ class ReadFileCompileAsyncWasmPlugin {
133
155
  ) {
134
156
  return;
135
157
  }
158
+ if (
159
+ usesFullHash(compilation.outputOptions.webassemblyModuleFilename)
160
+ ) {
161
+ set.add(RuntimeGlobals.getFullHash);
162
+ }
136
163
  compilation.addRuntimeModule(
137
164
  chunk,
138
165
  new AsyncWasmCompileRuntimeModule({
@@ -8,11 +8,20 @@
8
8
  const { WEBASSEMBLY_MODULE_TYPE_SYNC } = require("../ModuleTypeConstants");
9
9
  const RuntimeGlobals = require("../RuntimeGlobals");
10
10
  const Template = require("../Template");
11
+ const { getPresentKinds } = require("../TemplatedPathPlugin");
11
12
  const WasmChunkLoadingRuntimeModule = require("../wasm-sync/WasmChunkLoadingRuntimeModule");
12
13
 
13
14
  /** @typedef {import("../Chunk")} Chunk */
14
15
  /** @typedef {import("../Compiler")} Compiler */
15
16
 
17
+ /**
18
+ * The wasm runtime inlines `[fullhash]` as a runtime `getFullHash()` call, so
19
+ * that runtime module must be requested (`[hash]` is the per-module hash here).
20
+ * @param {string} filename `output.webassemblyModuleFilename`
21
+ * @returns {boolean} whether it references the compilation `[fullhash]`
22
+ */
23
+ const usesFullHash = (filename) => getPresentKinds(filename).has("fullhash");
24
+
16
25
  /**
17
26
  * Defines the read file compile wasm plugin options type used by this module.
18
27
  * @typedef {object} ReadFileCompileWasmPluginOptions
@@ -68,7 +77,11 @@ class ReadFileCompileWasmPlugin {
68
77
  "",
69
78
  "// Fake fetch response",
70
79
  "resolve({",
71
- Template.indent(["arrayBuffer() { return buffer; }"]),
80
+ Template.indent([
81
+ // Return a real ArrayBuffer: some runtimes (e.g. Deno)
82
+ // reject a Node Buffer view here as "not a buffer source".
83
+ "arrayBuffer() { return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength); }"
84
+ ]),
72
85
  "});"
73
86
  ]),
74
87
  "});"
@@ -90,7 +103,11 @@ class ReadFileCompileWasmPlugin {
90
103
  "",
91
104
  "// Fake fetch response",
92
105
  "resolve({",
93
- Template.indent(["arrayBuffer() { return buffer; }"]),
106
+ Template.indent([
107
+ // Return a real ArrayBuffer: some runtimes (e.g. Deno)
108
+ // reject a Node Buffer view here as "not a buffer source".
109
+ "arrayBuffer() { return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength); }"
110
+ ]),
94
111
  "});"
95
112
  ]),
96
113
  "});"
@@ -113,6 +130,11 @@ class ReadFileCompileWasmPlugin {
113
130
  return;
114
131
  }
115
132
  set.add(RuntimeGlobals.moduleCache);
133
+ if (
134
+ usesFullHash(compilation.outputOptions.webassemblyModuleFilename)
135
+ ) {
136
+ set.add(RuntimeGlobals.getFullHash);
137
+ }
116
138
  compilation.addRuntimeModule(
117
139
  chunk,
118
140
  new WasmChunkLoadingRuntimeModule({
@@ -53,8 +53,16 @@ class AggressiveMergingPlugin {
53
53
  },
54
54
  (chunks) => {
55
55
  const chunkGraph = compilation.chunkGraph;
56
- /** @type {{ a: Chunk, b: Chunk, improvement: number }[]} */
57
- const combinations = [];
56
+ // Only the single best pair is merged per pass (the hook re-runs
57
+ // after each merge), so track the max directly instead of building
58
+ // and sorting the full O(chunks²) list of pairs every pass. A strict
59
+ // `>` keeps the first-encountered best, matching the previous stable
60
+ // descending sort's `[0]`.
61
+ /** @type {Chunk | undefined} */
62
+ let bestA;
63
+ /** @type {Chunk | undefined} */
64
+ let bestB;
65
+ let bestImprovement = -Infinity;
58
66
  for (const a of chunks) {
59
67
  if (a.canBeInitial()) continue;
60
68
  for (const b of chunks) {
@@ -73,23 +81,19 @@ class AggressiveMergingPlugin {
73
81
  chunkOverhead: 0
74
82
  });
75
83
  const improvement = (aSize + bSize) / abSize;
76
- combinations.push({
77
- a,
78
- b,
79
- improvement
80
- });
84
+ if (improvement > bestImprovement) {
85
+ bestImprovement = improvement;
86
+ bestA = a;
87
+ bestB = b;
88
+ }
81
89
  }
82
90
  }
83
91
 
84
- combinations.sort((a, b) => b.improvement - a.improvement);
85
-
86
- const pair = combinations[0];
87
-
88
- if (!pair) return;
89
- if (pair.improvement < minSizeReduce) return;
92
+ if (bestA === undefined) return;
93
+ if (bestImprovement < minSizeReduce) return;
90
94
 
91
- chunkGraph.integrateChunks(pair.b, pair.a);
92
- compilation.chunks.delete(pair.a);
95
+ chunkGraph.integrateChunks(/** @type {Chunk} */ (bestB), bestA);
96
+ compilation.chunks.delete(bestA);
93
97
  return true;
94
98
  }
95
99
  );
@@ -26,8 +26,11 @@ const RuntimeGlobals = require("../RuntimeGlobals");
26
26
  const Template = require("../Template");
27
27
  const { DEFAULTS } = require("../config/defaults");
28
28
  const { ImportPhaseUtils } = require("../dependencies/ImportPhase");
29
+ const { isCommonJsWrapped } = require("../javascript/JavascriptGenerator");
29
30
  const JavascriptParser = require("../javascript/JavascriptParser");
30
31
  const {
32
+ getDeferredCycleModuleIds,
33
+ getDeferredCycleModules,
31
34
  getMakeDeferredNamespaceModeFromExportsType,
32
35
  getOptimizedDeferredModule
33
36
  } = require("../runtime/MakeDeferredNamespaceObjectRuntime");
@@ -82,6 +85,7 @@ const { InlinedUsedName } = require("./InlineExports");
82
85
  /** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
83
86
  /** @typedef {import("../Module").SourceTypes} SourceTypes */
84
87
  /** @typedef {import("../ModuleGraph")} ModuleGraph */
88
+ /** @typedef {import("../NormalModule")} NormalModule */
85
89
  /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
86
90
  /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
87
91
  /** @typedef {import("../RequestShortener")} RequestShortener */
@@ -95,6 +99,7 @@ const { InlinedUsedName } = require("./InlineExports");
95
99
  /** @typedef {import("../javascript/JavascriptModulesPlugin").Variable} Variable */
96
100
  /** @typedef {import("../javascript/JavascriptParser").Program} Program */
97
101
  /** @typedef {import("../javascript/JavascriptParser").Range} Range */
102
+ /** @typedef {import("estree").Identifier} Identifier */
98
103
  /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
99
104
  /** @typedef {import("../util/Hash")} Hash */
100
105
  /** @typedef {import("../util/Hash").HashFunction} HashFunction */
@@ -153,6 +158,7 @@ if (!ReferencerClass.prototype.PropertyDefinition) {
153
158
  * @property {"concatenated"} type
154
159
  * @property {Module} module
155
160
  * @property {number} index
161
+ * @property {boolean=} cjsWrapped a "weird" CommonJS module executed via the CJS wrapper runtime helper with real module/exports objects
156
162
  * @property {Program | undefined} ast
157
163
  * @property {Source | undefined} internalSource
158
164
  * @property {ReplaceSource | undefined} source
@@ -354,6 +360,9 @@ const getFinalBinding = (
354
360
  if (exportName.length === 0) {
355
361
  switch (exportsType) {
356
362
  case "default-only":
363
+ // a concatenated CommonJS module has no runtime exports object;
364
+ // its fake namespace is built over the generated namespace object
365
+ if (info.type === "concatenated") neededNamespaceObjects.add(info);
357
366
  if (deferred) info.deferredNamespaceObjectUsed = true;
358
367
  else info.interopNamespaceObject2Used = true;
359
368
  return {
@@ -367,6 +376,7 @@ const getFinalBinding = (
367
376
  exportName
368
377
  };
369
378
  case "default-with-named":
379
+ if (info.type === "concatenated") neededNamespaceObjects.add(info);
370
380
  if (deferred) info.deferredNamespaceObjectUsed = true;
371
381
  else info.interopNamespaceObjectUsed = true;
372
382
  return {
@@ -657,7 +667,9 @@ const getFinalBinding = (
657
667
  alreadyVisited
658
668
  );
659
669
  }
660
- if (info.namespaceExportSymbol) {
670
+ // A wrapped module resolves every export through its live exports
671
+ // alias (namespaceObjectName), same as namespaceExportSymbol modules.
672
+ if (info.namespaceExportSymbol || info.cjsWrapped) {
661
673
  const usedName = /** @type {ExportName} */ (
662
674
  exportsInfo.getUsedName(exportName, runtime)
663
675
  );
@@ -985,20 +997,32 @@ class ConcatenatedModule extends Module {
985
997
 
986
998
  for (const m of this._modules) {
987
999
  // populate cacheable
988
- if (!(/** @type {BuildInfo} */ (m.buildInfo).cacheable)) {
1000
+ const { cacheable, notCacheableReasons } = /** @type {BuildInfo} */ (
1001
+ m.buildInfo
1002
+ );
1003
+ if (!cacheable) {
989
1004
  this.buildInfo.cacheable = false;
1005
+ if (notCacheableReasons) {
1006
+ const reasons =
1007
+ this.buildInfo.notCacheableReasons ||
1008
+ (this.buildInfo.notCacheableReasons = []);
1009
+ for (const reason of notCacheableReasons) {
1010
+ if (!reasons.includes(reason)) reasons.push(reason);
1011
+ }
1012
+ }
990
1013
  }
991
1014
 
992
- // populate dependencies
993
- for (const d of m.dependencies.filter(
994
- (dep) =>
995
- !Dependency.canConcatenate(dep) ||
1015
+ // populate dependencies — keep only deps that leave the concat set
1016
+ for (const d of m.dependencies) {
1017
+ if (
1018
+ !Dependency.canConcatenate(d) ||
996
1019
  !this._modules.has(
997
1020
  /** @type {Module} */
998
- (compilation.moduleGraph.getModule(dep))
1021
+ (compilation.moduleGraph.getModule(d))
999
1022
  )
1000
- )) {
1001
- this.dependencies.push(d);
1023
+ ) {
1024
+ this.dependencies.push(d);
1025
+ }
1002
1026
  }
1003
1027
  // populate codeGenerationDependencies — the inner modules'
1004
1028
  // templates are applied during ConcatenatedModule.codeGeneration,
@@ -1517,7 +1541,7 @@ class ConcatenatedModule extends Module {
1517
1541
 
1518
1542
  // get all global names
1519
1543
  for (const info of modulesWithInfo) {
1520
- if (info.type === "concatenated") {
1544
+ if (info.type === "concatenated" && !info.cjsWrapped) {
1521
1545
  // ignore symbols from moduleScope
1522
1546
  if (info.moduleScope) {
1523
1547
  ignoredScopes.add(info.moduleScope);
@@ -1707,6 +1731,23 @@ class ConcatenatedModule extends Module {
1707
1731
  );
1708
1732
  switch (info.type) {
1709
1733
  case "concatenated": {
1734
+ if (info.cjsWrapped) {
1735
+ // Wrapped modules expose one shared-scope name: the final
1736
+ // exports object used as the namespace.
1737
+ const namespaceObjectName = findNewName(
1738
+ "namespaceObject",
1739
+ allUsedNames,
1740
+ namespaceObjectUsedNames,
1741
+ info.module.readableIdentifier(requestShortener)
1742
+ );
1743
+ allUsedNames.add(namespaceObjectName);
1744
+ topLevelDeclarations.add(namespaceObjectName);
1745
+ info.namespaceObjectName = namespaceObjectName;
1746
+ // Route every binding to the live exports alias and skip the
1747
+ // materialized namespace object generated for other modules.
1748
+ info.namespaceExportSymbol = namespaceObjectName;
1749
+ break;
1750
+ }
1710
1751
  const variables = /** @type {Scope} */ (info.moduleScope).variables;
1711
1752
  for (const variable of variables) {
1712
1753
  const name = variable.name;
@@ -1714,10 +1755,12 @@ class ConcatenatedModule extends Module {
1714
1755
  const newName = _findNewName(name, info, references);
1715
1756
  if (newName) {
1716
1757
  const source = /** @type {ReplaceSource} */ (info.source);
1717
- const allIdentifiers = new Set([
1718
- ...references.map((r) => r.identifier),
1719
- ...variable.identifiers
1720
- ]);
1758
+ /** @type {Set<Identifier>} */
1759
+ const allIdentifiers = new Set();
1760
+ for (const r of references) allIdentifiers.add(r.identifier);
1761
+ for (const identifier of variable.identifiers) {
1762
+ allIdentifiers.add(identifier);
1763
+ }
1721
1764
  for (const identifier of allIdentifiers) {
1722
1765
  const r = /** @type {Range} */ (identifier.range);
1723
1766
  const path = getPathInAst(
@@ -1843,18 +1886,18 @@ class ConcatenatedModule extends Module {
1843
1886
 
1844
1887
  // Find and replace references to modules
1845
1888
  for (const info of moduleToInfoMap.values()) {
1846
- if (info.type === "concatenated") {
1889
+ if (info.type === "concatenated" && !info.cjsWrapped) {
1847
1890
  const globalScope = /** @type {Scope} */ (info.globalScope);
1848
1891
  // group references by name
1849
1892
  /** @type {Map<string, Reference[]>} */
1850
1893
  const referencesByName = new Map();
1851
1894
  for (const reference of globalScope.through) {
1852
1895
  const name = reference.identifier.name;
1853
- if (!referencesByName.has(name)) {
1854
- referencesByName.set(name, []);
1896
+ let references = referencesByName.get(name);
1897
+ if (references === undefined) {
1898
+ referencesByName.set(name, (references = []));
1855
1899
  }
1856
- /** @type {Reference[]} */
1857
- (referencesByName.get(name)).push(reference);
1900
+ references.push(reference);
1858
1901
  }
1859
1902
  for (const [name, references] of referencesByName) {
1860
1903
  const match = ConcatenationScope.matchModuleReference(name);
@@ -2081,7 +2124,9 @@ class ConcatenatedModule extends Module {
2081
2124
  if (!usedName) continue;
2082
2125
  if (usedName instanceof InlinedUsedName) {
2083
2126
  nsObj.push(
2084
- `\n ${propertyName(exportInfo.name)}: ${runtimeTemplate.returningFunction(
2127
+ `\n ${propertyName(
2128
+ exportInfo.name
2129
+ )}: ${runtimeTemplate.returningFunction(
2085
2130
  usedName.render(
2086
2131
  Template.toNormalComment(
2087
2132
  `inlined export ${propertyAccess([exportInfo.name])}`
@@ -2094,7 +2139,9 @@ class ConcatenatedModule extends Module {
2094
2139
  // import variable; concatenated ones resolve to an internal binding.
2095
2140
  const finalName =
2096
2141
  info.type === "external"
2097
- ? `${/** @type {string} */ (info.name)}${propertyAccess([usedName])}`
2142
+ ? `${/** @type {string} */ (info.name)}${propertyAccess([
2143
+ usedName
2144
+ ])}`
2098
2145
  : getFinalName(
2099
2146
  moduleGraph,
2100
2147
  info,
@@ -2112,9 +2159,9 @@ class ConcatenatedModule extends Module {
2112
2159
  true
2113
2160
  );
2114
2161
  nsObj.push(
2115
- `\n ${propertyName(exportInfo.name)}: ${runtimeTemplate.returningFunction(
2116
- finalName
2117
- )}`
2162
+ `\n ${propertyName(
2163
+ exportInfo.name
2164
+ )}: ${runtimeTemplate.returningFunction(finalName)}`
2118
2165
  );
2119
2166
  }
2120
2167
  }
@@ -2131,7 +2178,9 @@ class ConcatenatedModule extends Module {
2131
2178
  escapeNamespaceObjectSources.set(
2132
2179
  info,
2133
2180
  `
2134
- // NAMESPACE OBJECT (decoupled): ${info.module.readableIdentifier(requestShortener)}
2181
+ // NAMESPACE OBJECT (decoupled): ${info.module.readableIdentifier(
2182
+ requestShortener
2183
+ )}
2135
2184
  var ${name} = {};
2136
2185
  ${RuntimeGlobals.makeNamespaceObject}(${name});
2137
2186
  ${defineGetters}`
@@ -2154,7 +2203,9 @@ ${defineGetters}`
2154
2203
  // TODO: Replace with the inlined value directly at the call site
2155
2204
  if (usedName instanceof InlinedUsedName) {
2156
2205
  nsObj.push(
2157
- `\n ${propertyName(exportInfo.name)}: ${runtimeTemplate.returningFunction(
2206
+ `\n ${propertyName(
2207
+ exportInfo.name
2208
+ )}: ${runtimeTemplate.returningFunction(
2158
2209
  usedName.render(
2159
2210
  Template.toNormalComment(
2160
2211
  `inlined export ${propertyAccess([exportInfo.name])}`
@@ -2180,9 +2231,9 @@ ${defineGetters}`
2180
2231
  true
2181
2232
  );
2182
2233
  nsObj.push(
2183
- `\n ${propertyName(usedName)}: ${runtimeTemplate.returningFunction(
2184
- finalName
2185
- )}`
2234
+ `\n ${propertyName(
2235
+ usedName
2236
+ )}: ${runtimeTemplate.returningFunction(finalName)}`
2186
2237
  );
2187
2238
  }
2188
2239
  }
@@ -2232,6 +2283,16 @@ ${defineGetters}`
2232
2283
  ),
2233
2284
  // an async module will opt-out of the concat module optimization.
2234
2285
  [],
2286
+ // A closure member absorbed into this concatenation shares this
2287
+ // module's runtime id (and thus its `evaluating` flag); resolve it
2288
+ // to that id instead of the member's now-absent standalone id.
2289
+ getDeferredCycleModuleIds(
2290
+ getDeferredCycleModules(moduleGraph, info.module),
2291
+ (mod) =>
2292
+ moduleToInfoMap.has(mod)
2293
+ ? chunkGraph.getModuleId(this)
2294
+ : chunkGraph.getModuleId(mod)
2295
+ ),
2235
2296
  runtimeRequirements
2236
2297
  );
2237
2298
  runtimeRequirements.add(RuntimeGlobals.require);
@@ -2269,7 +2330,18 @@ ${defineGetters}`
2269
2330
  result.add(
2270
2331
  `\n;// ${info.module.readableIdentifier(requestShortener)}\n`
2271
2332
  );
2272
- result.add(/** @type {ReplaceSource} */ (info.source));
2333
+ if (info.cjsWrapped) {
2334
+ // Real CommonJS semantics via the runtime helper: it calls the
2335
+ // body with this = exports and returns the final module.exports.
2336
+ runtimeRequirements.add(RuntimeGlobals.commonJsWrap);
2337
+ result.add(
2338
+ `var ${info.namespaceObjectName} = /*#__PURE__*/${RuntimeGlobals.commonJsWrap}(function(${info.module.moduleArgument}, ${info.module.exportsArgument}) {\n`
2339
+ );
2340
+ result.add(/** @type {ReplaceSource} */ (info.source));
2341
+ result.add("\n});\n");
2342
+ } else {
2343
+ result.add(/** @type {ReplaceSource} */ (info.source));
2344
+ }
2273
2345
  if (info.chunkInitFragments) {
2274
2346
  for (const f of info.chunkInitFragments) chunkInitFragments.push(f);
2275
2347
  }
@@ -2403,6 +2475,33 @@ ${defineGetters}`
2403
2475
  if (info.type === "concatenated") {
2404
2476
  const m = info.module;
2405
2477
  try {
2478
+ if (info.cjsWrapped) {
2479
+ // A wrapped module renders its normal module source (real
2480
+ // module/exports objects, own module ids) inside an IIFE, so it
2481
+ // needs no concatenation scope, reference rewriting, or scope
2482
+ // analysis — the wrapper isolates its top-level declarations.
2483
+ const codeGenResult = m.codeGeneration({
2484
+ dependencyTemplates,
2485
+ runtimeTemplate,
2486
+ moduleGraph,
2487
+ chunkGraph,
2488
+ runtime,
2489
+ runtimes,
2490
+ codeGenerationResults,
2491
+ sourceTypes: JAVASCRIPT_TYPES
2492
+ });
2493
+ const source =
2494
+ /** @type {Source} */
2495
+ (codeGenResult.sources.get(JAVASCRIPT_TYPE));
2496
+ const data = codeGenResult.data;
2497
+ info.runtimeRequirements =
2498
+ /** @type {ReadOnlyRuntimeRequirements} */
2499
+ (codeGenResult.runtimeRequirements);
2500
+ info.internalSource = source;
2501
+ info.source = new ReplaceSource(source);
2502
+ info.chunkInitFragments = data && data.get("chunkInitFragments");
2503
+ return;
2504
+ }
2406
2505
  // Create a concatenation scope to track and capture information
2407
2506
  const concatenationScope = new ConcatenationScope(
2408
2507
  modulesMap,
@@ -2434,11 +2533,17 @@ ${defineGetters}`
2434
2533
  let ast;
2435
2534
 
2436
2535
  try {
2536
+ const { experiments } = this.compilation.options;
2537
+
2437
2538
  ({ ast } = JavascriptParser._parse(
2438
2539
  code,
2439
2540
  {
2440
2541
  sourceType: "module",
2441
- ranges: true
2542
+ ranges: true,
2543
+ // generated code contains phase imports when the experiments are on
2544
+ importPhases: Boolean(
2545
+ experiments.deferImport || experiments.sourceImport
2546
+ )
2442
2547
  },
2443
2548
  JavascriptParser._getModuleParseFunction(this.compilation, m)
2444
2549
  ));
@@ -2511,6 +2616,9 @@ ${defineGetters}`
2511
2616
  type: "concatenated",
2512
2617
  module: info.module,
2513
2618
  index,
2619
+ cjsWrapped: isCommonJsWrapped(
2620
+ /** @type {NormalModule} */ (info.module)
2621
+ ),
2514
2622
  ast: undefined,
2515
2623
  chunkInitFragments: undefined,
2516
2624
  internalSource: undefined,
@@ -76,6 +76,12 @@ class FlagIncludedChunksPlugin {
76
76
  chunkModulesHash.set(chunk, hash);
77
77
  }
78
78
 
79
+ // Chunks that received an included id and need their `ids` re-sorted
80
+ // once, after all pushes — instead of re-sorting on every push
81
+ // inside the nested loop below (https://github.com/webpack/webpack/issues/18837).
82
+ /** @type {Set<Chunk>} */
83
+ const chunksWithIncludedIds = new Set();
84
+
79
85
  for (const chunkA of chunks) {
80
86
  const chunkAHash =
81
87
  /** @type {number} */
@@ -125,11 +131,15 @@ class FlagIncludedChunksPlugin {
125
131
 
126
132
  /** @type {ChunkId[]} */
127
133
  (chunkB.ids).push(/** @type {ChunkId} */ (chunkA.id));
128
- // https://github.com/webpack/webpack/issues/18837
129
- /** @type {ChunkId[]} */
130
- (chunkB.ids).sort(compareIds);
134
+ chunksWithIncludedIds.add(chunkB);
131
135
  }
132
136
  }
137
+
138
+ // Sort each affected chunk's ids once (https://github.com/webpack/webpack/issues/18837).
139
+ for (const chunk of chunksWithIncludedIds) {
140
+ /** @type {ChunkId[]} */
141
+ (chunk.ids).sort(compareIds);
142
+ }
133
143
  });
134
144
  });
135
145
  }