webpack 5.103.0 → 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 (176) hide show
  1. package/hot/dev-server.js +18 -3
  2. package/hot/emitter-event-target.js +7 -0
  3. package/hot/lazy-compilation-node.js +45 -29
  4. package/hot/lazy-compilation-universal.js +18 -0
  5. package/hot/lazy-compilation-web.js +15 -5
  6. package/hot/load-http.js +7 -0
  7. package/hot/only-dev-server.js +19 -4
  8. package/lib/APIPlugin.js +6 -0
  9. package/lib/Chunk.js +1 -1
  10. package/lib/ChunkGraph.js +9 -7
  11. package/lib/ChunkGroup.js +8 -5
  12. package/lib/CleanPlugin.js +6 -3
  13. package/lib/CodeGenerationResults.js +2 -1
  14. package/lib/CompatibilityPlugin.js +3 -0
  15. package/lib/Compilation.js +33 -19
  16. package/lib/Compiler.js +3 -3
  17. package/lib/ContextModule.js +6 -3
  18. package/lib/ContextModuleFactory.js +6 -4
  19. package/lib/DefinePlugin.js +34 -3
  20. package/lib/DelegatedModule.js +7 -4
  21. package/lib/DllModule.js +6 -3
  22. package/lib/DotenvPlugin.js +11 -6
  23. package/lib/ExportsInfo.js +5 -5
  24. package/lib/ExternalModule.js +8 -7
  25. package/lib/ExternalModuleFactoryPlugin.js +1 -1
  26. package/lib/FileSystemInfo.js +1 -1
  27. package/lib/Generator.js +10 -7
  28. package/lib/HookWebpackError.js +33 -4
  29. package/lib/HotModuleReplacementPlugin.js +22 -0
  30. package/lib/ManifestPlugin.js +1 -1
  31. package/lib/Module.js +24 -15
  32. package/lib/ModuleBuildError.js +1 -1
  33. package/lib/ModuleError.js +1 -1
  34. package/lib/ModuleFilenameHelpers.js +1 -1
  35. package/lib/ModuleGraph.js +27 -12
  36. package/lib/ModuleGraphConnection.js +2 -2
  37. package/lib/ModuleSourceTypeConstants.js +189 -0
  38. package/lib/ModuleTypeConstants.js +1 -4
  39. package/lib/ModuleWarning.js +1 -1
  40. package/lib/NodeStuffPlugin.js +52 -42
  41. package/lib/NormalModule.js +6 -4
  42. package/lib/NormalModuleFactory.js +7 -10
  43. package/lib/Parser.js +1 -1
  44. package/lib/RawModule.js +7 -4
  45. package/lib/RuntimeModule.js +1 -1
  46. package/lib/RuntimeTemplate.js +5 -1
  47. package/lib/SourceMapDevToolPlugin.js +6 -1
  48. package/lib/Template.js +17 -6
  49. package/lib/TemplatedPathPlugin.js +5 -6
  50. package/lib/WebpackError.js +0 -1
  51. package/lib/WebpackOptionsApply.js +37 -9
  52. package/lib/asset/AssetBytesGenerator.js +15 -11
  53. package/lib/asset/AssetGenerator.js +30 -24
  54. package/lib/asset/AssetSourceGenerator.js +15 -11
  55. package/lib/asset/RawDataUrlModule.js +6 -3
  56. package/lib/buildChunkGraph.js +4 -2
  57. package/lib/cache/PackFileCacheStrategy.js +6 -5
  58. package/lib/cli.js +2 -43
  59. package/lib/config/browserslistTargetHandler.js +19 -0
  60. package/lib/config/defaults.js +128 -43
  61. package/lib/config/normalization.js +2 -2
  62. package/lib/config/target.js +5 -0
  63. package/lib/container/ContainerEntryModule.js +6 -3
  64. package/lib/container/FallbackModule.js +6 -3
  65. package/lib/container/RemoteModule.js +1 -3
  66. package/lib/css/CssGenerator.js +26 -24
  67. package/lib/css/CssLoadingRuntimeModule.js +12 -4
  68. package/lib/css/CssModulesPlugin.js +29 -74
  69. package/lib/css/CssParser.js +828 -341
  70. package/lib/css/walkCssTokens.js +33 -13
  71. package/lib/dependencies/CachedConstDependency.js +24 -10
  72. package/lib/dependencies/CommonJsRequireContextDependency.js +1 -1
  73. package/lib/dependencies/ContextDependencyHelpers.js +2 -2
  74. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +3 -1
  75. package/lib/dependencies/CssIcssExportDependency.js +242 -104
  76. package/lib/dependencies/CssIcssImportDependency.js +61 -4
  77. package/lib/dependencies/CssIcssSymbolDependency.js +2 -6
  78. package/lib/dependencies/CssImportDependency.js +2 -1
  79. package/lib/dependencies/CssUrlDependency.js +3 -2
  80. package/lib/dependencies/DynamicExports.js +7 -7
  81. package/lib/dependencies/ExternalModuleDependency.js +7 -4
  82. package/lib/dependencies/ExternalModuleInitFragment.js +2 -1
  83. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +2 -1
  84. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +3 -2
  85. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +1 -1
  86. package/lib/dependencies/HarmonyExports.js +4 -4
  87. package/lib/dependencies/HarmonyImportDependency.js +8 -3
  88. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
  89. package/lib/dependencies/ImportMetaPlugin.js +57 -0
  90. package/lib/dependencies/ImportParserPlugin.js +2 -2
  91. package/lib/dependencies/LocalModulesHelpers.js +3 -3
  92. package/lib/dependencies/WorkerPlugin.js +2 -2
  93. package/lib/dependencies/getFunctionExpression.js +1 -1
  94. package/lib/esm/ModuleChunkFormatPlugin.js +5 -4
  95. package/lib/hmr/HotModuleReplacement.runtime.js +2 -1
  96. package/lib/hmr/LazyCompilationPlugin.js +4 -3
  97. package/lib/ids/IdHelpers.js +16 -7
  98. package/lib/javascript/ChunkHelpers.js +1 -1
  99. package/lib/javascript/JavascriptGenerator.js +4 -3
  100. package/lib/javascript/JavascriptModulesPlugin.js +57 -24
  101. package/lib/javascript/JavascriptParser.js +19 -6
  102. package/lib/json/JsonGenerator.js +5 -4
  103. package/lib/json/JsonParser.js +2 -1
  104. package/lib/library/AbstractLibraryPlugin.js +1 -1
  105. package/lib/library/AmdLibraryPlugin.js +4 -1
  106. package/lib/library/ExportPropertyLibraryPlugin.js +4 -1
  107. package/lib/library/ModuleLibraryPlugin.js +41 -13
  108. package/lib/library/SystemLibraryPlugin.js +4 -1
  109. package/lib/library/UmdLibraryPlugin.js +1 -1
  110. package/lib/logging/Logger.js +5 -4
  111. package/lib/logging/createConsoleLogger.js +2 -2
  112. package/lib/optimize/ConcatenatedModule.js +47 -32
  113. package/lib/optimize/ModuleConcatenationPlugin.js +5 -4
  114. package/lib/optimize/SideEffectsFlagPlugin.js +3 -2
  115. package/lib/optimize/SplitChunksPlugin.js +60 -46
  116. package/lib/rules/RuleSetCompiler.js +1 -1
  117. package/lib/runtime/GetChunkFilenameRuntimeModule.js +3 -2
  118. package/lib/schemes/HttpUriPlugin.js +78 -7
  119. package/lib/serialization/AggregateErrorSerializer.js +1 -2
  120. package/lib/serialization/ObjectMiddleware.js +0 -2
  121. package/lib/serialization/SingleItemMiddleware.js +1 -1
  122. package/lib/sharing/ConsumeSharedModule.js +1 -1
  123. package/lib/sharing/ConsumeSharedPlugin.js +5 -3
  124. package/lib/sharing/ProvideSharedModule.js +1 -1
  125. package/lib/sharing/resolveMatchedConfigs.js +15 -9
  126. package/lib/sharing/utils.js +1 -1
  127. package/lib/stats/DefaultStatsFactoryPlugin.js +8 -5
  128. package/lib/stats/DefaultStatsPresetPlugin.js +1 -1
  129. package/lib/stats/DefaultStatsPrinterPlugin.js +1 -1
  130. package/lib/util/StringXor.js +1 -1
  131. package/lib/util/URLAbsoluteSpecifier.js +2 -2
  132. package/lib/util/binarySearchBounds.js +2 -2
  133. package/lib/util/comparators.js +53 -76
  134. package/lib/util/compileBooleanMatcher.js +78 -6
  135. package/lib/util/createHash.js +20 -199
  136. package/lib/util/deprecation.js +1 -1
  137. package/lib/util/deterministicGrouping.js +6 -3
  138. package/lib/util/fs.js +75 -75
  139. package/lib/util/hash/BatchedHash.js +10 -9
  140. package/lib/util/hash/BulkUpdateHash.js +138 -0
  141. package/lib/util/hash/DebugHash.js +75 -0
  142. package/lib/util/hash/hash-digest.js +216 -0
  143. package/lib/util/identifier.js +82 -17
  144. package/lib/util/internalSerializables.js +2 -6
  145. package/lib/util/runtime.js +3 -3
  146. package/lib/util/source.js +2 -2
  147. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +3 -2
  148. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +3 -2
  149. package/lib/wasm-sync/WebAssemblyGenerator.js +9 -6
  150. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +3 -2
  151. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +6 -2
  152. package/lib/webpack.js +1 -1
  153. package/package.json +29 -25
  154. package/schemas/WebpackOptions.check.js +1 -1
  155. package/schemas/WebpackOptions.json +59 -82
  156. package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +1 -1
  157. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  158. package/types.d.ts +225 -157
  159. package/lib/ModuleSourceTypesConstants.js +0 -117
  160. package/lib/dependencies/CssIcssFromIdentifierDependency.js +0 -124
  161. package/lib/dependencies/CssIcssGlobalIdentifierDependency.js +0 -48
  162. package/lib/dependencies/CssIcssLocalIdentifierDependency.js +0 -61
  163. package/lib/dependencies/CssIcssSelfLocalIdentifierDependency.js +0 -190
  164. package/lib/util/jsonParseEvenBetterErrors.js +0 -10
  165. package/schemas/plugins/css/CssAutoGeneratorOptions.check.d.ts +0 -7
  166. package/schemas/plugins/css/CssAutoGeneratorOptions.check.js +0 -6
  167. package/schemas/plugins/css/CssAutoGeneratorOptions.json +0 -3
  168. package/schemas/plugins/css/CssAutoParserOptions.check.d.ts +0 -7
  169. package/schemas/plugins/css/CssAutoParserOptions.check.js +0 -6
  170. package/schemas/plugins/css/CssAutoParserOptions.json +0 -3
  171. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.d.ts +0 -7
  172. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.js +0 -6
  173. package/schemas/plugins/css/CssGlobalGeneratorOptions.json +0 -3
  174. package/schemas/plugins/css/CssGlobalParserOptions.check.d.ts +0 -7
  175. package/schemas/plugins/css/CssGlobalParserOptions.check.js +0 -6
  176. package/schemas/plugins/css/CssGlobalParserOptions.json +0 -3
@@ -34,6 +34,8 @@ const memoize = require("../util/memoize");
34
34
  const getHttp = memoize(() => require("http"));
35
35
  const getHttps = memoize(() => require("https"));
36
36
 
37
+ const MAX_REDIRECTS = 5;
38
+
37
39
  /**
38
40
  * @param {typeof import("http") | typeof import("https")} request request
39
41
  * @param {string | URL | undefined} proxy proxy
@@ -200,6 +202,22 @@ const areLockfileEntriesEqual = (a, b) =>
200
202
  const entryToString = (entry) =>
201
203
  `resolved: ${entry.resolved}, integrity: ${entry.integrity}, contentType: ${entry.contentType}`;
202
204
 
205
+ /**
206
+ * Sanitize URL for inclusion in error messages
207
+ * @param {string} href URL string to sanitize
208
+ * @returns {string} sanitized URL text for logs/errors
209
+ */
210
+ const sanitizeUrlForError = (href) => {
211
+ try {
212
+ const u = new URL(href);
213
+ return `${u.protocol}//${u.host}`;
214
+ } catch (_err) {
215
+ return String(href)
216
+ .slice(0, 200)
217
+ .replace(/[\r\n]/g, "");
218
+ }
219
+ };
220
+
203
221
  class Lockfile {
204
222
  constructor() {
205
223
  this.version = 1;
@@ -317,7 +335,7 @@ const cachedWithoutKey = (fn) => {
317
335
  * @template R
318
336
  * @param {FnWithKey<T, R>} fn function
319
337
  * @param {FnWithKey<T, R>=} forceFn function for the second try
320
- * @returns {(FnWithKey<T, R>) & { force: FnWithKey<T, R> }} cached function
338
+ * @returns {FnWithKey<T, R> & { force: FnWithKey<T, R> }} cached function
321
339
  */
322
340
  const cachedWithKey = (fn, forceFn = fn) => {
323
341
  /**
@@ -636,12 +654,47 @@ class HttpUriPlugin {
636
654
  };
637
655
 
638
656
  for (const { scheme, fetch } of schemes) {
657
+ /**
658
+ * @param {string} location Location header value (relative or absolute)
659
+ * @param {string} base current absolute URL
660
+ * @returns {string} absolute, validated redirect target
661
+ */
662
+ const validateRedirectLocation = (location, base) => {
663
+ let nextUrl;
664
+ try {
665
+ nextUrl = new URL(location, base);
666
+ } catch (err) {
667
+ throw new Error(
668
+ `Invalid redirect URL: ${sanitizeUrlForError(location)}`,
669
+ { cause: err }
670
+ );
671
+ }
672
+ if (nextUrl.protocol !== "http:" && nextUrl.protocol !== "https:") {
673
+ throw new Error(
674
+ `Redirected URL uses disallowed protocol: ${sanitizeUrlForError(nextUrl.href)}`
675
+ );
676
+ }
677
+ if (!isAllowed(nextUrl.href)) {
678
+ throw new Error(
679
+ `${nextUrl.href} doesn't match the allowedUris policy after redirect. These URIs are allowed:\n${allowedUris
680
+ .map((uri) => ` - ${uri}`)
681
+ .join("\n")}`
682
+ );
683
+ }
684
+ return nextUrl.href;
685
+ };
639
686
  /**
640
687
  * @param {string} url URL
641
688
  * @param {string | null} integrity integrity
642
689
  * @param {(err: Error | null, resolveContentResult?: ResolveContentResult) => void} callback callback
690
+ * @param {number=} redirectCount number of followed redirects
643
691
  */
644
- const resolveContent = (url, integrity, callback) => {
692
+ const resolveContent = (
693
+ url,
694
+ integrity,
695
+ callback,
696
+ redirectCount = 0
697
+ ) => {
645
698
  /**
646
699
  * @param {Error | null} err error
647
700
  * @param {FetchResult=} _result fetch result
@@ -653,8 +706,18 @@ class HttpUriPlugin {
653
706
  const result = /** @type {FetchResult} */ (_result);
654
707
 
655
708
  if ("location" in result) {
709
+ // Validate redirect target before following
710
+ let absolute;
711
+ try {
712
+ absolute = validateRedirectLocation(result.location, url);
713
+ } catch (err_) {
714
+ return callback(/** @type {Error} */ (err_));
715
+ }
716
+ if (redirectCount >= MAX_REDIRECTS) {
717
+ return callback(new Error("Too many redirects"));
718
+ }
656
719
  return resolveContent(
657
- result.location,
720
+ absolute,
658
721
  integrity,
659
722
  (err, innerResult) => {
660
723
  if (err) return callback(err);
@@ -665,7 +728,8 @@ class HttpUriPlugin {
665
728
  content,
666
729
  storeLock: storeLock && result.storeLock
667
730
  });
668
- }
731
+ },
732
+ redirectCount + 1
669
733
  );
670
734
  }
671
735
 
@@ -781,9 +845,16 @@ class HttpUriPlugin {
781
845
  res.statusCode >= 301 &&
782
846
  res.statusCode <= 308
783
847
  ) {
784
- const result = {
785
- location: new URL(location, url).href
786
- };
848
+ let absolute;
849
+ try {
850
+ absolute = validateRedirectLocation(location, url);
851
+ } catch (err) {
852
+ logger.log(
853
+ `GET ${url} [${res.statusCode}] -> ${String(location)} (rejected: ${/** @type {Error} */ (err).message})`
854
+ );
855
+ return callback(/** @type {Error} */ (err));
856
+ }
857
+ const result = { location: absolute };
787
858
  if (
788
859
  !cachedResult ||
789
860
  !("location" in cachedResult) ||
@@ -7,7 +7,7 @@
7
7
  /** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
8
8
  /** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
9
9
 
10
- /** @typedef {Error & { cause: unknown, errors: EXPECTED_ANY[] }} AggregateError */
10
+ /** @typedef {Error & { cause?: unknown, errors: EXPECTED_ANY[] }} AggregateError */
11
11
 
12
12
  class AggregateErrorSerializer {
13
13
  /**
@@ -27,7 +27,6 @@ class AggregateErrorSerializer {
27
27
  */
28
28
  deserialize(context) {
29
29
  const errors = context.read();
30
- // @ts-expect-error ES2018 doesn't `AggregateError`, but it can be used by developers
31
30
  // eslint-disable-next-line n/no-unsupported-features/es-builtins, n/no-unsupported-features/es-syntax, unicorn/error-message
32
31
  const err = new AggregateError(errors);
33
32
 
@@ -157,11 +157,9 @@ jsTypes.set(ReferenceError, new ErrorObjectSerializer(ReferenceError));
157
157
  jsTypes.set(SyntaxError, new ErrorObjectSerializer(SyntaxError));
158
158
  jsTypes.set(TypeError, new ErrorObjectSerializer(TypeError));
159
159
 
160
- // @ts-expect-error ES2018 doesn't `AggregateError`, but it can be used by developers
161
160
  // eslint-disable-next-line n/no-unsupported-features/es-builtins, n/no-unsupported-features/es-syntax
162
161
  if (typeof AggregateError !== "undefined") {
163
162
  jsTypes.set(
164
- // @ts-expect-error ES2018 doesn't `AggregateError`, but it can be used by developers
165
163
  // eslint-disable-next-line n/no-unsupported-features/es-builtins, n/no-unsupported-features/es-syntax
166
164
  AggregateError,
167
165
  new AggregateErrorSerializer()
@@ -8,7 +8,7 @@ const SerializerMiddleware = require("./SerializerMiddleware");
8
8
 
9
9
  /** @typedef {EXPECTED_ANY} DeserializedType */
10
10
  /** @typedef {EXPECTED_ANY[]} SerializedType */
11
- /** @typedef {{}} Context */
11
+ /** @typedef {EXPECTED_OBJECT} Context */
12
12
 
13
13
  /**
14
14
  * @extends {SerializerMiddleware<DeserializedType, SerializedType, Context>}
@@ -8,7 +8,7 @@
8
8
  const { RawSource } = require("webpack-sources");
9
9
  const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
10
10
  const Module = require("../Module");
11
- const { CONSUME_SHARED_TYPES } = require("../ModuleSourceTypesConstants");
11
+ const { CONSUME_SHARED_TYPES } = require("../ModuleSourceTypeConstants");
12
12
  const {
13
13
  WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE
14
14
  } = require("../ModuleTypeConstants");
@@ -119,11 +119,13 @@ class ConsumeSharedPlugin {
119
119
  normalModuleFactory
120
120
  );
121
121
 
122
- /** @type {Map<string, ConsumeOptions>} */
122
+ /** @typedef {Map<string, ConsumeOptions>} Consumes */
123
+
124
+ /** @type {Consumes} */
123
125
  let unresolvedConsumes;
124
- /** @type {Map<string, ConsumeOptions>} */
126
+ /** @type {Consumes} */
125
127
  let resolvedConsumes;
126
- /** @type {Map<string, ConsumeOptions>} */
128
+ /** @type {Consumes} */
127
129
  let prefixedConsumes;
128
130
  const promise = resolveMatchedConfigs(compilation, this._consumes).then(
129
131
  ({ resolved, unresolved, prefixed }) => {
@@ -7,7 +7,7 @@
7
7
 
8
8
  const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
9
9
  const Module = require("../Module");
10
- const { SHARED_INIT_TYPES } = require("../ModuleSourceTypesConstants");
10
+ const { SHARED_INIT_TYPES } = require("../ModuleSourceTypeConstants");
11
11
  const { WEBPACK_MODULE_TYPE_PROVIDE } = require("../ModuleTypeConstants");
12
12
  const RuntimeGlobals = require("../RuntimeGlobals");
13
13
  const makeSerializable = require("../util/makeSerializable");
@@ -10,14 +10,20 @@ const LazySet = require("../util/LazySet");
10
10
 
11
11
  /** @typedef {import("enhanced-resolve").ResolveContext} ResolveContext */
12
12
  /** @typedef {import("../Compilation")} Compilation */
13
+ /** @typedef {import("../Compilation").FileSystemDependencies} FileSystemDependencies */
13
14
  /** @typedef {import("../ResolverFactory").ResolveOptionsWithDependencyType} ResolveOptionsWithDependencyType */
14
15
 
16
+ /**
17
+ * @template T
18
+ * @typedef {Map<string, T>} MatchedConfigsItem
19
+ */
20
+
15
21
  /**
16
22
  * @template T
17
23
  * @typedef {object} MatchedConfigs
18
- * @property {Map<string, T>} resolved
19
- * @property {Map<string, T>} unresolved
20
- * @property {Map<string, T>} prefixed
24
+ * @property {MatchedConfigsItem<T>} resolved
25
+ * @property {MatchedConfigsItem<T>} unresolved
26
+ * @property {MatchedConfigsItem<T>} prefixed
21
27
  */
22
28
 
23
29
  /** @type {ResolveOptionsWithDependencyType} */
@@ -30,11 +36,11 @@ const RESOLVE_OPTIONS = { dependencyType: "esm" };
30
36
  * @returns {Promise<MatchedConfigs<T>>} resolved matchers
31
37
  */
32
38
  module.exports.resolveMatchedConfigs = (compilation, configs) => {
33
- /** @type {Map<string, T>} */
39
+ /** @type {MatchedConfigsItem<T>} */
34
40
  const resolved = new Map();
35
- /** @type {Map<string, T>} */
41
+ /** @type {MatchedConfigsItem<T>} */
36
42
  const unresolved = new Map();
37
- /** @type {Map<string, T>} */
43
+ /** @type {MatchedConfigsItem<T>} */
38
44
  const prefixed = new Map();
39
45
  /** @type {ResolveContext} */
40
46
  const resolveContext = {
@@ -84,15 +90,15 @@ module.exports.resolveMatchedConfigs = (compilation, configs) => {
84
90
  })
85
91
  ).then(() => {
86
92
  compilation.contextDependencies.addAll(
87
- /** @type {LazySet<string>} */
93
+ /** @type {FileSystemDependencies} */
88
94
  (resolveContext.contextDependencies)
89
95
  );
90
96
  compilation.fileDependencies.addAll(
91
- /** @type {LazySet<string>} */
97
+ /** @type {FileSystemDependencies} */
92
98
  (resolveContext.fileDependencies)
93
99
  );
94
100
  compilation.missingDependencies.addAll(
95
- /** @type {LazySet<string>} */
101
+ /** @type {FileSystemDependencies} */
96
102
  (resolveContext.missingDependencies)
97
103
  );
98
104
  return { resolved, unresolved, prefixed };
@@ -379,7 +379,7 @@ const getRequiredVersionFromDescriptionFile = (data, packageName) => {
379
379
  packageName in dependency
380
380
  ) {
381
381
  return normalizeVersion(
382
- /** @type {Exclude<JsonPrimitive, null | boolean| number>} */ (
382
+ /** @type {Exclude<JsonPrimitive, null | boolean | number>} */ (
383
383
  dependency[packageName]
384
384
  )
385
385
  );
@@ -49,6 +49,8 @@ const { makePathsRelative, parseResource } = require("../util/identifier");
49
49
  /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
50
50
  /** @typedef {import("../ModuleProfile")} ModuleProfile */
51
51
  /** @typedef {import("../WebpackError")} WebpackError */
52
+ /** @typedef {import("../serialization/AggregateErrorSerializer").AggregateError} AggregateError */
53
+ /** @typedef {import("../serialization/ErrorObjectSerializer").ErrorWithCause} ErrorWithCause */
52
54
  /** @typedef {import("../ExportsInfo").ExportInfoName} ExportInfoName */
53
55
 
54
56
  /**
@@ -370,13 +372,17 @@ const uniqueArray = (items, selector) => {
370
372
  const uniqueOrderedArray = (items, selector, comparator) =>
371
373
  uniqueArray(items, selector).sort(comparator);
372
374
 
373
- /** @template T @template R @typedef {{ [P in keyof T]: R }} MappedValues<T, R> */
375
+ /**
376
+ * @template T
377
+ * @template R
378
+ * @typedef {{ [P in keyof T]: R }} MappedValues<T, R>
379
+ */
374
380
 
375
381
  /**
376
382
  * @template {object} T
377
383
  * @template {object} R
378
384
  * @param {T} obj object to be mapped
379
- * @param {function(T[keyof T], keyof T): R} fn mapping function
385
+ * @param {(value: T[keyof T], key: keyof T) => R} fn mapping function
380
386
  * @returns {MappedValues<T, R>} mapped object
381
387
  */
382
388
  const mapObject = (obj, fn) => {
@@ -406,9 +412,6 @@ const countWithChildren = (compilation, getItems) => {
406
412
  return count;
407
413
  };
408
414
 
409
- /** @typedef {Error & { cause?: unknown }} ErrorWithCause */
410
- /** @typedef {Error & { errors: EXPECTED_ANY[] }} AggregateError */
411
-
412
415
  /** @type {ExtractorsByOption<string | ErrorWithCause | AggregateError | WebpackError, StatsError>} */
413
416
  const EXTRACT_ERROR = {
414
417
  _: (object, error, context, { requestShortener }) => {
@@ -30,7 +30,7 @@ const applyDefaults = (options, defaults) => {
30
30
  }
31
31
  };
32
32
 
33
- /** @typedef {{ [Key in Exclude<StatsValue, boolean | object | "normal">]: StatsOptions }} NamedPresets */
33
+ /** @typedef {{ [Key in Exclude<StatsValue, boolean | EXPECTED_OBJECT | "normal">]: StatsOptions }} NamedPresets */
34
34
 
35
35
  /** @type {NamedPresets} */
36
36
  const NAMED_PRESETS = {
@@ -76,7 +76,7 @@ const getResourceName = (resource) => {
76
76
 
77
77
  /**
78
78
  * @param {string} name module name
79
- * @returns {[string,string]} prefix and module name
79
+ * @returns {[string, string]} prefix and module name
80
80
  */
81
81
  const getModuleName = (name) => {
82
82
  const [, prefix, resource] =
@@ -36,7 +36,7 @@
36
36
  */
37
37
  class StringXor {
38
38
  constructor() {
39
- /** @type {Buffer|undefined} */
39
+ /** @type {Buffer | undefined} */
40
40
  this._value = undefined;
41
41
  }
42
42
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- /** @typedef {(error: Error|null, result?: Buffer) => void} ErrorFirstCallback */
8
+ /** @typedef {(error: Error | null, result?: Buffer) => void} ErrorFirstCallback */
9
9
 
10
10
  const backSlashCharCode = "\\".charCodeAt(0);
11
11
  const slashCharCode = "/".charCodeAt(0);
@@ -25,7 +25,7 @@ const queryCharCode = "?".charCodeAt(0);
25
25
  * e.g. Absolute specifiers like 'file:///user/webpack/index.js'
26
26
  * https://tools.ietf.org/html/rfc3986#section-3.1
27
27
  * @param {string} specifier specifier
28
- * @returns {string|undefined} scheme if absolute URL specifier provided
28
+ * @returns {string | undefined} scheme if absolute URL specifier provided
29
29
  */
30
30
  function getScheme(specifier) {
31
31
  const start = specifier.charCodeAt(0);
@@ -8,8 +8,8 @@
8
8
  /* cspell:disable-next-line */
9
9
  // Refactor: Peter Somogyvari @petermetz
10
10
 
11
- /** @typedef {">=" | "<=" | "<" | ">" | "-" } BinarySearchPredicate */
12
- /** @typedef {"GE" | "GT" | "LT" | "LE" | "EQ" } SearchPredicateSuffix */
11
+ /** @typedef {">=" | "<=" | "<" | ">" | "-"} BinarySearchPredicate */
12
+ /** @typedef {"GE" | "GT" | "LT" | "LE" | "EQ"} SearchPredicateSuffix */
13
13
 
14
14
  /**
15
15
  * Helper function for compiling binary search functions.
@@ -57,7 +57,7 @@ const createCachedParameterizedComparator = (fn) => {
57
57
  /**
58
58
  * @param {T} a first item
59
59
  * @param {T} b second item
60
- * @returns {-1|0|1} compare result
60
+ * @returns {-1 | 0 | 1} compare result
61
61
  */
62
62
  const result = fn.bind(null, arg);
63
63
  map.set(/** @type {EXPECTED_OBJECT} */ (arg), result);
@@ -90,7 +90,7 @@ const compareIterables = (elementComparator) => {
90
90
  /**
91
91
  * @param {Iterable<T>} a first value
92
92
  * @param {Iterable<T>} b second value
93
- * @returns {-1|0|1} compare result
93
+ * @returns {-1 | 0 | 1} compare result
94
94
  */
95
95
  const result = (a, b) => {
96
96
  const aI = a[Symbol.iterator]();
@@ -115,7 +115,7 @@ const compareIterables = (elementComparator) => {
115
115
  * Compare two locations
116
116
  * @param {DependencyLocation} a A location node
117
117
  * @param {DependencyLocation} b A location node
118
- * @returns {-1|0|1} sorting comparator value
118
+ * @returns {-1 | 0 | 1} sorting comparator value
119
119
  */
120
120
  const compareLocations = (a, b) => {
121
121
  const isObjectA = typeof a === "object" && a !== null;
@@ -178,7 +178,7 @@ const compareLocations = (a, b) => {
178
178
  * @param {ChunkGraph} chunkGraph the chunk graph
179
179
  * @param {Module} a module
180
180
  * @param {Module} b module
181
- * @returns {-1|0|1} compare result
181
+ * @returns {-1 | 0 | 1} compare result
182
182
  */
183
183
  const compareModulesById = (chunkGraph, a, b) =>
184
184
  compareIds(
@@ -189,7 +189,7 @@ const compareModulesById = (chunkGraph, a, b) =>
189
189
  /**
190
190
  * @param {number} a number
191
191
  * @param {number} b number
192
- * @returns {-1|0|1} compare result
192
+ * @returns {-1 | 0 | 1} compare result
193
193
  */
194
194
  const compareNumbers = (a, b) => {
195
195
  if (typeof a !== typeof b) {
@@ -203,7 +203,7 @@ const compareNumbers = (a, b) => {
203
203
  /**
204
204
  * @param {string} a string
205
205
  * @param {string} b string
206
- * @returns {-1|0|1} compare result
206
+ * @returns {-1 | 0 | 1} compare result
207
207
  */
208
208
  const compareStringsNumeric = (a, b) => {
209
209
  const aLength = a.length;
@@ -275,7 +275,7 @@ const compareStringsNumeric = (a, b) => {
275
275
  * @param {ModuleGraph} moduleGraph the module graph
276
276
  * @param {Module} a module
277
277
  * @param {Module} b module
278
- * @returns {-1|0|1} compare result
278
+ * @returns {-1 | 0 | 1} compare result
279
279
  */
280
280
  const compareModulesByPostOrderIndexOrIdentifier = (moduleGraph, a, b) => {
281
281
  const cmp = compareNumbers(
@@ -290,7 +290,7 @@ const compareModulesByPostOrderIndexOrIdentifier = (moduleGraph, a, b) => {
290
290
  * @param {ModuleGraph} moduleGraph the module graph
291
291
  * @param {Module} a module
292
292
  * @param {Module} b module
293
- * @returns {-1|0|1} compare result
293
+ * @returns {-1 | 0 | 1} compare result
294
294
  */
295
295
  const compareModulesByPreOrderIndexOrIdentifier = (moduleGraph, a, b) => {
296
296
  const cmp = compareNumbers(
@@ -305,7 +305,7 @@ const compareModulesByPreOrderIndexOrIdentifier = (moduleGraph, a, b) => {
305
305
  * @param {ChunkGraph} chunkGraph the chunk graph
306
306
  * @param {Module} a module
307
307
  * @param {Module} b module
308
- * @returns {-1|0|1} compare result
308
+ * @returns {-1 | 0 | 1} compare result
309
309
  */
310
310
  const compareModulesByIdOrIdentifier = (chunkGraph, a, b) => {
311
311
  const cmp = compareIds(
@@ -327,7 +327,7 @@ const compareChunks = (chunkGraph, a, b) => chunkGraph.compareChunks(a, b);
327
327
  /**
328
328
  * @param {string} a first string
329
329
  * @param {string} b second string
330
- * @returns {-1|0|1} compare result
330
+ * @returns {-1 | 0 | 1} compare result
331
331
  */
332
332
  const compareStrings = (a, b) => {
333
333
  if (a < b) return -1;
@@ -408,7 +408,7 @@ const concatComparators = (c1, c2, ...cRest) => {
408
408
  /**
409
409
  * @param {T} a first value
410
410
  * @param {T} b second value
411
- * @returns {-1|0|1} compare result
411
+ * @returns {-1 | 0 | 1} compare result
412
412
  */
413
413
  const result = (a, b) => {
414
414
  const res = c1(a, b);
@@ -440,7 +440,7 @@ const compareSelect = (getter, comparator) => {
440
440
  /**
441
441
  * @param {T} a first value
442
442
  * @param {T} b second value
443
- * @returns {-1|0|1} compare result
443
+ * @returns {-1 | 0 | 1} compare result
444
444
  */
445
445
  const result = (a, b) => {
446
446
  const aValue = getter(a);
@@ -511,47 +511,42 @@ const compareChunksNatural = (chunkGraph) => {
511
511
  * https://github.com/webpack/webpack/pull/19686
512
512
  * @param {Dependency[]} dependencies dependencies
513
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
514
515
  * @returns {void}
515
516
  */
516
- const sortWithSourceOrder = (dependencies, dependencySourceOrderMap) => {
517
- /**
518
- * @param {Dependency} dep dependency
519
- * @returns {number} source order
520
- */
521
- const getSourceOrder = (dep) => {
522
- if (dependencySourceOrderMap.has(dep)) {
523
- const { main } = /** @type {DependencySourceOrder} */ (
524
- dependencySourceOrderMap.get(dep)
525
- );
526
- return main;
527
- }
528
- return /** @type {number} */ (
529
- /** @type {ModuleDependency} */ (dep).sourceOrder
530
- );
531
- };
532
-
533
- /**
534
- * If the sourceOrder is a number, it means the dependency needs to be sorted.
535
- * @param {number | undefined} sourceOrder sourceOrder
536
- * @returns {boolean} needReSort
537
- */
538
- const needReSort = (sourceOrder) => {
539
- if (typeof sourceOrder === "number") {
540
- return true;
541
- }
542
- return false;
543
- };
544
-
545
- // 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}[]} */
546
523
  const withSourceOrder = [];
524
+ /** @type {number[]} */
525
+ const positions = [];
547
526
 
548
- // First pass: collect dependencies with sourceOrder
549
527
  for (let i = 0; i < dependencies.length; i++) {
550
528
  const dep = dependencies[i];
551
- const sourceOrder = getSourceOrder(dep);
552
-
553
- if (needReSort(sourceOrder)) {
554
- 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
+ }
555
550
  }
556
551
  }
557
552
 
@@ -559,37 +554,19 @@ const sortWithSourceOrder = (dependencies, dependencySourceOrderMap) => {
559
554
  return;
560
555
  }
561
556
 
562
- // Sort dependencies with sourceOrder
563
557
  withSourceOrder.sort((a, b) => {
564
- // Handle both dependencies in map case
565
- if (
566
- dependencySourceOrderMap.has(a.dep) &&
567
- dependencySourceOrderMap.has(b.dep)
568
- ) {
569
- const { main: mainA, sub: subA } = /** @type {DependencySourceOrder} */ (
570
- dependencySourceOrderMap.get(a.dep)
571
- );
572
- const { main: mainB, sub: subB } = /** @type {DependencySourceOrder} */ (
573
- dependencySourceOrderMap.get(b.dep)
574
- );
575
- if (mainA === mainB) {
576
- return compareNumbers(subA, subB);
577
- }
578
- return compareNumbers(mainA, mainB);
558
+ if (a.main !== b.main) {
559
+ return compareNumbers(a.main, b.main);
579
560
  }
580
-
581
- return compareNumbers(a.sourceOrder, b.sourceOrder);
561
+ return compareNumbers(a.sub, b.sub);
582
562
  });
583
563
 
584
- // Second pass: build result array
585
- let sortedIndex = 0;
586
- for (let i = 0; i < dependencies.length; i++) {
587
- const dep = dependencies[i];
588
- const sourceOrder = getSourceOrder(dep);
589
-
590
- if (needReSort(sourceOrder)) {
591
- dependencies[i] = withSourceOrder[sortedIndex].dep;
592
- 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);
593
570
  }
594
571
  }
595
572
  };
@@ -601,7 +578,7 @@ module.exports.compareChunks =
601
578
  /**
602
579
  * @param {Chunk} a chunk
603
580
  * @param {Chunk} b chunk
604
- * @returns {-1|0|1} compare result
581
+ * @returns {-1 | 0 | 1} compare result
605
582
  */
606
583
  module.exports.compareChunksById = (a, b) =>
607
584
  compareIds(/** @type {ChunkId} */ (a.id), /** @type {ChunkId} */ (b.id));
@@ -622,7 +599,7 @@ module.exports.compareModulesByIdOrIdentifier =
622
599
  /**
623
600
  * @param {Module} a module
624
601
  * @param {Module} b module
625
- * @returns {-1|0|1} compare result
602
+ * @returns {-1 | 0 | 1} compare result
626
603
  */
627
604
  module.exports.compareModulesByIdentifier = (a, b) =>
628
605
  compareIds(a.identifier(), b.identifier());