webpack 5.102.1 → 5.104.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 (220) hide show
  1. package/README.md +121 -134
  2. package/hot/dev-server.js +18 -3
  3. package/hot/emitter-event-target.js +7 -0
  4. package/hot/lazy-compilation-node.js +45 -29
  5. package/hot/lazy-compilation-universal.js +18 -0
  6. package/hot/lazy-compilation-web.js +15 -5
  7. package/hot/load-http.js +7 -0
  8. package/hot/only-dev-server.js +19 -4
  9. package/lib/APIPlugin.js +6 -0
  10. package/lib/Chunk.js +1 -1
  11. package/lib/ChunkGraph.js +9 -7
  12. package/lib/ChunkGroup.js +8 -5
  13. package/lib/CleanPlugin.js +6 -3
  14. package/lib/CodeGenerationResults.js +2 -1
  15. package/lib/CompatibilityPlugin.js +28 -2
  16. package/lib/Compilation.js +58 -21
  17. package/lib/Compiler.js +3 -3
  18. package/lib/ConcatenationScope.js +0 -15
  19. package/lib/ContextModule.js +6 -3
  20. package/lib/ContextModuleFactory.js +6 -4
  21. package/lib/CssModule.js +6 -1
  22. package/lib/DefinePlugin.js +45 -14
  23. package/lib/DelegatedModule.js +7 -4
  24. package/lib/Dependency.js +8 -1
  25. package/lib/DependencyTemplate.js +1 -0
  26. package/lib/DllModule.js +6 -3
  27. package/lib/DotenvPlugin.js +462 -0
  28. package/lib/EnvironmentPlugin.js +19 -16
  29. package/lib/EvalSourceMapDevToolPlugin.js +16 -0
  30. package/lib/ExportsInfo.js +6 -2
  31. package/lib/ExternalModule.js +28 -35
  32. package/lib/ExternalModuleFactoryPlugin.js +11 -9
  33. package/lib/ExternalsPlugin.js +2 -1
  34. package/lib/FileSystemInfo.js +1 -1
  35. package/lib/Generator.js +10 -7
  36. package/lib/HookWebpackError.js +33 -4
  37. package/lib/HotModuleReplacementPlugin.js +22 -0
  38. package/lib/ManifestPlugin.js +235 -0
  39. package/lib/Module.js +27 -15
  40. package/lib/ModuleBuildError.js +1 -1
  41. package/lib/ModuleError.js +1 -1
  42. package/lib/ModuleFilenameHelpers.js +1 -1
  43. package/lib/ModuleGraph.js +29 -13
  44. package/lib/ModuleGraphConnection.js +2 -2
  45. package/lib/ModuleSourceTypeConstants.js +189 -0
  46. package/lib/ModuleTypeConstants.js +1 -4
  47. package/lib/ModuleWarning.js +1 -1
  48. package/lib/MultiCompiler.js +1 -1
  49. package/lib/NodeStuffPlugin.js +424 -116
  50. package/lib/NormalModule.js +23 -20
  51. package/lib/NormalModuleFactory.js +7 -10
  52. package/lib/Parser.js +1 -1
  53. package/lib/RawModule.js +7 -4
  54. package/lib/RuntimeGlobals.js +22 -4
  55. package/lib/RuntimeModule.js +1 -1
  56. package/lib/RuntimePlugin.js +27 -6
  57. package/lib/RuntimeTemplate.js +120 -57
  58. package/lib/SourceMapDevToolPlugin.js +26 -1
  59. package/lib/Template.js +17 -6
  60. package/lib/TemplatedPathPlugin.js +5 -6
  61. package/lib/WebpackError.js +0 -1
  62. package/lib/WebpackOptionsApply.js +67 -15
  63. package/lib/asset/AssetBytesGenerator.js +16 -12
  64. package/lib/asset/AssetGenerator.js +31 -26
  65. package/lib/asset/AssetSourceGenerator.js +16 -12
  66. package/lib/asset/RawDataUrlModule.js +6 -3
  67. package/lib/buildChunkGraph.js +4 -2
  68. package/lib/cache/PackFileCacheStrategy.js +6 -5
  69. package/lib/cli.js +2 -43
  70. package/lib/config/browserslistTargetHandler.js +24 -0
  71. package/lib/config/defaults.js +226 -61
  72. package/lib/config/normalization.js +4 -3
  73. package/lib/config/target.js +11 -0
  74. package/lib/container/ContainerEntryModule.js +6 -3
  75. package/lib/container/FallbackModule.js +6 -3
  76. package/lib/container/RemoteModule.js +1 -3
  77. package/lib/css/CssGenerator.js +304 -76
  78. package/lib/css/CssLoadingRuntimeModule.js +14 -4
  79. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +56 -0
  80. package/lib/css/CssModulesPlugin.js +72 -67
  81. package/lib/css/CssParser.js +1726 -732
  82. package/lib/css/walkCssTokens.js +128 -11
  83. package/lib/dependencies/CachedConstDependency.js +24 -10
  84. package/lib/dependencies/CommonJsImportsParserPlugin.js +0 -9
  85. package/lib/dependencies/CommonJsPlugin.js +12 -0
  86. package/lib/dependencies/CommonJsRequireContextDependency.js +1 -1
  87. package/lib/dependencies/ContextDependencyHelpers.js +2 -2
  88. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +3 -1
  89. package/lib/dependencies/CssIcssExportDependency.js +389 -12
  90. package/lib/dependencies/CssIcssImportDependency.js +114 -51
  91. package/lib/dependencies/CssIcssSymbolDependency.js +31 -33
  92. package/lib/dependencies/CssImportDependency.js +17 -6
  93. package/lib/dependencies/CssUrlDependency.js +3 -2
  94. package/lib/dependencies/DynamicExports.js +7 -7
  95. package/lib/dependencies/ExternalModuleDependency.js +7 -4
  96. package/lib/dependencies/ExternalModuleInitFragment.js +3 -2
  97. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +96 -0
  98. package/lib/dependencies/HarmonyAcceptDependency.js +6 -1
  99. package/lib/dependencies/HarmonyAcceptImportDependency.js +2 -1
  100. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +12 -1
  101. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +35 -23
  102. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +13 -9
  103. package/lib/dependencies/HarmonyExports.js +4 -4
  104. package/lib/dependencies/HarmonyImportDependency.js +28 -27
  105. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +28 -69
  106. package/lib/dependencies/HarmonyImportSideEffectDependency.js +4 -3
  107. package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -8
  108. package/lib/dependencies/ImportDependency.js +8 -2
  109. package/lib/dependencies/ImportEagerDependency.js +6 -3
  110. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
  111. package/lib/dependencies/ImportMetaPlugin.js +154 -9
  112. package/lib/dependencies/ImportParserPlugin.js +21 -23
  113. package/lib/dependencies/ImportPhase.js +121 -0
  114. package/lib/dependencies/ImportWeakDependency.js +6 -3
  115. package/lib/dependencies/LocalModulesHelpers.js +3 -3
  116. package/lib/dependencies/ModuleDependency.js +5 -1
  117. package/lib/dependencies/ModuleHotAcceptDependency.js +1 -1
  118. package/lib/dependencies/WorkerPlugin.js +2 -2
  119. package/lib/dependencies/getFunctionExpression.js +1 -1
  120. package/lib/esm/ExportWebpackRequireRuntimeModule.js +1 -8
  121. package/lib/esm/ModuleChunkFormatPlugin.js +5 -4
  122. package/lib/hmr/HotModuleReplacement.runtime.js +2 -1
  123. package/lib/hmr/LazyCompilationPlugin.js +5 -3
  124. package/lib/ids/IdHelpers.js +20 -8
  125. package/lib/index.js +6 -0
  126. package/lib/javascript/ChunkHelpers.js +16 -5
  127. package/lib/javascript/JavascriptGenerator.js +105 -104
  128. package/lib/javascript/JavascriptModulesPlugin.js +80 -37
  129. package/lib/javascript/JavascriptParser.js +161 -44
  130. package/lib/json/JsonGenerator.js +5 -4
  131. package/lib/json/JsonParser.js +9 -2
  132. package/lib/library/AbstractLibraryPlugin.js +1 -1
  133. package/lib/library/AmdLibraryPlugin.js +4 -1
  134. package/lib/library/ExportPropertyLibraryPlugin.js +4 -1
  135. package/lib/library/ModuleLibraryPlugin.js +41 -23
  136. package/lib/library/SystemLibraryPlugin.js +8 -1
  137. package/lib/library/UmdLibraryPlugin.js +2 -2
  138. package/lib/logging/Logger.js +5 -4
  139. package/lib/logging/createConsoleLogger.js +2 -2
  140. package/lib/node/NodeTargetPlugin.js +9 -1
  141. package/lib/node/ReadFileCompileWasmPlugin.js +0 -2
  142. package/lib/optimize/ConcatenatedModule.js +208 -167
  143. package/lib/optimize/ModuleConcatenationPlugin.js +5 -4
  144. package/lib/optimize/SideEffectsFlagPlugin.js +3 -2
  145. package/lib/optimize/SplitChunksPlugin.js +60 -46
  146. package/lib/rules/RuleSetCompiler.js +1 -1
  147. package/lib/runtime/AsyncModuleRuntimeModule.js +28 -18
  148. package/lib/runtime/AutoPublicPathRuntimeModule.js +8 -3
  149. package/lib/runtime/GetChunkFilenameRuntimeModule.js +3 -2
  150. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +89 -55
  151. package/lib/schemes/HttpUriPlugin.js +78 -7
  152. package/lib/serialization/AggregateErrorSerializer.js +1 -2
  153. package/lib/serialization/ObjectMiddleware.js +0 -2
  154. package/lib/serialization/SingleItemMiddleware.js +1 -1
  155. package/lib/sharing/ConsumeSharedModule.js +1 -1
  156. package/lib/sharing/ConsumeSharedPlugin.js +5 -3
  157. package/lib/sharing/ProvideSharedModule.js +1 -1
  158. package/lib/sharing/resolveMatchedConfigs.js +15 -9
  159. package/lib/sharing/utils.js +1 -1
  160. package/lib/stats/DefaultStatsFactoryPlugin.js +8 -5
  161. package/lib/stats/DefaultStatsPresetPlugin.js +1 -1
  162. package/lib/stats/DefaultStatsPrinterPlugin.js +1 -1
  163. package/lib/util/StringXor.js +1 -1
  164. package/lib/util/URLAbsoluteSpecifier.js +2 -2
  165. package/lib/util/binarySearchBounds.js +2 -2
  166. package/lib/util/comparators.js +54 -76
  167. package/lib/util/compileBooleanMatcher.js +78 -6
  168. package/lib/util/createHash.js +20 -199
  169. package/lib/util/deprecation.js +1 -1
  170. package/lib/util/deterministicGrouping.js +6 -3
  171. package/lib/util/fs.js +75 -75
  172. package/lib/util/hash/BatchedHash.js +10 -9
  173. package/lib/util/hash/BulkUpdateHash.js +138 -0
  174. package/lib/util/hash/DebugHash.js +75 -0
  175. package/lib/util/hash/hash-digest.js +216 -0
  176. package/lib/util/identifier.js +82 -17
  177. package/lib/util/internalSerializables.js +2 -6
  178. package/lib/util/runtime.js +3 -3
  179. package/lib/util/source.js +2 -2
  180. package/lib/wasm/EnableWasmLoadingPlugin.js +10 -4
  181. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +3 -2
  182. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +11 -7
  183. package/lib/wasm-sync/WebAssemblyGenerator.js +9 -6
  184. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +11 -6
  185. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +6 -2
  186. package/lib/web/FetchCompileWasmPlugin.js +0 -2
  187. package/lib/webpack.js +85 -82
  188. package/module.d.ts +5 -0
  189. package/package.json +34 -28
  190. package/schemas/WebpackOptions.check.js +1 -1
  191. package/schemas/WebpackOptions.json +160 -101
  192. package/schemas/plugins/{css/CssAutoParserOptions.check.d.ts → ManifestPlugin.check.d.ts} +1 -1
  193. package/schemas/plugins/ManifestPlugin.check.js +6 -0
  194. package/schemas/plugins/ManifestPlugin.json +98 -0
  195. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  196. package/schemas/plugins/SourceMapDevToolPlugin.json +16 -3
  197. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  198. package/schemas/plugins/container/ContainerReferencePlugin.json +4 -1
  199. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  200. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  201. package/schemas/plugins/container/ModuleFederationPlugin.json +4 -1
  202. package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +1 -1
  203. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  204. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  205. package/schemas/plugins/json/JsonModulesPluginParser.check.js +1 -1
  206. package/types.d.ts +771 -436
  207. package/lib/ModuleSourceTypesConstants.js +0 -123
  208. package/lib/dependencies/CssLocalIdentifierDependency.js +0 -250
  209. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +0 -112
  210. package/schemas/plugins/css/CssAutoGeneratorOptions.check.d.ts +0 -7
  211. package/schemas/plugins/css/CssAutoGeneratorOptions.check.js +0 -6
  212. package/schemas/plugins/css/CssAutoGeneratorOptions.json +0 -3
  213. package/schemas/plugins/css/CssAutoParserOptions.check.js +0 -6
  214. package/schemas/plugins/css/CssAutoParserOptions.json +0 -3
  215. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.d.ts +0 -7
  216. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.js +0 -6
  217. package/schemas/plugins/css/CssGlobalGeneratorOptions.json +0 -3
  218. package/schemas/plugins/css/CssGlobalParserOptions.check.d.ts +0 -7
  219. package/schemas/plugins/css/CssGlobalParserOptions.check.js +0 -6
  220. package/schemas/plugins/css/CssGlobalParserOptions.json +0 -3
@@ -19,6 +19,7 @@ const { compareRuntime } = require("./runtime");
19
19
  /** @typedef {import("../dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */
20
20
  /** @typedef {import("../Module")} Module */
21
21
  /** @typedef {import("../ModuleGraph")} ModuleGraph */
22
+ /** @typedef {import("../dependencies/ModuleDependency")} ModuleDependency */
22
23
 
23
24
  /**
24
25
  * @typedef {object} DependencySourceOrder
@@ -56,7 +57,7 @@ const createCachedParameterizedComparator = (fn) => {
56
57
  /**
57
58
  * @param {T} a first item
58
59
  * @param {T} b second item
59
- * @returns {-1|0|1} compare result
60
+ * @returns {-1 | 0 | 1} compare result
60
61
  */
61
62
  const result = fn.bind(null, arg);
62
63
  map.set(/** @type {EXPECTED_OBJECT} */ (arg), result);
@@ -89,7 +90,7 @@ const compareIterables = (elementComparator) => {
89
90
  /**
90
91
  * @param {Iterable<T>} a first value
91
92
  * @param {Iterable<T>} b second value
92
- * @returns {-1|0|1} compare result
93
+ * @returns {-1 | 0 | 1} compare result
93
94
  */
94
95
  const result = (a, b) => {
95
96
  const aI = a[Symbol.iterator]();
@@ -114,7 +115,7 @@ const compareIterables = (elementComparator) => {
114
115
  * Compare two locations
115
116
  * @param {DependencyLocation} a A location node
116
117
  * @param {DependencyLocation} b A location node
117
- * @returns {-1|0|1} sorting comparator value
118
+ * @returns {-1 | 0 | 1} sorting comparator value
118
119
  */
119
120
  const compareLocations = (a, b) => {
120
121
  const isObjectA = typeof a === "object" && a !== null;
@@ -177,7 +178,7 @@ const compareLocations = (a, b) => {
177
178
  * @param {ChunkGraph} chunkGraph the chunk graph
178
179
  * @param {Module} a module
179
180
  * @param {Module} b module
180
- * @returns {-1|0|1} compare result
181
+ * @returns {-1 | 0 | 1} compare result
181
182
  */
182
183
  const compareModulesById = (chunkGraph, a, b) =>
183
184
  compareIds(
@@ -188,7 +189,7 @@ const compareModulesById = (chunkGraph, a, b) =>
188
189
  /**
189
190
  * @param {number} a number
190
191
  * @param {number} b number
191
- * @returns {-1|0|1} compare result
192
+ * @returns {-1 | 0 | 1} compare result
192
193
  */
193
194
  const compareNumbers = (a, b) => {
194
195
  if (typeof a !== typeof b) {
@@ -202,7 +203,7 @@ const compareNumbers = (a, b) => {
202
203
  /**
203
204
  * @param {string} a string
204
205
  * @param {string} b string
205
- * @returns {-1|0|1} compare result
206
+ * @returns {-1 | 0 | 1} compare result
206
207
  */
207
208
  const compareStringsNumeric = (a, b) => {
208
209
  const aLength = a.length;
@@ -274,7 +275,7 @@ const compareStringsNumeric = (a, b) => {
274
275
  * @param {ModuleGraph} moduleGraph the module graph
275
276
  * @param {Module} a module
276
277
  * @param {Module} b module
277
- * @returns {-1|0|1} compare result
278
+ * @returns {-1 | 0 | 1} compare result
278
279
  */
279
280
  const compareModulesByPostOrderIndexOrIdentifier = (moduleGraph, a, b) => {
280
281
  const cmp = compareNumbers(
@@ -289,7 +290,7 @@ const compareModulesByPostOrderIndexOrIdentifier = (moduleGraph, a, b) => {
289
290
  * @param {ModuleGraph} moduleGraph the module graph
290
291
  * @param {Module} a module
291
292
  * @param {Module} b module
292
- * @returns {-1|0|1} compare result
293
+ * @returns {-1 | 0 | 1} compare result
293
294
  */
294
295
  const compareModulesByPreOrderIndexOrIdentifier = (moduleGraph, a, b) => {
295
296
  const cmp = compareNumbers(
@@ -304,7 +305,7 @@ const compareModulesByPreOrderIndexOrIdentifier = (moduleGraph, a, b) => {
304
305
  * @param {ChunkGraph} chunkGraph the chunk graph
305
306
  * @param {Module} a module
306
307
  * @param {Module} b module
307
- * @returns {-1|0|1} compare result
308
+ * @returns {-1 | 0 | 1} compare result
308
309
  */
309
310
  const compareModulesByIdOrIdentifier = (chunkGraph, a, b) => {
310
311
  const cmp = compareIds(
@@ -326,7 +327,7 @@ const compareChunks = (chunkGraph, a, b) => chunkGraph.compareChunks(a, b);
326
327
  /**
327
328
  * @param {string} a first string
328
329
  * @param {string} b second string
329
- * @returns {-1|0|1} compare result
330
+ * @returns {-1 | 0 | 1} compare result
330
331
  */
331
332
  const compareStrings = (a, b) => {
332
333
  if (a < b) return -1;
@@ -407,7 +408,7 @@ const concatComparators = (c1, c2, ...cRest) => {
407
408
  /**
408
409
  * @param {T} a first value
409
410
  * @param {T} b second value
410
- * @returns {-1|0|1} compare result
411
+ * @returns {-1 | 0 | 1} compare result
411
412
  */
412
413
  const result = (a, b) => {
413
414
  const res = c1(a, b);
@@ -439,7 +440,7 @@ const compareSelect = (getter, comparator) => {
439
440
  /**
440
441
  * @param {T} a first value
441
442
  * @param {T} b second value
442
- * @returns {-1|0|1} compare result
443
+ * @returns {-1 | 0 | 1} compare result
443
444
  */
444
445
  const result = (a, b) => {
445
446
  const aValue = getter(a);
@@ -510,47 +511,42 @@ const compareChunksNatural = (chunkGraph) => {
510
511
  * https://github.com/webpack/webpack/pull/19686
511
512
  * @param {Dependency[]} dependencies dependencies
512
513
  * @param {WeakMap<Dependency, DependencySourceOrder>} dependencySourceOrderMap dependency source order map
514
+ * @param {((dep: Dependency, index: number) => void)=} onDependencyReSort optional callback to set index for each dependency
513
515
  * @returns {void}
514
516
  */
515
- const sortWithSourceOrder = (dependencies, dependencySourceOrderMap) => {
516
- /**
517
- * @param {Dependency} dep dependency
518
- * @returns {number} source order
519
- */
520
- const getSourceOrder = (dep) => {
521
- if (dependencySourceOrderMap.has(dep)) {
522
- const { main } = /** @type {DependencySourceOrder} */ (
523
- dependencySourceOrderMap.get(dep)
524
- );
525
- return main;
526
- }
527
- return /** @type { HarmonyImportSideEffectDependency | HarmonyImportSpecifierDependency} */ (
528
- dep
529
- ).sourceOrder;
530
- };
531
-
532
- /**
533
- * If the sourceOrder is a number, it means the dependency needs to be sorted.
534
- * @param {number | undefined} sourceOrder sourceOrder
535
- * @returns {boolean} needReSort
536
- */
537
- const needReSort = (sourceOrder) => {
538
- if (typeof sourceOrder === "number") {
539
- return true;
540
- }
541
- return false;
542
- };
543
-
544
- // Extract dependencies with sourceOrder and sort them
517
+ const sortWithSourceOrder = (
518
+ dependencies,
519
+ dependencySourceOrderMap,
520
+ onDependencyReSort
521
+ ) => {
522
+ /** @type {{dep: Dependency, main: number, sub: number}[]} */
545
523
  const withSourceOrder = [];
524
+ /** @type {number[]} */
525
+ const positions = [];
546
526
 
547
- // First pass: collect dependencies with sourceOrder
548
527
  for (let i = 0; i < dependencies.length; i++) {
549
528
  const dep = dependencies[i];
550
- const sourceOrder = getSourceOrder(dep);
551
-
552
- if (needReSort(sourceOrder)) {
553
- withSourceOrder.push({ dep, sourceOrder, originalIndex: i });
529
+ const cached = dependencySourceOrderMap.get(dep);
530
+
531
+ if (cached) {
532
+ positions.push(i);
533
+ withSourceOrder.push({
534
+ dep,
535
+ main: cached.main,
536
+ sub: cached.sub
537
+ });
538
+ } else {
539
+ const sourceOrder = /** @type {number | undefined} */ (
540
+ /** @type {ModuleDependency} */ (dep).sourceOrder
541
+ );
542
+ if (typeof sourceOrder === "number") {
543
+ positions.push(i);
544
+ withSourceOrder.push({
545
+ dep,
546
+ main: sourceOrder,
547
+ sub: 0
548
+ });
549
+ }
554
550
  }
555
551
  }
556
552
 
@@ -558,37 +554,19 @@ const sortWithSourceOrder = (dependencies, dependencySourceOrderMap) => {
558
554
  return;
559
555
  }
560
556
 
561
- // Sort dependencies with sourceOrder
562
557
  withSourceOrder.sort((a, b) => {
563
- // Handle both dependencies in map case
564
- if (
565
- dependencySourceOrderMap.has(a.dep) &&
566
- dependencySourceOrderMap.has(b.dep)
567
- ) {
568
- const { main: mainA, sub: subA } = /** @type {DependencySourceOrder} */ (
569
- dependencySourceOrderMap.get(a.dep)
570
- );
571
- const { main: mainB, sub: subB } = /** @type {DependencySourceOrder} */ (
572
- dependencySourceOrderMap.get(b.dep)
573
- );
574
- if (mainA === mainB) {
575
- return compareNumbers(subA, subB);
576
- }
577
- return compareNumbers(mainA, mainB);
558
+ if (a.main !== b.main) {
559
+ return compareNumbers(a.main, b.main);
578
560
  }
579
-
580
- return compareNumbers(a.sourceOrder, b.sourceOrder);
561
+ return compareNumbers(a.sub, b.sub);
581
562
  });
582
563
 
583
- // Second pass: build result array
584
- let sortedIndex = 0;
585
- for (let i = 0; i < dependencies.length; i++) {
586
- const dep = dependencies[i];
587
- const sourceOrder = getSourceOrder(dep);
588
-
589
- if (needReSort(sourceOrder)) {
590
- dependencies[i] = withSourceOrder[sortedIndex].dep;
591
- sortedIndex++;
564
+ // Second pass: place sorted deps back to original positions
565
+ for (let i = 0; i < positions.length; i++) {
566
+ const depIndex = positions[i];
567
+ dependencies[depIndex] = withSourceOrder[i].dep;
568
+ if (onDependencyReSort) {
569
+ onDependencyReSort(dependencies[depIndex], depIndex);
592
570
  }
593
571
  }
594
572
  };
@@ -600,7 +578,7 @@ module.exports.compareChunks =
600
578
  /**
601
579
  * @param {Chunk} a chunk
602
580
  * @param {Chunk} b chunk
603
- * @returns {-1|0|1} compare result
581
+ * @returns {-1 | 0 | 1} compare result
604
582
  */
605
583
  module.exports.compareChunksById = (a, b) =>
606
584
  compareIds(/** @type {ChunkId} */ (a.id), /** @type {ChunkId} */ (b.id));
@@ -621,7 +599,7 @@ module.exports.compareModulesByIdOrIdentifier =
621
599
  /**
622
600
  * @param {Module} a module
623
601
  * @param {Module} b module
624
- * @returns {-1|0|1} compare result
602
+ * @returns {-1 | 0 | 1} compare result
625
603
  */
626
604
  module.exports.compareModulesByIdentifier = (a, b) =>
627
605
  compareIds(a.identifier(), b.identifier());
@@ -11,6 +11,79 @@
11
11
  */
12
12
  const quoteMeta = (str) => str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&");
13
13
 
14
+ /**
15
+ * @param {string} char character to escape for use in character class
16
+ * @returns {string} escaped character
17
+ */
18
+ const quoteMetaInCharClass = (char) => {
19
+ // In character class, only these need escaping: ] \ ^ -
20
+ if (char === "]" || char === "\\" || char === "^" || char === "-") {
21
+ return `\\${char}`;
22
+ }
23
+ return char;
24
+ };
25
+
26
+ /**
27
+ * Converts an array of single characters into an optimized character class string
28
+ * using ranges where possible. E.g., ["1","2","3","4","a"] => "1-4a"
29
+ * @param {string[]} chars array of single characters (should be sorted)
30
+ * @returns {string} optimized character class content (without the brackets)
31
+ */
32
+ const charsToCharClassContent = (chars) => {
33
+ if (chars.length === 0) return "";
34
+ if (chars.length === 1) return quoteMetaInCharClass(chars[0]);
35
+
36
+ // Sort by char code
37
+ const sorted = [...chars].sort((a, b) => a.charCodeAt(0) - b.charCodeAt(0));
38
+
39
+ /** @type {string[]} */
40
+ const parts = [];
41
+ let rangeStart = sorted[0];
42
+ let rangeEnd = sorted[0];
43
+
44
+ for (let i = 1; i < sorted.length; i++) {
45
+ const char = sorted[i];
46
+ const prevCode = rangeEnd.charCodeAt(0);
47
+ const currCode = char.charCodeAt(0);
48
+
49
+ if (currCode === prevCode + 1) {
50
+ // Extend the range
51
+ rangeEnd = char;
52
+ } else {
53
+ // Flush the current range
54
+ parts.push(formatRange(rangeStart, rangeEnd));
55
+ rangeStart = char;
56
+ rangeEnd = char;
57
+ }
58
+ }
59
+ // Flush the last range
60
+ parts.push(formatRange(rangeStart, rangeEnd));
61
+
62
+ return parts.join("");
63
+ };
64
+
65
+ /**
66
+ * Formats a range of characters for use in a character class
67
+ * @param {string} start start character
68
+ * @param {string} end end character
69
+ * @returns {string} formatted range
70
+ */
71
+ const formatRange = (start, end) => {
72
+ const startCode = start.charCodeAt(0);
73
+ const endCode = end.charCodeAt(0);
74
+ const length = endCode - startCode + 1;
75
+
76
+ if (length === 1) {
77
+ return quoteMetaInCharClass(start);
78
+ }
79
+ if (length === 2) {
80
+ // For 2 chars, just list them (e.g., "ab" instead of "a-b")
81
+ return quoteMetaInCharClass(start) + quoteMetaInCharClass(end);
82
+ }
83
+ // For 3+ chars, use range notation
84
+ return `${quoteMetaInCharClass(start)}-${quoteMetaInCharClass(end)}`;
85
+ };
86
+
14
87
  /**
15
88
  * @param {string} str string
16
89
  * @returns {string} string
@@ -148,19 +221,20 @@ const itemsToRegexp = (itemsArr) => {
148
221
  }
149
222
  // special case for only single char items
150
223
  if (countOfSingleCharItems === itemsArr.length) {
151
- return `[${quoteMeta(itemsArr.sort().join(""))}]`;
224
+ return `[${charsToCharClassContent(itemsArr)}]`;
152
225
  }
153
226
  /** @type {Set<string>} */
154
227
  const items = new Set(itemsArr.sort());
155
228
  if (countOfSingleCharItems > 2) {
156
- let singleCharItems = "";
229
+ /** @type {string[]} */
230
+ const singleCharItems = [];
157
231
  for (const item of items) {
158
232
  if (item.length === 1) {
159
- singleCharItems += item;
233
+ singleCharItems.push(item);
160
234
  items.delete(item);
161
235
  }
162
236
  }
163
- finishedItems.push(`[${quoteMeta(singleCharItems)}]`);
237
+ finishedItems.push(`[${charsToCharClassContent(singleCharItems)}]`);
164
238
  }
165
239
 
166
240
  // special case for 2 items with common prefix/suffix
@@ -227,8 +301,6 @@ const itemsToRegexp = (itemsArr) => {
227
301
  );
228
302
  }
229
303
 
230
- // TODO further optimize regexp, i. e.
231
- // use ranges: (1|2|3|4|a) => [1-4a]
232
304
  /** @type {string[]} */
233
305
  const conditional = [...finishedItems, ...Array.from(items, quoteMeta)];
234
306
  if (conditional.length === 1) return conditional[0];
@@ -5,212 +5,21 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const Hash = require("./Hash");
9
-
10
- /** @typedef {import("../../declarations/WebpackOptions").HashDigest} Encoding */
8
+ /** @typedef {import("./Hash")} Hash */
11
9
  /** @typedef {import("../../declarations/WebpackOptions").HashFunction} HashFunction */
12
10
 
13
- const BULK_SIZE = 3;
14
-
15
- // We are using an object instead of a Map as this will stay static during the runtime
16
- // so access to it can be optimized by v8
17
- /** @type {{[key: string]: Map<string, string>}} */
18
- const digestCaches = {};
19
-
20
- /** @typedef {() => Hash} HashFactory */
21
-
22
- class BulkUpdateDecorator extends Hash {
23
- /**
24
- * @param {Hash | HashFactory} hashOrFactory function to create a hash
25
- * @param {string=} hashKey key for caching
26
- */
27
- constructor(hashOrFactory, hashKey) {
28
- super();
29
- this.hashKey = hashKey;
30
- if (typeof hashOrFactory === "function") {
31
- this.hashFactory = hashOrFactory;
32
- this.hash = undefined;
33
- } else {
34
- this.hashFactory = undefined;
35
- this.hash = hashOrFactory;
36
- }
37
- this.buffer = "";
38
- }
39
-
40
- /**
41
- * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
42
- * @overload
43
- * @param {string | Buffer} data data
44
- * @returns {Hash} updated hash
45
- */
46
- /**
47
- * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
48
- * @overload
49
- * @param {string} data data
50
- * @param {Encoding} inputEncoding data encoding
51
- * @returns {Hash} updated hash
52
- */
53
- /**
54
- * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
55
- * @param {string | Buffer} data data
56
- * @param {Encoding=} inputEncoding data encoding
57
- * @returns {Hash} updated hash
58
- */
59
- update(data, inputEncoding) {
60
- if (
61
- inputEncoding !== undefined ||
62
- typeof data !== "string" ||
63
- data.length > BULK_SIZE
64
- ) {
65
- if (this.hash === undefined) {
66
- this.hash = /** @type {HashFactory} */ (this.hashFactory)();
67
- }
68
- if (this.buffer.length > 0) {
69
- this.hash.update(this.buffer);
70
- this.buffer = "";
71
- }
72
- if (typeof data === "string" && inputEncoding) {
73
- this.hash.update(data, inputEncoding);
74
- } else {
75
- this.hash.update(data);
76
- }
77
- } else {
78
- this.buffer += data;
79
- if (this.buffer.length > BULK_SIZE) {
80
- if (this.hash === undefined) {
81
- this.hash = /** @type {HashFactory} */ (this.hashFactory)();
82
- }
83
- this.hash.update(this.buffer);
84
- this.buffer = "";
85
- }
86
- }
87
- return this;
88
- }
89
-
90
- /**
91
- * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
92
- * @overload
93
- * @returns {Buffer} digest
94
- */
95
- /**
96
- * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
97
- * @overload
98
- * @param {Encoding} encoding encoding of the return value
99
- * @returns {string} digest
100
- */
101
- /**
102
- * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
103
- * @param {Encoding=} encoding encoding of the return value
104
- * @returns {string | Buffer} digest
105
- */
106
- digest(encoding) {
107
- let digestCache;
108
- const buffer = this.buffer;
109
- if (this.hash === undefined) {
110
- // short data for hash, we can use caching
111
- const cacheKey = `${this.hashKey}-${encoding}`;
112
- digestCache = digestCaches[cacheKey];
113
- if (digestCache === undefined) {
114
- digestCache = digestCaches[cacheKey] = new Map();
115
- }
116
- const cacheEntry = digestCache.get(buffer);
117
- if (cacheEntry !== undefined) return cacheEntry;
118
- this.hash = /** @type {HashFactory} */ (this.hashFactory)();
119
- }
120
- if (buffer.length > 0) {
121
- this.hash.update(buffer);
122
- }
123
- if (!encoding) {
124
- const result = this.hash.digest();
125
- if (digestCache !== undefined) {
126
- digestCache.set(buffer, result);
127
- }
128
- return result;
129
- }
130
- const digestResult = this.hash.digest(encoding);
131
- // Compatibility with the old hash library
132
- const result =
133
- typeof digestResult === "string"
134
- ? digestResult
135
- : /** @type {NodeJS.TypedArray} */ (digestResult).toString();
136
- if (digestCache !== undefined) {
137
- digestCache.set(buffer, result);
138
- }
139
- return result;
140
- }
141
- }
142
-
143
- /* istanbul ignore next */
144
- class DebugHash extends Hash {
145
- constructor() {
146
- super();
147
- this.string = "";
148
- }
149
-
150
- /**
151
- * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
152
- * @overload
153
- * @param {string | Buffer} data data
154
- * @returns {Hash} updated hash
155
- */
156
- /**
157
- * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
158
- * @overload
159
- * @param {string} data data
160
- * @param {Encoding} inputEncoding data encoding
161
- * @returns {Hash} updated hash
162
- */
163
- /**
164
- * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
165
- * @param {string | Buffer} data data
166
- * @param {Encoding=} inputEncoding data encoding
167
- * @returns {Hash} updated hash
168
- */
169
- update(data, inputEncoding) {
170
- if (typeof data !== "string") data = data.toString("utf8");
171
- const prefix = Buffer.from("@webpack-debug-digest@").toString("hex");
172
- if (data.startsWith(prefix)) {
173
- data = Buffer.from(data.slice(prefix.length), "hex").toString();
174
- }
175
- this.string += `[${data}](${
176
- /** @type {string} */
177
- (
178
- // eslint-disable-next-line unicorn/error-message
179
- new Error().stack
180
- ).split("\n", 3)[2]
181
- })\n`;
182
- return this;
183
- }
184
-
185
- /**
186
- * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
187
- * @overload
188
- * @returns {Buffer} digest
189
- */
190
- /**
191
- * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
192
- * @overload
193
- * @param {Encoding} encoding encoding of the return value
194
- * @returns {string} digest
195
- */
196
- /**
197
- * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
198
- * @param {Encoding=} encoding encoding of the return value
199
- * @returns {string | Buffer} digest
200
- */
201
- digest(encoding) {
202
- return Buffer.from(`@webpack-debug-digest@${this.string}`).toString("hex");
203
- }
204
- }
205
-
206
11
  /** @type {typeof import("crypto") | undefined} */
207
12
  let crypto;
208
13
  /** @type {typeof import("./hash/xxhash64") | undefined} */
209
14
  let createXXHash64;
210
15
  /** @type {typeof import("./hash/md4") | undefined} */
211
16
  let createMd4;
17
+ /** @type {typeof import("./hash/DebugHash") | undefined} */
18
+ let DebugHash;
212
19
  /** @type {typeof import("./hash/BatchedHash") | undefined} */
213
20
  let BatchedHash;
21
+ /** @type {typeof import("./hash/BulkUpdateHash") | undefined} */
22
+ let BulkUpdateHash;
214
23
 
215
24
  /**
216
25
  * Creates a hash by name or function
@@ -219,12 +28,18 @@ let BatchedHash;
219
28
  */
220
29
  module.exports = (algorithm) => {
221
30
  if (typeof algorithm === "function") {
31
+ if (BulkUpdateHash === undefined) {
32
+ BulkUpdateHash = require("./hash/BulkUpdateHash");
33
+ }
222
34
  // eslint-disable-next-line new-cap
223
- return new BulkUpdateDecorator(() => new algorithm());
35
+ return new BulkUpdateHash(() => new algorithm());
224
36
  }
225
37
  switch (algorithm) {
226
38
  // TODO add non-cryptographic algorithm here
227
39
  case "debug":
40
+ if (DebugHash === undefined) {
41
+ DebugHash = require("./hash/DebugHash");
42
+ }
228
43
  return new DebugHash();
229
44
  case "xxhash64":
230
45
  if (createXXHash64 === undefined) {
@@ -248,7 +63,10 @@ module.exports = (algorithm) => {
248
63
  )(createMd4());
249
64
  case "native-md4":
250
65
  if (crypto === undefined) crypto = require("crypto");
251
- return new BulkUpdateDecorator(
66
+ if (BulkUpdateHash === undefined) {
67
+ BulkUpdateHash = require("./hash/BulkUpdateHash");
68
+ }
69
+ return new BulkUpdateHash(
252
70
  () =>
253
71
  /** @type {Hash} */ (
254
72
  /** @type {typeof import("crypto")} */
@@ -258,7 +76,10 @@ module.exports = (algorithm) => {
258
76
  );
259
77
  default:
260
78
  if (crypto === undefined) crypto = require("crypto");
261
- return new BulkUpdateDecorator(
79
+ if (BulkUpdateHash === undefined) {
80
+ BulkUpdateHash = require("./hash/BulkUpdateHash");
81
+ }
82
+ return new BulkUpdateHash(
262
83
  () =>
263
84
  /** @type {Hash} */ (
264
85
  /** @type {typeof import("crypto")} */
@@ -194,7 +194,7 @@ module.exports.arrayToSetDeprecation = (set, name) => {
194
194
  /**
195
195
  * @template T
196
196
  * @param {string} name name
197
- * @returns {{ new <T = any>(values?: ReadonlyArray<T> | null): SetDeprecatedArray<T> }} SetDeprecatedArray
197
+ * @returns {{ new <T = EXPECTED_ANY>(values?: ReadonlyArray<T> | null): SetDeprecatedArray<T> }} SetDeprecatedArray
198
198
  */
199
199
  module.exports.createArrayToSetDeprecationSet = (name) => {
200
200
  let initialized = false;
@@ -137,12 +137,15 @@ const isTooSmall = (size, minSize) => {
137
137
  return false;
138
138
  };
139
139
 
140
+ /** @typedef {Set<string>} Types */
141
+
140
142
  /**
141
143
  * @param {Sizes} size size
142
144
  * @param {Sizes} minSize minimum size
143
- * @returns {Set<string>} set of types that are too small
145
+ * @returns {Types} set of types that are too small
144
146
  */
145
147
  const getTooSmallTypes = (size, minSize) => {
148
+ /** @typedef {Types} */
146
149
  const types = new Set();
147
150
  for (const key of Object.keys(size)) {
148
151
  const s = size[key];
@@ -156,7 +159,7 @@ const getTooSmallTypes = (size, minSize) => {
156
159
  /**
157
160
  * @template {object} T
158
161
  * @param {T} size size
159
- * @param {Set<string>} types types
162
+ * @param {Types} types types
160
163
  * @returns {number} number of matching size types
161
164
  */
162
165
  const getNumberOfMatchingSizeTypes = (size, types) => {
@@ -169,7 +172,7 @@ const getNumberOfMatchingSizeTypes = (size, types) => {
169
172
 
170
173
  /**
171
174
  * @param {Sizes} size size
172
- * @param {Set<string>} types types
175
+ * @param {Types} types types
173
176
  * @returns {number} selective size sum
174
177
  */
175
178
  const selectiveSizeSum = (size, types) => {