webpack 5.94.0 → 5.96.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 (151) hide show
  1. package/README.md +1 -1
  2. package/lib/AsyncDependenciesBlock.js +1 -1
  3. package/lib/BannerPlugin.js +2 -1
  4. package/lib/Chunk.js +30 -0
  5. package/lib/ChunkGraph.js +11 -6
  6. package/lib/ChunkGroup.js +2 -2
  7. package/lib/CleanPlugin.js +4 -5
  8. package/lib/CodeGenerationResults.js +6 -5
  9. package/lib/Compilation.js +71 -48
  10. package/lib/Compiler.js +7 -5
  11. package/lib/ConcatenationScope.js +7 -20
  12. package/lib/ContextModule.js +7 -8
  13. package/lib/CssModule.js +25 -21
  14. package/lib/DefinePlugin.js +14 -8
  15. package/lib/DelegatedModule.js +3 -3
  16. package/lib/DllModule.js +4 -4
  17. package/lib/DynamicEntryPlugin.js +29 -22
  18. package/lib/EnvironmentPlugin.js +3 -2
  19. package/lib/EvalDevToolModulePlugin.js +5 -2
  20. package/lib/EvalSourceMapDevToolPlugin.js +5 -2
  21. package/lib/ExternalModule.js +118 -99
  22. package/lib/ExternalModuleFactoryPlugin.js +33 -9
  23. package/lib/FileSystemInfo.js +12 -8
  24. package/lib/Generator.js +5 -4
  25. package/lib/HotModuleReplacementPlugin.js +8 -6
  26. package/lib/IgnorePlugin.js +19 -1
  27. package/lib/LoaderOptionsPlugin.js +3 -1
  28. package/lib/Module.js +9 -8
  29. package/lib/ModuleSourceTypesConstants.js +100 -0
  30. package/lib/NormalModule.js +27 -13
  31. package/lib/NormalModuleFactory.js +38 -22
  32. package/lib/OptionsApply.js +12 -1
  33. package/lib/ProgressPlugin.js +50 -10
  34. package/lib/RawModule.js +3 -4
  35. package/lib/RuntimeModule.js +3 -4
  36. package/lib/RuntimePlugin.js +11 -4
  37. package/lib/RuntimeTemplate.js +13 -42
  38. package/lib/SourceMapDevToolPlugin.js +10 -7
  39. package/lib/TemplatedPathPlugin.js +9 -3
  40. package/lib/Watching.js +2 -2
  41. package/lib/WebpackOptionsApply.js +42 -21
  42. package/lib/asset/AssetGenerator.js +347 -194
  43. package/lib/asset/AssetModulesPlugin.js +2 -1
  44. package/lib/asset/AssetSourceGenerator.js +82 -27
  45. package/lib/asset/RawDataUrlModule.js +5 -4
  46. package/lib/buildChunkGraph.js +79 -62
  47. package/lib/cache/PackFileCacheStrategy.js +69 -31
  48. package/lib/cache/ResolverCachePlugin.js +248 -173
  49. package/lib/config/defaults.js +135 -126
  50. package/lib/container/ContainerEntryModule.js +3 -4
  51. package/lib/container/ContainerPlugin.js +8 -0
  52. package/lib/container/FallbackModule.js +2 -2
  53. package/lib/container/HoistContainerReferencesPlugin.js +250 -0
  54. package/lib/container/ModuleFederationPlugin.js +38 -1
  55. package/lib/container/RemoteModule.js +4 -2
  56. package/lib/container/RemoteRuntimeModule.js +4 -2
  57. package/lib/css/CssExportsGenerator.js +16 -12
  58. package/lib/css/CssGenerator.js +22 -16
  59. package/lib/css/CssLoadingRuntimeModule.js +7 -6
  60. package/lib/css/CssModulesPlugin.js +122 -77
  61. package/lib/css/CssParser.js +655 -526
  62. package/lib/css/walkCssTokens.js +1168 -338
  63. package/lib/debug/ProfilingPlugin.js +5 -0
  64. package/lib/dependencies/CommonJsExportsParserPlugin.js +5 -2
  65. package/lib/dependencies/CommonJsImportsParserPlugin.js +3 -6
  66. package/lib/dependencies/ContextDependency.js +6 -1
  67. package/lib/dependencies/ContextElementDependency.js +33 -6
  68. package/lib/dependencies/CssExportDependency.js +3 -3
  69. package/lib/dependencies/CssLocalIdentifierDependency.js +26 -17
  70. package/lib/dependencies/CssUrlDependency.js +33 -3
  71. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +3 -3
  72. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +39 -14
  73. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +15 -82
  74. package/lib/dependencies/HarmonyImportSpecifierDependency.js +5 -2
  75. package/lib/dependencies/ImportParserPlugin.js +9 -7
  76. package/lib/dependencies/LoaderPlugin.js +19 -0
  77. package/lib/dependencies/SystemPlugin.js +2 -1
  78. package/lib/dependencies/URLPlugin.js +7 -1
  79. package/lib/dependencies/WorkerPlugin.js +1 -1
  80. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +4 -2
  81. package/lib/hmr/HotModuleReplacement.runtime.js +1 -0
  82. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +1 -0
  83. package/lib/hmr/LazyCompilationPlugin.js +16 -4
  84. package/lib/hmr/lazyCompilationBackend.js +1 -7
  85. package/lib/index.js +35 -6
  86. package/lib/javascript/EnableChunkLoadingPlugin.js +2 -2
  87. package/lib/javascript/JavascriptGenerator.js +8 -8
  88. package/lib/javascript/JavascriptModulesPlugin.js +166 -88
  89. package/lib/javascript/JavascriptParser.js +338 -117
  90. package/lib/json/JsonGenerator.js +5 -5
  91. package/lib/library/EnableLibraryPlugin.js +2 -2
  92. package/lib/library/ExportPropertyLibraryPlugin.js +1 -1
  93. package/lib/library/UmdLibraryPlugin.js +16 -8
  94. package/lib/logging/Logger.js +11 -11
  95. package/lib/logging/createConsoleLogger.js +14 -14
  96. package/lib/logging/truncateArgs.js +1 -1
  97. package/lib/node/NodeWatchFileSystem.js +3 -1
  98. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +20 -18
  99. package/lib/node/ReadFileCompileWasmPlugin.js +1 -2
  100. package/lib/node/nodeConsole.js +11 -8
  101. package/lib/optimize/AggressiveSplittingPlugin.js +21 -7
  102. package/lib/optimize/ConcatenatedModule.js +44 -148
  103. package/lib/optimize/FlagIncludedChunksPlugin.js +6 -0
  104. package/lib/optimize/InnerGraphPlugin.js +57 -16
  105. package/lib/optimize/LimitChunkCountPlugin.js +2 -4
  106. package/lib/optimize/MergeDuplicateChunksPlugin.js +2 -2
  107. package/lib/optimize/ModuleConcatenationPlugin.js +4 -2
  108. package/lib/optimize/RealContentHashPlugin.js +1 -1
  109. package/lib/optimize/SideEffectsFlagPlugin.js +6 -3
  110. package/lib/rules/RuleSetCompiler.js +2 -2
  111. package/lib/runtime/GetChunkFilenameRuntimeModule.js +2 -2
  112. package/lib/schemes/DataUriPlugin.js +1 -1
  113. package/lib/serialization/BinaryMiddleware.js +32 -19
  114. package/lib/serialization/ObjectMiddleware.js +23 -9
  115. package/lib/serialization/SerializerMiddleware.js +3 -2
  116. package/lib/serialization/types.js +2 -2
  117. package/lib/sharing/ConsumeSharedModule.js +2 -3
  118. package/lib/sharing/ConsumeSharedRuntimeModule.js +3 -1
  119. package/lib/sharing/ProvideSharedModule.js +2 -3
  120. package/lib/stats/DefaultStatsFactoryPlugin.js +22 -20
  121. package/lib/stats/StatsFactory.js +12 -12
  122. package/lib/stats/StatsPrinter.js +7 -7
  123. package/lib/util/AsyncQueue.js +17 -1
  124. package/lib/util/IterableHelpers.js +1 -1
  125. package/lib/util/LazySet.js +12 -0
  126. package/lib/util/SetHelpers.js +1 -1
  127. package/lib/util/cleverMerge.js +48 -24
  128. package/lib/util/concatenate.js +227 -0
  129. package/lib/util/create-schema-validation.js +22 -9
  130. package/lib/util/deprecation.js +86 -28
  131. package/lib/util/fs.js +10 -10
  132. package/lib/util/hash/wasm-hash.js +12 -1
  133. package/lib/util/magicComment.js +21 -0
  134. package/lib/util/makeSerializable.js +24 -1
  135. package/lib/util/memoize.js +2 -1
  136. package/lib/util/runtime.js +10 -1
  137. package/lib/util/semver.js +130 -23
  138. package/lib/wasm/EnableWasmLoadingPlugin.js +2 -2
  139. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +3 -3
  140. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +5 -5
  141. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +5 -5
  142. package/lib/wasm-sync/WebAssemblyGenerator.js +8 -9
  143. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +5 -5
  144. package/lib/web/FetchCompileAsyncWasmPlugin.js +1 -2
  145. package/lib/web/FetchCompileWasmPlugin.js +1 -2
  146. package/lib/web/JsonpChunkLoadingRuntimeModule.js +6 -6
  147. package/package.json +19 -20
  148. package/schemas/WebpackOptions.check.js +1 -1
  149. package/schemas/WebpackOptions.json +12 -2
  150. package/types.d.ts +817 -269
  151. package/lib/util/mergeScope.js +0 -76
@@ -8,50 +8,86 @@
8
8
  const { RawSource } = require("webpack-sources");
9
9
  const ConcatenationScope = require("../ConcatenationScope");
10
10
  const Generator = require("../Generator");
11
+ const {
12
+ NO_TYPES,
13
+ CSS_URL_TYPES,
14
+ JS_TYPES,
15
+ JS_AND_CSS_URL_TYPES
16
+ } = require("../ModuleSourceTypesConstants");
11
17
  const RuntimeGlobals = require("../RuntimeGlobals");
12
18
 
13
19
  /** @typedef {import("webpack-sources").Source} Source */
14
20
  /** @typedef {import("../Generator").GenerateContext} GenerateContext */
15
21
  /** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
22
+ /** @typedef {import("../Module").SourceTypes} SourceTypes */
23
+ /** @typedef {import("../ModuleGraph")} ModuleGraph */
16
24
  /** @typedef {import("../NormalModule")} NormalModule */
17
25
 
18
- const TYPES = new Set(["javascript"]);
19
-
20
26
  class AssetSourceGenerator extends Generator {
27
+ /**
28
+ * @param {ModuleGraph} moduleGraph the module graph
29
+ */
30
+ constructor(moduleGraph) {
31
+ super();
32
+
33
+ this._moduleGraph = moduleGraph;
34
+ }
35
+
21
36
  /**
22
37
  * @param {NormalModule} module module for which the code should be generated
23
38
  * @param {GenerateContext} generateContext context for generate
24
- * @returns {Source} generated code
39
+ * @returns {Source | null} generated code
25
40
  */
26
41
  generate(
27
42
  module,
28
- { concatenationScope, chunkGraph, runtimeTemplate, runtimeRequirements }
43
+ { type, concatenationScope, getData, runtimeTemplate, runtimeRequirements }
29
44
  ) {
30
45
  const originalSource = module.originalSource();
46
+ const data = getData ? getData() : undefined;
31
47
 
32
- if (!originalSource) {
33
- return new RawSource("");
34
- }
48
+ switch (type) {
49
+ case "javascript": {
50
+ if (!originalSource) {
51
+ return new RawSource("");
52
+ }
53
+
54
+ const content = originalSource.source();
55
+ const encodedSource =
56
+ typeof content === "string" ? content : content.toString("utf-8");
35
57
 
36
- const content = originalSource.source();
37
- const encodedSource =
38
- typeof content === "string" ? content : content.toString("utf-8");
39
-
40
- let sourceContent;
41
- if (concatenationScope) {
42
- concatenationScope.registerNamespaceExport(
43
- ConcatenationScope.NAMESPACE_OBJECT_EXPORT
44
- );
45
- sourceContent = `${runtimeTemplate.supportsConst() ? "const" : "var"} ${
46
- ConcatenationScope.NAMESPACE_OBJECT_EXPORT
47
- } = ${JSON.stringify(encodedSource)};`;
48
- } else {
49
- runtimeRequirements.add(RuntimeGlobals.module);
50
- sourceContent = `${RuntimeGlobals.module}.exports = ${JSON.stringify(
51
- encodedSource
52
- )};`;
58
+ let sourceContent;
59
+ if (concatenationScope) {
60
+ concatenationScope.registerNamespaceExport(
61
+ ConcatenationScope.NAMESPACE_OBJECT_EXPORT
62
+ );
63
+ sourceContent = `${runtimeTemplate.supportsConst() ? "const" : "var"} ${
64
+ ConcatenationScope.NAMESPACE_OBJECT_EXPORT
65
+ } = ${JSON.stringify(encodedSource)};`;
66
+ } else {
67
+ runtimeRequirements.add(RuntimeGlobals.module);
68
+ sourceContent = `${RuntimeGlobals.module}.exports = ${JSON.stringify(
69
+ encodedSource
70
+ )};`;
71
+ }
72
+ return new RawSource(sourceContent);
73
+ }
74
+ case "css-url": {
75
+ if (!originalSource) {
76
+ return null;
77
+ }
78
+
79
+ const content = originalSource.source();
80
+ const encodedSource =
81
+ typeof content === "string" ? content : content.toString("utf-8");
82
+
83
+ if (data) {
84
+ data.set("url", { [type]: encodedSource });
85
+ }
86
+ return null;
87
+ }
88
+ default:
89
+ return null;
53
90
  }
54
- return new RawSource(sourceContent);
55
91
  }
56
92
 
57
93
  /**
@@ -65,10 +101,29 @@ class AssetSourceGenerator extends Generator {
65
101
 
66
102
  /**
67
103
  * @param {NormalModule} module fresh module
68
- * @returns {Set<string>} available types (do not mutate)
104
+ * @returns {SourceTypes} available types (do not mutate)
69
105
  */
70
106
  getTypes(module) {
71
- return TYPES;
107
+ const sourceTypes = new Set();
108
+ const connections = this._moduleGraph.getIncomingConnections(module);
109
+
110
+ for (const connection of connections) {
111
+ if (!connection.originModule) {
112
+ continue;
113
+ }
114
+
115
+ sourceTypes.add(connection.originModule.type.split("/")[0]);
116
+ }
117
+
118
+ if (sourceTypes.has("javascript") && sourceTypes.has("css")) {
119
+ return JS_AND_CSS_URL_TYPES;
120
+ } else if (sourceTypes.has("javascript")) {
121
+ return JS_TYPES;
122
+ } else if (sourceTypes.has("css")) {
123
+ return CSS_URL_TYPES;
124
+ }
125
+
126
+ return NO_TYPES;
72
127
  }
73
128
 
74
129
  /**
@@ -7,6 +7,7 @@
7
7
 
8
8
  const { RawSource } = require("webpack-sources");
9
9
  const Module = require("../Module");
10
+ const { JS_TYPES } = require("../ModuleSourceTypesConstants");
10
11
  const { ASSET_MODULE_TYPE_RAW_DATA_URL } = require("../ModuleTypeConstants");
11
12
  const RuntimeGlobals = require("../RuntimeGlobals");
12
13
  const makeSerializable = require("../util/makeSerializable");
@@ -26,8 +27,6 @@ const makeSerializable = require("../util/makeSerializable");
26
27
  /** @typedef {import("../util/Hash")} Hash */
27
28
  /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
28
29
 
29
- const TYPES = new Set(["javascript"]);
30
-
31
30
  class RawDataUrlModule extends Module {
32
31
  /**
33
32
  * @param {string} url raw url
@@ -46,7 +45,7 @@ class RawDataUrlModule extends Module {
46
45
  * @returns {SourceTypes} types available (do not mutate)
47
46
  */
48
47
  getSourceTypes() {
49
- return TYPES;
48
+ return JS_TYPES;
50
49
  }
51
50
 
52
51
  /**
@@ -114,7 +113,9 @@ class RawDataUrlModule extends Module {
114
113
  new RawSource(`module.exports = ${JSON.stringify(this.url)};`)
115
114
  );
116
115
  const data = new Map();
117
- data.set("url", this.urlBuffer);
116
+ data.set("url", {
117
+ javascript: this.url
118
+ });
118
119
  const runtimeRequirements = new Set();
119
120
  runtimeRequirements.add(RuntimeGlobals.module);
120
121
  return { sources, runtimeRequirements, data };
@@ -38,6 +38,7 @@ const { getEntryRuntime, mergeRuntime } = require("./util/runtime");
38
38
  * @typedef {object} ChunkGroupInfo
39
39
  * @property {ChunkGroup} chunkGroup the chunk group
40
40
  * @property {RuntimeSpec} runtime the runtimes
41
+ * @property {boolean} initialized is this chunk group initialized
41
42
  * @property {bigint | undefined} minAvailableModules current minimal set of modules available at this point
42
43
  * @property {bigint[]} availableModulesToBeMerged enqueued updates to the minimal set of available modules
43
44
  * @property {Set<Module>=} skippedItems modules that were skipped because module is already available in parent chunks (need to reconsider when minAvailableModules is shrinking)
@@ -345,8 +346,8 @@ const visitModules = (
345
346
  /** @type {Map<DependenciesBlock, ChunkGroupInfo>} */
346
347
  const blockChunkGroups = new Map();
347
348
 
348
- /** @type {Map<ChunkGroupInfo, DependenciesBlock>} */
349
- const blockByChunkGroups = new Map();
349
+ /** @type {Map<ChunkGroupInfo, Set<DependenciesBlock>>} */
350
+ const blocksByChunkGroups = new Map();
350
351
 
351
352
  /** @type {Map<string, ChunkGroupInfo>} */
352
353
  const namedChunkGroups = new Map();
@@ -367,7 +368,7 @@ const visitModules = (
367
368
  /** @type {QueueItem[]} */
368
369
  let queue = [];
369
370
 
370
- /** @type {Map<ChunkGroupInfo, Set<ChunkGroupInfo>>} */
371
+ /** @type {Map<ChunkGroupInfo, Set<[ChunkGroupInfo, QueueItem | null]>>} */
371
372
  const queueConnect = new Map();
372
373
  /** @type {Set<ChunkGroupInfo>} */
373
374
  const chunkGroupsForCombining = new Set();
@@ -382,6 +383,7 @@ const visitModules = (
382
383
  );
383
384
  /** @type {ChunkGroupInfo} */
384
385
  const chunkGroupInfo = {
386
+ initialized: false,
385
387
  chunkGroup,
386
388
  runtime,
387
389
  minAvailableModules: undefined,
@@ -452,7 +454,7 @@ const visitModules = (
452
454
 
453
455
  /** @type {Set<ChunkGroupInfo>} */
454
456
  const outdatedChunkGroupInfo = new Set();
455
- /** @type {Set<ChunkGroupInfo>} */
457
+ /** @type {Set<[ChunkGroupInfo, QueueItem | null]>} */
456
458
  const chunkGroupsForMerging = new Set();
457
459
  /** @type {QueueItem[]} */
458
460
  let queueDelayed = [];
@@ -505,6 +507,7 @@ const visitModules = (
505
507
  entrypoint.index = nextChunkGroupIndex++;
506
508
  cgi = {
507
509
  chunkGroup: entrypoint,
510
+ initialized: false,
508
511
  runtime: entrypoint.options.runtime || entrypoint.name,
509
512
  minAvailableModules: ZERO_BIGINT,
510
513
  availableModulesToBeMerged: [],
@@ -572,6 +575,7 @@ const visitModules = (
572
575
  maskByChunk.set(c.chunks[0], ZERO_BIGINT);
573
576
  c.index = nextChunkGroupIndex++;
574
577
  cgi = {
578
+ initialized: false,
575
579
  chunkGroup: c,
576
580
  runtime: chunkGroupInfo.runtime,
577
581
  minAvailableModules: undefined,
@@ -614,7 +618,6 @@ const visitModules = (
614
618
  blockConnections.set(b, []);
615
619
  }
616
620
  blockChunkGroups.set(b, /** @type {ChunkGroupInfo} */ (cgi));
617
- blockByChunkGroups.set(/** @type {ChunkGroupInfo} */ (cgi), b);
618
621
  } else if (entryOptions) {
619
622
  entrypoint = /** @type {Entrypoint} */ (cgi.chunkGroup);
620
623
  } else {
@@ -636,19 +639,17 @@ const visitModules = (
636
639
  connectList = new Set();
637
640
  queueConnect.set(chunkGroupInfo, connectList);
638
641
  }
639
- connectList.add(/** @type {ChunkGroupInfo} */ (cgi));
640
-
641
- // TODO check if this really need to be done for each traversal
642
- // or if it is enough when it's queued when created
643
- // 4. We enqueue the DependenciesBlock for traversal
644
- queueDelayed.push({
645
- action: PROCESS_BLOCK,
646
- block: b,
647
- module,
648
- chunk: c.chunks[0],
649
- chunkGroup: c,
650
- chunkGroupInfo: /** @type {ChunkGroupInfo} */ (cgi)
651
- });
642
+ connectList.add([
643
+ /** @type {ChunkGroupInfo} */ (cgi),
644
+ {
645
+ action: PROCESS_BLOCK,
646
+ block: b,
647
+ module,
648
+ chunk: c.chunks[0],
649
+ chunkGroup: c,
650
+ chunkGroupInfo: /** @type {ChunkGroupInfo} */ (cgi)
651
+ }
652
+ ]);
652
653
  } else if (entrypoint !== undefined) {
653
654
  chunkGroupInfo.chunkGroup.addAsyncEntrypoint(entrypoint);
654
655
  }
@@ -901,11 +902,10 @@ const visitModules = (
901
902
  for (const [chunkGroupInfo, targets] of queueConnect) {
902
903
  // 1. Add new targets to the list of children
903
904
  if (chunkGroupInfo.children === undefined) {
904
- chunkGroupInfo.children = targets;
905
- } else {
906
- for (const target of targets) {
907
- chunkGroupInfo.children.add(target);
908
- }
905
+ chunkGroupInfo.children = new Set();
906
+ }
907
+ for (const [target] of targets) {
908
+ chunkGroupInfo.children.add(target);
909
909
  }
910
910
 
911
911
  // 2. Calculate resulting available modules
@@ -915,9 +915,9 @@ const visitModules = (
915
915
  const runtime = chunkGroupInfo.runtime;
916
916
 
917
917
  // 3. Update chunk group info
918
- for (const target of targets) {
918
+ for (const [target, processBlock] of targets) {
919
919
  target.availableModulesToBeMerged.push(resultingAvailableModules);
920
- chunkGroupsForMerging.add(target);
920
+ chunkGroupsForMerging.add([target, processBlock]);
921
921
  const oldRuntime = target.runtime;
922
922
  const newRuntime = mergeRuntime(oldRuntime, runtime);
923
923
  if (oldRuntime !== newRuntime) {
@@ -935,7 +935,7 @@ const visitModules = (
935
935
  statProcessedChunkGroupsForMerging += chunkGroupsForMerging.size;
936
936
 
937
937
  // Execute the merge
938
- for (const info of chunkGroupsForMerging) {
938
+ for (const [info, processBlock] of chunkGroupsForMerging) {
939
939
  const availableModulesToBeMerged = info.availableModulesToBeMerged;
940
940
  const cachedMinAvailableModules = info.minAvailableModules;
941
941
  let minAvailableModules = cachedMinAvailableModules;
@@ -958,6 +958,27 @@ const visitModules = (
958
958
  info.resultingAvailableModules = undefined;
959
959
  outdatedChunkGroupInfo.add(info);
960
960
  }
961
+
962
+ if (processBlock) {
963
+ let blocks = blocksByChunkGroups.get(info);
964
+ if (!blocks) {
965
+ blocksByChunkGroups.set(info, (blocks = new Set()));
966
+ }
967
+
968
+ // Whether to walk block depends on minAvailableModules and input block.
969
+ // We can treat creating chunk group as a function with 2 input, entry block and minAvailableModules
970
+ // If input is the same, we can skip re-walk
971
+ let needWalkBlock = !info.initialized || changed;
972
+ if (!blocks.has(processBlock.block)) {
973
+ needWalkBlock = true;
974
+ blocks.add(processBlock.block);
975
+ }
976
+
977
+ if (needWalkBlock) {
978
+ info.initialized = true;
979
+ queueDelayed.push(processBlock);
980
+ }
981
+ }
961
982
  }
962
983
  chunkGroupsForMerging.clear();
963
984
  };
@@ -1057,7 +1078,7 @@ const visitModules = (
1057
1078
  connectList = new Set();
1058
1079
  queueConnect.set(info, connectList);
1059
1080
  }
1060
- connectList.add(cgi);
1081
+ connectList.add([cgi, null]);
1061
1082
  }
1062
1083
  }
1063
1084
 
@@ -1117,48 +1138,44 @@ const visitModules = (
1117
1138
  for (const info of outdatedOrderIndexChunkGroups) {
1118
1139
  const { chunkGroup, runtime } = info;
1119
1140
 
1120
- const block = blockByChunkGroups.get(info);
1141
+ const blocks = blocksByChunkGroups.get(info);
1121
1142
 
1122
- if (!block) {
1143
+ if (!blocks) {
1123
1144
  continue;
1124
1145
  }
1125
1146
 
1126
- let preOrderIndex = 0;
1127
- let postOrderIndex = 0;
1128
-
1129
- /**
1130
- * @param {DependenciesBlock} current current
1131
- * @param {BlocksWithNestedBlocks} visited visited dependencies blocks
1132
- */
1133
- const process = (current, visited) => {
1134
- const blockModules = getBlockModules(current, runtime);
1135
- if (blockModules === undefined) {
1136
- return;
1137
- }
1138
-
1139
- for (let i = 0, len = blockModules.length; i < len; i += 3) {
1140
- const activeState = /** @type {ConnectionState} */ (
1141
- blockModules[i + 1]
1142
- );
1143
- if (activeState === false) {
1144
- continue;
1145
- }
1146
- const refModule = /** @type {Module} */ (blockModules[i]);
1147
- if (visited.has(refModule)) {
1148
- continue;
1149
- }
1147
+ for (const block of blocks) {
1148
+ let preOrderIndex = 0;
1149
+ let postOrderIndex = 0;
1150
+ /**
1151
+ * @param {DependenciesBlock} current current
1152
+ * @param {BlocksWithNestedBlocks} visited visited dependencies blocks
1153
+ */
1154
+ const process = (current, visited) => {
1155
+ const blockModules = getBlockModules(current, runtime);
1156
+ for (let i = 0, len = blockModules.length; i < len; i += 3) {
1157
+ const activeState = /** @type {ConnectionState} */ (
1158
+ blockModules[i + 1]
1159
+ );
1160
+ if (activeState === false) {
1161
+ continue;
1162
+ }
1163
+ const refModule = /** @type {Module} */ (blockModules[i]);
1164
+ if (visited.has(refModule)) {
1165
+ continue;
1166
+ }
1150
1167
 
1151
- visited.add(refModule);
1168
+ visited.add(refModule);
1152
1169
 
1153
- if (refModule) {
1154
- chunkGroup.setModulePreOrderIndex(refModule, preOrderIndex++);
1155
- process(refModule, visited);
1156
- chunkGroup.setModulePostOrderIndex(refModule, postOrderIndex++);
1170
+ if (refModule) {
1171
+ chunkGroup.setModulePreOrderIndex(refModule, preOrderIndex++);
1172
+ process(refModule, visited);
1173
+ chunkGroup.setModulePostOrderIndex(refModule, postOrderIndex++);
1174
+ }
1157
1175
  }
1158
- }
1159
- };
1160
-
1161
- process(block, new Set());
1176
+ };
1177
+ process(block, new Set());
1178
+ }
1162
1179
  }
1163
1180
  outdatedOrderIndexChunkGroups.clear();
1164
1181
  ordinalByModule.clear();