webpack 5.100.1 → 5.100.2

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.
@@ -292,7 +292,7 @@ const { isSourceEqual } = require("./util/source");
292
292
  * @property {boolean=} development true, when asset is only used for development and doesn't count towards user-facing assets
293
293
  * @property {boolean=} hotModuleReplacement true, when asset ships data for updating an existing application (HMR)
294
294
  * @property {boolean=} javascriptModule true, when asset is javascript and an ESM
295
- * @property {Record<string, string | string[]>=} related object of pointers to other assets, keyed by type of relation (only points from parent to child)
295
+ * @property {Record<string, null | string | string[]>=} related object of pointers to other assets, keyed by type of relation (only points from parent to child)
296
296
  */
297
297
 
298
298
  /** @typedef {KnownAssetInfo & Record<string, EXPECTED_ANY>} AssetInfo */
@@ -10,6 +10,7 @@ const ExportsInfo = require("./ExportsInfo");
10
10
  const ModuleGraphConnection = require("./ModuleGraphConnection");
11
11
  const SortableSet = require("./util/SortableSet");
12
12
  const WeakTupleMap = require("./util/WeakTupleMap");
13
+ const { sortWithSourceOrder } = require("./util/comparators");
13
14
 
14
15
  /** @typedef {import("./Compilation").ModuleMemCaches} ModuleMemCaches */
15
16
  /** @typedef {import("./DependenciesBlock")} DependenciesBlock */
@@ -19,6 +20,9 @@ const WeakTupleMap = require("./util/WeakTupleMap");
19
20
  /** @typedef {import("./ModuleProfile")} ModuleProfile */
20
21
  /** @typedef {import("./RequestShortener")} RequestShortener */
21
22
  /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
23
+ /** @typedef {import("./dependencies/HarmonyImportSideEffectDependency")} HarmonyImportSideEffectDependency */
24
+ /** @typedef {import("./dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */
25
+ /** @typedef {import("./util/comparators").DependencySourceOrder} DependencySourceOrder */
22
26
 
23
27
  /**
24
28
  * @callback OptimizationBailoutFunction
@@ -158,6 +162,12 @@ class ModuleGraph {
158
162
  * @private
159
163
  */
160
164
  this._cacheStage = undefined;
165
+
166
+ /**
167
+ * @type {WeakMap<Dependency, DependencySourceOrder>}
168
+ * @private
169
+ */
170
+ this._dependencySourceOrderMap = new WeakMap();
161
171
  }
162
172
 
163
173
  /**
@@ -186,6 +196,15 @@ class ModuleGraph {
186
196
  dependency._parentModule = module;
187
197
  }
188
198
 
199
+ /**
200
+ * @param {Dependency} dependency the dependency
201
+ * @param {number} index the index
202
+ * @returns {void}
203
+ */
204
+ setParentDependenciesBlockIndex(dependency, index) {
205
+ dependency._parentDependenciesBlockIndex = index;
206
+ }
207
+
189
208
  /**
190
209
  * @param {Dependency} dependency the dependency
191
210
  * @returns {Module | undefined} parent module
@@ -265,6 +284,64 @@ class ModuleGraph {
265
284
  targetMgm.incomingConnections.add(newConnection);
266
285
  }
267
286
 
287
+ /**
288
+ * @param {Dependency} dependency the need update dependency
289
+ * @param {ModuleGraphConnection=} connection the target connection
290
+ * @param {Module=} parentModule the parent module
291
+ * @returns {void}
292
+ */
293
+ updateParent(dependency, connection, parentModule) {
294
+ if (this._dependencySourceOrderMap.has(dependency)) {
295
+ return;
296
+ }
297
+ if (!connection || !parentModule) {
298
+ return;
299
+ }
300
+ const originDependency = connection.dependency;
301
+
302
+ // src/index.js
303
+ // import { c } from "lib/c" -> c = 0
304
+ // import { a, b } from "lib" -> a and b have the same source order -> a = b = 1
305
+ // import { d } from "lib/d" -> d = 2
306
+ const currentSourceOrder =
307
+ /** @type { HarmonyImportSideEffectDependency | HarmonyImportSpecifierDependency} */ (
308
+ dependency
309
+ ).sourceOrder;
310
+
311
+ // lib/index.js (reexport)
312
+ // import { a } from "lib/a" -> a = 0
313
+ // import { b } from "lib/b" -> b = 1
314
+ const originSourceOrder =
315
+ /** @type { HarmonyImportSideEffectDependency | HarmonyImportSpecifierDependency} */ (
316
+ originDependency
317
+ ).sourceOrder;
318
+ if (
319
+ typeof currentSourceOrder === "number" &&
320
+ typeof originSourceOrder === "number"
321
+ ) {
322
+ // src/index.js
323
+ // import { c } from "lib/c" -> c = 0
324
+ // import { a } from "lib/a" -> a = 1.0 = 1(main) + 0.0(sub)
325
+ // import { b } from "lib/b" -> b = 1.1 = 1(main) + 0.1(sub)
326
+ // import { d } from "lib/d" -> d = 2
327
+ this._dependencySourceOrderMap.set(dependency, {
328
+ main: currentSourceOrder,
329
+ sub: originSourceOrder
330
+ });
331
+
332
+ // If dependencies like HarmonyImportSideEffectDependency and HarmonyImportSpecifierDependency have a SourceOrder,
333
+ // we sort based on it; otherwise, we preserve the original order.
334
+ sortWithSourceOrder(
335
+ parentModule.dependencies,
336
+ this._dependencySourceOrderMap
337
+ );
338
+
339
+ for (const [index, dep] of parentModule.dependencies.entries()) {
340
+ this.setParentDependenciesBlockIndex(dep, index);
341
+ }
342
+ }
343
+ }
344
+
268
345
  /**
269
346
  * @param {Dependency} dependency the referencing dependency
270
347
  * @returns {void}
@@ -40,7 +40,8 @@ const {
40
40
  compareLocations,
41
41
  compareSelect,
42
42
  concatComparators,
43
- keepOriginalOrder
43
+ keepOriginalOrder,
44
+ sortWithSourceOrder
44
45
  } = require("./util/comparators");
45
46
  const createHash = require("./util/createHash");
46
47
  const { createFakeHook } = require("./util/deprecation");
@@ -99,6 +100,8 @@ const memoize = require("./util/memoize");
99
100
  /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
100
101
  /** @typedef {import("../declarations/WebpackOptions").HashFunction} HashFunction */
101
102
  /** @typedef {import("./util/identifier").AssociatedObjectForCache} AssociatedObjectForCache */
103
+ /** @typedef {import("./dependencies/HarmonyImportSideEffectDependency")} HarmonyImportSideEffectDependency */
104
+ /** @typedef {import("./dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */
102
105
  /**
103
106
  * @template T
104
107
  * @typedef {import("./util/deprecation").FakeHook<T>} FakeHook
@@ -1221,6 +1224,7 @@ class NormalModule extends Module {
1221
1224
  keepOriginalOrder(this.dependencies)
1222
1225
  )
1223
1226
  );
1227
+ sortWithSourceOrder(this.dependencies, new WeakMap());
1224
1228
  this._initBuildHash(compilation);
1225
1229
  this._lastSuccessfulBuildMeta =
1226
1230
  /** @type {BuildMeta} */
@@ -8,6 +8,9 @@
8
8
  const InitFragment = require("./InitFragment");
9
9
  const RuntimeGlobals = require("./RuntimeGlobals");
10
10
  const Template = require("./Template");
11
+ const {
12
+ getOutgoingAsyncModules
13
+ } = require("./async-modules/AsyncModuleHelpers");
11
14
  const {
12
15
  getMakeDeferredNamespaceModeFromExportsType,
13
16
  getOptimizedDeferredModule
@@ -814,27 +817,12 @@ class RuntimeTemplate {
814
817
  ];
815
818
  }
816
819
 
817
- /** @type {Set<Module>} */
818
- const innerAsyncDependencies = new Set();
819
820
  defer = defer && (module.buildMeta ? !module.buildMeta.async : true);
820
821
 
821
- if (this.compilation.options.experiments.deferImport && defer) {
822
- const seen = new Set();
823
- (function gatherInnerAsyncDependencies(mod) {
824
- if (!moduleGraph.isAsync(mod) || seen.has(mod)) return;
825
- seen.add(mod);
826
- if (mod.buildMeta && mod.buildMeta.async) {
827
- innerAsyncDependencies.add(mod);
828
- } else {
829
- for (const dep of mod.dependencies) {
830
- const module = moduleGraph.getModule(dep);
831
- if (module) {
832
- gatherInnerAsyncDependencies(module);
833
- }
834
- }
835
- }
836
- })(module);
837
- }
822
+ /** @type {Set<Module>} */
823
+ const outgoingAsyncModules = defer
824
+ ? getOutgoingAsyncModules(moduleGraph, module)
825
+ : new Set();
838
826
 
839
827
  if (chunkGraph.getModuleId(module) === null) {
840
828
  if (weak) {
@@ -877,13 +865,14 @@ class RuntimeTemplate {
877
865
  this,
878
866
  exportsType,
879
867
  moduleId,
880
- Array.from(innerAsyncDependencies, mod => chunkGraph.getModuleId(mod))
868
+ Array.from(outgoingAsyncModules, mod => chunkGraph.getModuleId(mod))
881
869
  )};\n`;
882
- } else {
883
- importContent = `/* harmony import */ ${optDeclaration}${importVar} = ${RuntimeGlobals.require}(${moduleId});\n`;
870
+
871
+ return [importContent, ""];
884
872
  }
873
+ importContent = `/* harmony import */ ${optDeclaration}${importVar} = ${RuntimeGlobals.require}(${moduleId});\n`;
885
874
 
886
- if (exportsType === "dynamic" && !defer) {
875
+ if (exportsType === "dynamic") {
887
876
  runtimeRequirements.add(RuntimeGlobals.compatGetDefaultExport);
888
877
  return [
889
878
  importContent,
@@ -438,6 +438,13 @@ class WebpackOptionsApply extends OptionsApply {
438
438
  new HttpUriPlugin(httpOptions).apply(compiler);
439
439
  }
440
440
 
441
+ if (options.experiments.deferImport) {
442
+ const JavascriptParser = require("./javascript/JavascriptParser");
443
+ const importPhases = require("acorn-import-phases");
444
+
445
+ JavascriptParser.extend(importPhases({ source: false }));
446
+ }
447
+
441
448
  new EntryOptionPlugin().apply(compiler);
442
449
  compiler.hooks.entryOption.call(
443
450
  /** @type {string} */
@@ -57,8 +57,8 @@ const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
57
57
  /**
58
58
  * @template T
59
59
  * @template U
60
- * @param {string | Array<T> | Set<T> | undefined} a a
61
- * @param {string | Array<U> | Set<U> | undefined} b b
60
+ * @param {null | string | Array<T> | Set<T> | undefined} a a
61
+ * @param {null | string | Array<U> | Set<U> | undefined} b b
62
62
  * @returns {Array<T> & Array<U>} array
63
63
  */
64
64
  const mergeMaybeArrays = (a, b) => {
@@ -0,0 +1,50 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Haijie Xie @hai-x
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
9
+
10
+ /** @typedef {import("../ModuleGraph")} ModuleGraph */
11
+ /** @typedef {import("../Module")} Module */
12
+
13
+ /**
14
+ * @param {ModuleGraph} moduleGraph module graph
15
+ * @param {Module} module module
16
+ * @returns {Set<Module>} set of modules
17
+ */
18
+ const getOutgoingAsyncModules = (moduleGraph, module) => {
19
+ /** @type {Set<Module>} */
20
+ const set = new Set();
21
+ /** @type {Set<Module>} */
22
+ const seen = new Set();
23
+ (function g(/** @type {Module} */ module) {
24
+ if (!moduleGraph.isAsync(module) || seen.has(module)) return;
25
+ seen.add(module);
26
+ if (module.buildMeta && module.buildMeta.async) {
27
+ set.add(module);
28
+ } else {
29
+ const outgoingConnectionMap =
30
+ moduleGraph.getOutgoingConnectionsByModule(module);
31
+ if (outgoingConnectionMap) {
32
+ for (const [module, connections] of outgoingConnectionMap) {
33
+ if (
34
+ connections.some(
35
+ c =>
36
+ c.dependency instanceof HarmonyImportDependency &&
37
+ c.isTargetActive(undefined)
38
+ ) &&
39
+ module
40
+ ) {
41
+ g(module);
42
+ }
43
+ }
44
+ }
45
+ }
46
+ })(module);
47
+ return set;
48
+ };
49
+
50
+ module.exports.getOutgoingAsyncModules = getOutgoingAsyncModules;
@@ -77,12 +77,7 @@ module.exports = class HarmonyExportDependencyParserPlugin {
77
77
  clearDep.loc = /** @type {DependencyLocation} */ (statement.loc);
78
78
  clearDep.loc.index = -1;
79
79
  parser.state.module.addPresentationalDependency(clearDep);
80
- const { defer } = getImportMode(
81
- parser,
82
- statement,
83
- this.deferImport,
84
- true
85
- );
80
+ const { defer } = getImportMode(parser, statement);
86
81
  if (defer) {
87
82
  const error = new WebpackError(
88
83
  "Deferred re-export (`export defer * as namespace from '...'`) is not a part of the Import Defer proposal.\nUse the following code instead:\n import defer * as namespace from '...';\n export { namespace };"
@@ -207,12 +202,7 @@ module.exports = class HarmonyExportDependencyParserPlugin {
207
202
  parser.state.harmonyStarExports || new HarmonyStarExportsList();
208
203
  }
209
204
  const attributes = getImportAttributes(statement);
210
- const { defer } = getImportMode(
211
- parser,
212
- statement,
213
- this.deferImport,
214
- false
215
- );
205
+ const { defer } = getImportMode(parser, statement);
216
206
  const dep = new HarmonyExportImportedSpecifierDependency(
217
207
  /** @type {string} */
218
208
  (source),
@@ -7,7 +7,6 @@
7
7
 
8
8
  const CommentCompilationWarning = require("../CommentCompilationWarning");
9
9
  const HotModuleReplacementPlugin = require("../HotModuleReplacementPlugin");
10
- const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
11
10
  const WebpackError = require("../WebpackError");
12
11
  const { getImportAttributes } = require("../javascript/JavascriptParser");
13
12
  const InnerGraph = require("../optimize/InnerGraph");
@@ -125,12 +124,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
125
124
  parser.state.module.addPresentationalDependency(clearDep);
126
125
  parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]);
127
126
  const attributes = getImportAttributes(statement);
128
- const { defer } = getImportMode(
129
- parser,
130
- statement,
131
- this.deferImport,
132
- true
133
- );
127
+ const { defer } = getImportMode(parser, statement);
134
128
  if (
135
129
  defer &&
136
130
  (statement.specifiers.length !== 1 ||
@@ -156,12 +150,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
156
150
  PLUGIN_NAME,
157
151
  (statement, source, id, name) => {
158
152
  const ids = id === null ? [] : [id];
159
- const { defer } = getImportMode(
160
- parser,
161
- statement,
162
- this.deferImport,
163
- false
164
- );
153
+ const { defer } = getImportMode(parser, statement);
165
154
  parser.tagVariable(name, harmonySpecifierTag, {
166
155
  name,
167
156
  source,
@@ -398,23 +387,10 @@ module.exports = class HarmonyImportDependencyParserPlugin {
398
387
  /**
399
388
  * @param {JavascriptParser} parser parser
400
389
  * @param {ExportNamedDeclaration | ExportAllDeclaration | ImportDeclaration} node node
401
- * @param {boolean | undefined} deferImportEnabled defer import enabled
402
- * @param {boolean} reportSyntaxError report syntax error
403
390
  * @returns {{defer: boolean}} import attributes
404
391
  */
405
- function getImportMode(parser, node, deferImportEnabled, reportSyntaxError) {
406
- const result = { defer: false };
407
- if ("phase" in node && node.phase === "defer") {
408
- if (deferImportEnabled) {
409
- result.defer = true;
410
- } else if (reportSyntaxError) {
411
- const error = new WebpackError(
412
- "Deferred import syntax (`import defer * as namespace from '...'`) cannot be used unless experimental.deferImport is true."
413
- );
414
- error.loc = node.loc || undefined;
415
- parser.state.current.addError(error);
416
- }
417
- }
392
+ function getImportMode(parser, node) {
393
+ const result = { defer: "phase" in node && node.phase === "defer" };
418
394
  if (!node.range) {
419
395
  return result;
420
396
  }
@@ -437,7 +413,7 @@ function getImportMode(parser, node, deferImportEnabled, reportSyntaxError) {
437
413
  result.defer = options.webpackDefer;
438
414
  } else if (node.loc) {
439
415
  parser.state.module.addWarning(
440
- new UnsupportedFeatureWarning(
416
+ new CommentCompilationWarning(
441
417
  "webpackDefer magic comment expected a boolean value.",
442
418
  node.loc
443
419
  )
@@ -7,7 +7,6 @@
7
7
 
8
8
  const vm = require("vm");
9
9
  const { Parser: AcornParser, tokTypes } = require("acorn");
10
- const acornImportPhases = require("acorn-import-phases");
11
10
  const { HookMap, SyncBailHook } = require("tapable");
12
11
  const Parser = require("../Parser");
13
12
  const StackedMap = require("../util/StackedMap");
@@ -182,10 +181,7 @@ const importAssertions = Parser =>
182
181
  };
183
182
 
184
183
  // Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
185
- const parser = AcornParser.extend(
186
- importAssertions,
187
- acornImportPhases({ source: false })
188
- );
184
+ let parser = AcornParser.extend(importAssertions);
189
185
 
190
186
  /** @typedef {Record<string, string> & { _isLegacyAssert?: boolean }} ImportAttributes */
191
187
 
@@ -5135,6 +5131,15 @@ class JavascriptParser extends Parser {
5135
5131
 
5136
5132
  return /** @type {Program} */ (ast);
5137
5133
  }
5134
+
5135
+ /**
5136
+ * @param {((BaseParser: typeof AcornParser) => typeof AcornParser)[]} plugins parser plugin
5137
+ * @returns {typeof JavascriptParser} parser
5138
+ */
5139
+ static extend(...plugins) {
5140
+ parser = parser.extend(...plugins);
5141
+ return JavascriptParser;
5142
+ }
5138
5143
  }
5139
5144
 
5140
5145
  module.exports = JavascriptParser;
@@ -320,8 +320,17 @@ class SideEffectsFlagPlugin {
320
320
  ({ module }) =>
321
321
  module.getSideEffectsConnectionState(moduleGraph) ===
322
322
  false,
323
- ({ module: newModule, export: exportName }) => {
323
+ ({
324
+ module: newModule,
325
+ export: exportName,
326
+ connection: targetConnection
327
+ }) => {
324
328
  moduleGraph.updateModule(dep, newModule);
329
+ moduleGraph.updateParent(
330
+ dep,
331
+ targetConnection,
332
+ /** @type {Module} */ (connection.originModule)
333
+ );
325
334
  moduleGraph.addExplanation(
326
335
  dep,
327
336
  "(skipped side-effect-free modules)"
@@ -353,6 +362,13 @@ class SideEffectsFlagPlugin {
353
362
  if (!target) continue;
354
363
 
355
364
  moduleGraph.updateModule(dep, target.module);
365
+ moduleGraph.updateParent(
366
+ dep,
367
+ /** @type {ModuleGraphConnection} */ (
368
+ target.connection
369
+ ),
370
+ /** @type {Module} */ (connection.originModule)
371
+ );
356
372
  moduleGraph.addExplanation(
357
373
  dep,
358
374
  "(skipped side-effect-free modules)"
@@ -796,6 +796,7 @@ const SIMPLE_EXTRACTORS = {
796
796
  ? relatedEntry
797
797
  : [relatedEntry];
798
798
  for (const dep of deps) {
799
+ if (!dep) continue;
799
800
  const depItem = assetMap.get(dep);
800
801
  if (!depItem) continue;
801
802
  assets.delete(depItem);
@@ -13,9 +13,18 @@ const { compareRuntime } = require("./runtime");
13
13
  /** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
14
14
  /** @typedef {import("../ChunkGroup")} ChunkGroup */
15
15
  /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
16
+ /** @typedef {import("../Dependency")} Dependency */
17
+ /** @typedef {import("../dependencies/HarmonyImportSideEffectDependency")} HarmonyImportSideEffectDependency */
18
+ /** @typedef {import("../dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */
16
19
  /** @typedef {import("../Module")} Module */
17
20
  /** @typedef {import("../ModuleGraph")} ModuleGraph */
18
21
 
22
+ /**
23
+ * @typedef {object} DependencySourceOrder
24
+ * @property {number} main the main source order
25
+ * @property {number} sub the sub source order
26
+ */
27
+
19
28
  /**
20
29
  * @template T
21
30
  * @typedef {(a: T, b: T) => -1 | 0 | 1} Comparator
@@ -497,6 +506,95 @@ const compareChunksNatural = chunkGraph => {
497
506
  );
498
507
  };
499
508
 
509
+ /**
510
+ * For HarmonyImportSideEffectDependency and HarmonyImportSpecifierDependency, we should prioritize import order to match the behavior of running modules directly in a JS engine without a bundler.
511
+ * For other types like ConstDependency, we can instead prioritize usage order.
512
+ * https://github.com/webpack/webpack/pull/19686
513
+ * @param {Dependency[]} dependencies dependencies
514
+ * @param {WeakMap<Dependency, DependencySourceOrder>} dependencySourceOrderMap dependency source order map
515
+ * @returns {void}
516
+ */
517
+ const sortWithSourceOrder = (dependencies, dependencySourceOrderMap) => {
518
+ /**
519
+ * @param {Dependency} dep dependency
520
+ * @returns {number} source order
521
+ */
522
+ const getSourceOrder = dep => {
523
+ if (dependencySourceOrderMap.has(dep)) {
524
+ const { main } = /** @type {DependencySourceOrder} */ (
525
+ dependencySourceOrderMap.get(dep)
526
+ );
527
+ return main;
528
+ }
529
+ return /** @type { HarmonyImportSideEffectDependency | HarmonyImportSpecifierDependency} */ (
530
+ dep
531
+ ).sourceOrder;
532
+ };
533
+
534
+ /**
535
+ * If the sourceOrder is a number, it means the dependency needs to be sorted.
536
+ * @param {number | undefined} sourceOrder sourceOrder
537
+ * @returns {boolean} needReSort
538
+ */
539
+ const needReSort = sourceOrder => {
540
+ if (typeof sourceOrder === "number") {
541
+ return true;
542
+ }
543
+ return false;
544
+ };
545
+
546
+ // Extract dependencies with sourceOrder and sort them
547
+ const withSourceOrder = [];
548
+
549
+ // First pass: collect dependencies with sourceOrder
550
+ for (let i = 0; i < dependencies.length; i++) {
551
+ const dep = dependencies[i];
552
+ const sourceOrder = getSourceOrder(dep);
553
+
554
+ if (needReSort(sourceOrder)) {
555
+ withSourceOrder.push({ dep, sourceOrder, originalIndex: i });
556
+ }
557
+ }
558
+
559
+ if (withSourceOrder.length <= 1) {
560
+ return;
561
+ }
562
+
563
+ // Sort dependencies with sourceOrder
564
+ withSourceOrder.sort((a, b) => {
565
+ // Handle both dependencies in map case
566
+ if (
567
+ dependencySourceOrderMap.has(a.dep) &&
568
+ dependencySourceOrderMap.has(b.dep)
569
+ ) {
570
+ const { main: mainA, sub: subA } = /** @type {DependencySourceOrder} */ (
571
+ dependencySourceOrderMap.get(a.dep)
572
+ );
573
+ const { main: mainB, sub: subB } = /** @type {DependencySourceOrder} */ (
574
+ dependencySourceOrderMap.get(b.dep)
575
+ );
576
+ if (mainA === mainB) {
577
+ return compareNumbers(subA, subB);
578
+ }
579
+ return compareNumbers(mainA, mainB);
580
+ }
581
+
582
+ return compareNumbers(a.sourceOrder, b.sourceOrder);
583
+ });
584
+
585
+ // Second pass: build result array
586
+ let sortedIndex = 0;
587
+ for (let i = 0; i < dependencies.length; i++) {
588
+ const dep = dependencies[i];
589
+ const sourceOrder = getSourceOrder(dep);
590
+
591
+ if (needReSort(sourceOrder)) {
592
+ dependencies[i] = withSourceOrder[sortedIndex].dep;
593
+ sortedIndex++;
594
+ }
595
+ }
596
+ };
597
+
500
598
  module.exports.compareChunkGroupsByIndex = compareChunkGroupsByIndex;
501
599
  /** @type {ParameterizedComparator<ChunkGraph, Chunk>} */
502
600
  module.exports.compareChunks =
@@ -548,3 +646,4 @@ module.exports.compareStringsNumeric = compareStringsNumeric;
548
646
  module.exports.concatComparators = concatComparators;
549
647
 
550
648
  module.exports.keepOriginalOrder = keepOriginalOrder;
649
+ module.exports.sortWithSourceOrder = sortWithSourceOrder;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "5.100.1",
3
+ "version": "5.100.2",
4
4
  "description": "Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
5
5
  "homepage": "https://github.com/webpack/webpack",
6
6
  "bugs": "https://github.com/webpack/webpack/issues",
@@ -112,7 +112,7 @@
112
112
  "@babel/preset-react": "^7.27.1",
113
113
  "@codspeed/tinybench-plugin": "^4.0.1",
114
114
  "@eslint/js": "^9.29.0",
115
- "@eslint/markdown": "^6.6.0",
115
+ "@eslint/markdown": "^7.0.0",
116
116
  "@stylistic/eslint-plugin": "^5.0.0",
117
117
  "@types/glob-to-regexp": "^0.4.4",
118
118
  "@types/graceful-fs": "^4.1.9",
package/types.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  * Run `yarn fix:special` to update
5
5
  */
6
6
 
7
+ import { Parser as ParserImport } from "acorn";
7
8
  import { Buffer } from "buffer";
8
9
  import { Scope } from "eslint-scope";
9
10
  import {
@@ -3719,6 +3720,17 @@ declare interface DependencyConstructor {
3719
3720
  new (...args: any[]): Dependency;
3720
3721
  }
3721
3722
  type DependencyLocation = SyntheticDependencyLocation | RealDependencyLocation;
3723
+ declare interface DependencySourceOrder {
3724
+ /**
3725
+ * the main source order
3726
+ */
3727
+ main: number;
3728
+
3729
+ /**
3730
+ * the sub source order
3731
+ */
3732
+ sub: number;
3733
+ }
3722
3734
  declare class DependencyTemplate {
3723
3735
  constructor();
3724
3736
  apply(
@@ -6431,7 +6443,7 @@ declare class JavascriptModulesPlugin {
6431
6443
  ): TemplatePath;
6432
6444
  static chunkHasJs: (chunk: Chunk, chunkGraph: ChunkGraph) => boolean;
6433
6445
  }
6434
- declare class JavascriptParser extends Parser {
6446
+ declare class JavascriptParser extends ParserClass {
6435
6447
  constructor(sourceType?: "module" | "auto" | "script");
6436
6448
  hooks: Readonly<{
6437
6449
  evaluateTypeof: HookMap<
@@ -7759,6 +7771,9 @@ declare class JavascriptParser extends Parser {
7759
7771
  rootInfo: ExportedVariableInfo;
7760
7772
  getMembers: () => string[];
7761
7773
  };
7774
+ static extend(
7775
+ ...plugins: ((BaseParser: typeof ParserImport) => typeof ParserImport)[]
7776
+ ): typeof JavascriptParser;
7762
7777
  static ALLOWED_MEMBER_TYPES_ALL: 3;
7763
7778
  static ALLOWED_MEMBER_TYPES_CALL_EXPRESSION: 1;
7764
7779
  static ALLOWED_MEMBER_TYPES_EXPRESSION: 2;
@@ -8145,7 +8160,7 @@ declare interface KnownAssetInfo {
8145
8160
  /**
8146
8161
  * object of pointers to other assets, keyed by type of relation (only points from parent to child)
8147
8162
  */
8148
- related?: Record<string, string | string[]>;
8163
+ related?: Record<string, null | string | string[]>;
8149
8164
  }
8150
8165
  declare interface KnownBuildInfo {
8151
8166
  cacheable?: boolean;
@@ -9874,6 +9889,7 @@ declare class ModuleGraph {
9874
9889
  module: Module,
9875
9890
  indexInBlock?: number
9876
9891
  ): void;
9892
+ setParentDependenciesBlockIndex(dependency: Dependency, index: number): void;
9877
9893
  getParentModule(dependency: Dependency): undefined | Module;
9878
9894
  getParentBlock(dependency: Dependency): undefined | DependenciesBlock;
9879
9895
  getParentBlockIndex(dependency: Dependency): number;
@@ -9883,6 +9899,11 @@ declare class ModuleGraph {
9883
9899
  module: Module
9884
9900
  ): void;
9885
9901
  updateModule(dependency: Dependency, module: Module): void;
9902
+ updateParent(
9903
+ dependency: Dependency,
9904
+ connection?: ModuleGraphConnection,
9905
+ parentModule?: Module
9906
+ ): void;
9886
9907
  removeConnection(dependency: Dependency): void;
9887
9908
  addExplanation(dependency: Dependency, explanation: string): void;
9888
9909
  cloneModuleAttributes(sourceModule: Module, targetModule: Module): void;
@@ -10549,7 +10570,7 @@ declare class NormalModule extends Module {
10549
10570
  userRequest: string;
10550
10571
  rawRequest: string;
10551
10572
  binary: boolean;
10552
- parser?: Parser;
10573
+ parser?: ParserClass;
10553
10574
  parserOptions?: ParserOptions;
10554
10575
  generator?: Generator;
10555
10576
  generatorOptions?: GeneratorOptions;
@@ -10680,7 +10701,7 @@ declare interface NormalModuleCreateData {
10680
10701
  /**
10681
10702
  * the parser used
10682
10703
  */
10683
- parser: Parser;
10704
+ parser: ParserClass;
10684
10705
 
10685
10706
  /**
10686
10707
  * the options of the parser used
@@ -10728,7 +10749,7 @@ declare abstract class NormalModuleFactory extends ModuleFactory {
10728
10749
  ResolveData
10729
10750
  ]
10730
10751
  >;
10731
- createParser: HookMap<SyncBailHook<[ParserOptions], void | Parser>>;
10752
+ createParser: HookMap<SyncBailHook<[ParserOptions], void | ParserClass>>;
10732
10753
  parser: HookMap<SyncBailHook<[any, ParserOptions], void>>;
10733
10754
  createGenerator: HookMap<
10734
10755
  SyncBailHook<[GeneratorOptions], void | Generator>
@@ -10748,7 +10769,7 @@ declare abstract class NormalModuleFactory extends ModuleFactory {
10748
10769
  ruleSet: RuleSet;
10749
10770
  context: string;
10750
10771
  fs: InputFileSystem;
10751
- parserCache: Map<string, WeakMap<ParserOptions, Parser>>;
10772
+ parserCache: Map<string, WeakMap<ParserOptions, ParserClass>>;
10752
10773
  generatorCache: Map<string, WeakMap<GeneratorOptions, Generator>>;
10753
10774
  cleanupForCache(): void;
10754
10775
  resolveResource(
@@ -10771,8 +10792,8 @@ declare abstract class NormalModuleFactory extends ModuleFactory {
10771
10792
  resolveContext: ResolveContext,
10772
10793
  callback: CallbackNormalModuleFactory<LoaderItem[]>
10773
10794
  ): void;
10774
- getParser(type: string, parserOptions?: ParserOptions): Parser;
10775
- createParser(type: string, parserOptions?: ParserOptions): Parser;
10795
+ getParser(type: string, parserOptions?: ParserOptions): ParserClass;
10796
+ createParser(type: string, parserOptions?: ParserOptions): ParserClass;
10776
10797
  getGenerator(type: string, generatorOptions?: GeneratorOptions): Generator;
10777
10798
  createGenerator(type: string, generatorOptions?: GeneratorOptions): Generator;
10778
10799
  getResolver(
@@ -12238,7 +12259,7 @@ declare interface ParsedIdentifier {
12238
12259
  */
12239
12260
  internal: boolean;
12240
12261
  }
12241
- declare class Parser {
12262
+ declare class ParserClass {
12242
12263
  constructor();
12243
12264
  parse(
12244
12265
  source: string | Buffer | PreparsedAst,
@@ -17791,6 +17812,10 @@ declare namespace exports {
17791
17812
  ...cRest: Comparator<T>[]
17792
17813
  ) => Comparator<T>;
17793
17814
  export let keepOriginalOrder: <T>(iterable: Iterable<T>) => Comparator<T>;
17815
+ export let sortWithSourceOrder: (
17816
+ dependencies: Dependency[],
17817
+ dependencySourceOrderMap: WeakMap<Dependency, DependencySourceOrder>
17818
+ ) => void;
17794
17819
  }
17795
17820
  export namespace runtime {
17796
17821
  export let compareRuntime: (a: RuntimeSpec, b: RuntimeSpec) => 0 | 1 | -1;
@@ -18025,7 +18050,7 @@ declare namespace exports {
18025
18050
  NormalModule,
18026
18051
  NormalModuleReplacementPlugin,
18027
18052
  MultiCompiler,
18028
- Parser,
18053
+ ParserClass as Parser,
18029
18054
  PlatformPlugin,
18030
18055
  PrefetchPlugin,
18031
18056
  ProgressPlugin,