webpack 5.56.0 → 5.58.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.

Potentially problematic release.


This version of webpack might be problematic. Click here for more details.

@@ -29,7 +29,7 @@ const EMPTY_SET = new Set();
29
29
 
30
30
  /**
31
31
  * @param {SortableSet<ModuleGraphConnection>} set input
32
- * @returns {readonly Map<Module, readonly ModuleGraphConnection[]>} mapped by origin module
32
+ * @returns {readonly Map<Module | undefined, readonly ModuleGraphConnection[]>} mapped by origin module
33
33
  */
34
34
  const getConnectionsByOriginModule = set => {
35
35
  const map = new Map();
@@ -57,11 +57,41 @@ const getConnectionsByOriginModule = set => {
57
57
  return map;
58
58
  };
59
59
 
60
+ /**
61
+ * @param {SortableSet<ModuleGraphConnection>} set input
62
+ * @returns {readonly Map<Module | undefined, readonly ModuleGraphConnection[]>} mapped by module
63
+ */
64
+ const getConnectionsByModule = set => {
65
+ const map = new Map();
66
+ /** @type {Module | 0} */
67
+ let lastModule = 0;
68
+ /** @type {ModuleGraphConnection[]} */
69
+ let lastList = undefined;
70
+ for (const connection of set) {
71
+ const { module } = connection;
72
+ if (lastModule === module) {
73
+ lastList.push(connection);
74
+ } else {
75
+ lastModule = module;
76
+ const list = map.get(module);
77
+ if (list !== undefined) {
78
+ lastList = list;
79
+ list.push(connection);
80
+ } else {
81
+ const list = [connection];
82
+ lastList = list;
83
+ map.set(module, list);
84
+ }
85
+ }
86
+ }
87
+ return map;
88
+ };
89
+
60
90
  class ModuleGraphModule {
61
91
  constructor() {
62
92
  /** @type {SortableSet<ModuleGraphConnection>} */
63
93
  this.incomingConnections = new SortableSet();
64
- /** @type {Set<ModuleGraphConnection> | undefined} */
94
+ /** @type {SortableSet<ModuleGraphConnection> | undefined} */
65
95
  this.outgoingConnections = undefined;
66
96
  /** @type {Module | null} */
67
97
  this.issuer = undefined;
@@ -93,18 +123,10 @@ class ModuleGraph {
93
123
  /** @type {WeakMap<any, Object>} */
94
124
  this._metaMap = new WeakMap();
95
125
 
96
- // Caching
97
- this._cacheModuleGraphModuleKey1 = undefined;
98
- this._cacheModuleGraphModuleValue1 = undefined;
99
- this._cacheModuleGraphModuleKey2 = undefined;
100
- this._cacheModuleGraphModuleValue2 = undefined;
101
- this._cacheModuleGraphDependencyKey = undefined;
102
- this._cacheModuleGraphDependencyValue = undefined;
103
-
104
126
  /** @type {WeakTupleMap<any[], any>} */
105
127
  this._cache = undefined;
106
128
 
107
- /** @type {WeakMap<Module, WeakTupleMap<any, any>>} */
129
+ /** @type {Map<Module, WeakTupleMap<any, any>>} */
108
130
  this._moduleMemCaches = undefined;
109
131
  }
110
132
 
@@ -113,19 +135,11 @@ class ModuleGraph {
113
135
  * @returns {ModuleGraphModule} the internal module
114
136
  */
115
137
  _getModuleGraphModule(module) {
116
- if (this._cacheModuleGraphModuleKey1 === module)
117
- return this._cacheModuleGraphModuleValue1;
118
- if (this._cacheModuleGraphModuleKey2 === module)
119
- return this._cacheModuleGraphModuleValue2;
120
138
  let mgm = this._moduleMap.get(module);
121
139
  if (mgm === undefined) {
122
140
  mgm = new ModuleGraphModule();
123
141
  this._moduleMap.set(module, mgm);
124
142
  }
125
- this._cacheModuleGraphModuleKey2 = this._cacheModuleGraphModuleKey1;
126
- this._cacheModuleGraphModuleValue2 = this._cacheModuleGraphModuleValue1;
127
- this._cacheModuleGraphModuleKey1 = module;
128
- this._cacheModuleGraphModuleValue1 = mgm;
129
143
  return mgm;
130
144
  }
131
145
 
@@ -133,9 +147,11 @@ class ModuleGraph {
133
147
  * @param {Dependency} dependency the dependency
134
148
  * @param {DependenciesBlock} block parent block
135
149
  * @param {Module} module parent module
150
+ * @param {number=} indexInBlock position in block
136
151
  * @returns {void}
137
152
  */
138
- setParents(dependency, block, module) {
153
+ setParents(dependency, block, module, indexInBlock = -1) {
154
+ dependency._parentDependenciesBlockIndex = indexInBlock;
139
155
  dependency._parentDependenciesBlock = block;
140
156
  dependency._parentModule = module;
141
157
  }
@@ -156,6 +172,14 @@ class ModuleGraph {
156
172
  return dependency._parentDependenciesBlock;
157
173
  }
158
174
 
175
+ /**
176
+ * @param {Dependency} dependency the dependency
177
+ * @returns {number} index
178
+ */
179
+ getParentBlockIndex(dependency) {
180
+ return dependency._parentDependenciesBlockIndex;
181
+ }
182
+
159
183
  /**
160
184
  * @param {Module} originModule the referencing module
161
185
  * @param {Dependency} dependency the referencing dependency
@@ -180,7 +204,7 @@ class ModuleGraph {
180
204
  }
181
205
  mgm._unassignedConnections.push(connection);
182
206
  if (mgm.outgoingConnections === undefined) {
183
- mgm.outgoingConnections = new Set();
207
+ mgm.outgoingConnections = new SortableSet();
184
208
  }
185
209
  mgm.outgoingConnections.add(connection);
186
210
  } else {
@@ -282,7 +306,7 @@ class ModuleGraph {
282
306
  const oldConnections = oldMgm.outgoingConnections;
283
307
  if (oldConnections !== undefined) {
284
308
  if (newMgm.outgoingConnections === undefined) {
285
- newMgm.outgoingConnections = new Set();
309
+ newMgm.outgoingConnections = new SortableSet();
286
310
  }
287
311
  const newConnections = newMgm.outgoingConnections;
288
312
  for (const connection of oldConnections) {
@@ -319,7 +343,7 @@ class ModuleGraph {
319
343
  const oldConnections = oldMgm.outgoingConnections;
320
344
  if (oldConnections !== undefined) {
321
345
  if (newMgm.outgoingConnections === undefined) {
322
- newMgm.outgoingConnections = new Set();
346
+ newMgm.outgoingConnections = new SortableSet();
323
347
  }
324
348
  const newConnections = newMgm.outgoingConnections;
325
349
  for (const connection of oldConnections) {
@@ -434,13 +458,24 @@ class ModuleGraph {
434
458
 
435
459
  /**
436
460
  * @param {Module} module the module
437
- * @returns {readonly Map<Module, readonly ModuleGraphConnection[]>} reasons why a module is included, in a map by source module
461
+ * @returns {readonly Map<Module | undefined, readonly ModuleGraphConnection[]>} reasons why a module is included, in a map by source module
438
462
  */
439
463
  getIncomingConnectionsByOriginModule(module) {
440
464
  const connections = this._getModuleGraphModule(module).incomingConnections;
441
465
  return connections.getFromUnorderedCache(getConnectionsByOriginModule);
442
466
  }
443
467
 
468
+ /**
469
+ * @param {Module} module the module
470
+ * @returns {readonly Map<Module | undefined, readonly ModuleGraphConnection[]> | undefined} connections to modules, in a map by module
471
+ */
472
+ getOutgoingConnectionsByModule(module) {
473
+ const connections = this._getModuleGraphModule(module).outgoingConnections;
474
+ return connections === undefined
475
+ ? undefined
476
+ : connections.getFromUnorderedCache(getConnectionsByModule);
477
+ }
478
+
444
479
  /**
445
480
  * @param {Module} module the module
446
481
  * @returns {ModuleProfile | null} the module profile
@@ -728,7 +763,7 @@ class ModuleGraph {
728
763
  }
729
764
 
730
765
  /**
731
- * @param {WeakMap<Module, WeakTupleMap<any, any>>} moduleMemCaches mem caches for modules for better caching
766
+ * @param {Map<Module, WeakTupleMap<any, any>>} moduleMemCaches mem caches for modules for better caching
732
767
  */
733
768
  setModuleMemCaches(moduleMemCaches) {
734
769
  this._moduleMemCaches = moduleMemCaches;
@@ -37,6 +37,7 @@ const {
37
37
  keepOriginalOrder
38
38
  } = require("./util/comparators");
39
39
  const createHash = require("./util/createHash");
40
+ const { createFakeHook } = require("./util/deprecation");
40
41
  const { join } = require("./util/fs");
41
42
  const {
42
43
  contextify,
@@ -187,6 +188,7 @@ makeSerializable(
187
188
  * @property {SyncHook<[object, NormalModule]>} loader
188
189
  * @property {SyncHook<[LoaderItem[], NormalModule, object]>} beforeLoaders
189
190
  * @property {HookMap<AsyncSeriesBailHook<[string, NormalModule], string | Buffer>>} readResourceForScheme
191
+ * @property {HookMap<AsyncSeriesBailHook<[object], string | Buffer>>} readResource
190
192
  * @property {AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>} needBuild
191
193
  */
192
194
 
@@ -209,8 +211,28 @@ class NormalModule extends Module {
209
211
  hooks = {
210
212
  loader: new SyncHook(["loaderContext", "module"]),
211
213
  beforeLoaders: new SyncHook(["loaders", "module", "loaderContext"]),
212
- readResourceForScheme: new HookMap(
213
- () => new AsyncSeriesBailHook(["resource", "module"])
214
+ // TODO webpack 6 deprecate
215
+ readResourceForScheme: new HookMap(scheme => {
216
+ const hook = hooks.readResource.for(scheme);
217
+ return createFakeHook(
218
+ /** @type {AsyncSeriesBailHook<[string, NormalModule], string | Buffer>} */ ({
219
+ tap: (options, fn) =>
220
+ hook.tap(options, loaderContext =>
221
+ fn(loaderContext.resource, loaderContext._module)
222
+ ),
223
+ tapAsync: (options, fn) =>
224
+ hook.tapAsync(options, (loaderContext, callback) =>
225
+ fn(loaderContext.resource, loaderContext._module, callback)
226
+ ),
227
+ tapPromise: (options, fn) =>
228
+ hook.tapPromise(options, loaderContext =>
229
+ fn(loaderContext.resource, loaderContext._module)
230
+ )
231
+ })
232
+ );
233
+ }),
234
+ readResource: new HookMap(
235
+ () => new AsyncSeriesBailHook(["loaderContext"])
214
236
  ),
215
237
  needBuild: new AsyncSeriesBailHook(["module", "context"])
216
238
  };
@@ -786,20 +808,15 @@ class NormalModule extends Module {
786
808
  processResource: (loaderContext, resourcePath, callback) => {
787
809
  const resource = loaderContext.resource;
788
810
  const scheme = getScheme(resource);
789
- if (scheme) {
790
- hooks.readResourceForScheme
791
- .for(scheme)
792
- .callAsync(resource, this, (err, result) => {
793
- if (err) return callback(err);
794
- if (typeof result !== "string" && !result) {
795
- return callback(new UnhandledSchemeError(scheme, resource));
796
- }
797
- return callback(null, result);
798
- });
799
- } else {
800
- loaderContext.addDependency(resourcePath);
801
- fs.readFile(resourcePath, callback);
802
- }
811
+ hooks.readResource
812
+ .for(scheme)
813
+ .callAsync(loaderContext, (err, result) => {
814
+ if (err) return callback(err);
815
+ if (typeof result !== "string" && !result) {
816
+ return callback(new UnhandledSchemeError(scheme, resource));
817
+ }
818
+ return callback(null, result);
819
+ });
803
820
  }
804
821
  },
805
822
  (err, result) => {
@@ -550,7 +550,7 @@ class WebpackOptionsApply extends OptionsApply {
550
550
  "'cache.cacheUnaffected: true' is only allowed when 'experiments.cacheUnaffected' is enabled"
551
551
  );
552
552
  }
553
- compiler.moduleMemCaches = new WeakMap();
553
+ compiler.moduleMemCaches = new Map();
554
554
  }
555
555
  break;
556
556
  }
@@ -577,7 +577,7 @@ class WebpackOptionsApply extends OptionsApply {
577
577
  "'cache.memoryCacheUnaffected: true' is only allowed when 'experiments.cacheUnaffected' is enabled"
578
578
  );
579
579
  }
580
- compiler.moduleMemCaches = new WeakMap();
580
+ compiler.moduleMemCaches = new Map();
581
581
  }
582
582
  switch (cacheOptions.store) {
583
583
  case "pack": {
@@ -43,7 +43,7 @@ const { getEntryRuntime, mergeRuntime } = require("./util/runtime");
43
43
  * @property {boolean} minAvailableModulesOwned true, if minAvailableModules is owned and can be modified
44
44
  * @property {ModuleSetPlus[]} availableModulesToBeMerged enqueued updates to the minimal set of available modules
45
45
  * @property {Set<Module>=} skippedItems modules that were skipped because module is already available in parent chunks (need to reconsider when minAvailableModules is shrinking)
46
- * @property {Set<[Module, ModuleGraphConnection[]]>=} skippedModuleConnections referenced modules that where skipped because they were not active in this runtime
46
+ * @property {Set<[Module, ConnectionState]>=} skippedModuleConnections referenced modules that where skipped because they were not active in this runtime
47
47
  * @property {ModuleSetPlus} resultingAvailableModules set of modules available including modules from this chunk group
48
48
  * @property {Set<ChunkGroupInfo>} children set of children chunk groups, that will be revisited when availableModules shrink
49
49
  * @property {Set<ChunkGroupInfo>} availableSources set of chunk groups that are the source for minAvailableModules
@@ -70,97 +70,106 @@ const bySetSize = (a, b) => {
70
70
  return b.size + b.plus.size - a.size - a.plus.size;
71
71
  };
72
72
 
73
- /**
74
- *
75
- * @param {ModuleGraphConnection[]} connections list of connections
76
- * @param {RuntimeSpec} runtime for which runtime
77
- * @returns {ConnectionState} connection state
78
- */
79
- const getActiveStateOfConnections = (connections, runtime) => {
80
- let merged = connections[0].getActiveState(runtime);
81
- if (merged === true) return true;
82
- for (let i = 1; i < connections.length; i++) {
83
- const c = connections[i];
84
- merged = ModuleGraphConnection.addConnectionStates(
85
- merged,
86
- c.getActiveState(runtime)
87
- );
88
- if (merged === true) return true;
73
+ const extractBlockModules = (module, moduleGraph, runtime, blockModulesMap) => {
74
+ let blockCache;
75
+ let modules;
76
+
77
+ const arrays = [];
78
+
79
+ const queue = [module];
80
+ while (queue.length > 0) {
81
+ const block = queue.pop();
82
+ const arr = [];
83
+ arrays.push(arr);
84
+ blockModulesMap.set(block, arr);
85
+ for (const b of block.blocks) {
86
+ queue.push(b);
87
+ }
89
88
  }
90
- return merged;
91
- };
92
89
 
93
- /**
94
- * Extracts block to modules mapping from all modules
95
- * @param {Compilation} compilation the compilation
96
- * @returns {Map<DependenciesBlock, Map<Module, ModuleGraphConnection[]>>} the mapping block to modules
97
- */
98
- const extractBlockModulesMap = compilation => {
99
- const { moduleGraph } = compilation;
100
-
101
- /** @type {Map<DependenciesBlock, Map<Module, ModuleGraphConnection[]>>} */
102
- const blockModulesMap = new Map();
103
-
104
- const blockQueue = new Set();
105
-
106
- for (const module of compilation.modules) {
107
- /** @type {WeakMap<Dependency, ModuleGraphConnection>} */
108
- let moduleMap;
109
-
110
- for (const connection of moduleGraph.getOutgoingConnections(module)) {
111
- const d = connection.dependency;
112
- // We skip connections without dependency
113
- if (!d) continue;
114
- const m = connection.module;
115
- // We skip connections without Module pointer
116
- if (!m) continue;
117
- // We skip weak connections
118
- if (connection.weak) continue;
119
- const state = connection.getActiveState(undefined);
120
- // We skip inactive connections
121
- if (state === false) continue;
122
- // Store Dependency to Module mapping in local map
123
- // to allow to access it faster compared to
124
- // moduleGraph.getConnection()
125
- if (moduleMap === undefined) {
126
- moduleMap = new WeakMap();
127
- }
128
- moduleMap.set(connection.dependency, connection);
90
+ for (const connection of moduleGraph.getOutgoingConnections(module)) {
91
+ const d = connection.dependency;
92
+ // We skip connections without dependency
93
+ if (!d) continue;
94
+ const m = connection.module;
95
+ // We skip connections without Module pointer
96
+ if (!m) continue;
97
+ // We skip weak connections
98
+ if (connection.weak) continue;
99
+ const state = connection.getActiveState(runtime);
100
+ // We skip inactive connections
101
+ if (state === false) continue;
102
+
103
+ const block = moduleGraph.getParentBlock(d);
104
+ let index = moduleGraph.getParentBlockIndex(d);
105
+
106
+ // deprecated fallback
107
+ if (index < 0) {
108
+ index = block.dependencies.indexOf(d);
129
109
  }
130
110
 
131
- blockQueue.clear();
132
- blockQueue.add(module);
133
- for (const block of blockQueue) {
134
- let modules;
135
-
136
- if (moduleMap !== undefined && block.dependencies) {
137
- for (const dep of block.dependencies) {
138
- const connection = moduleMap.get(dep);
139
- if (connection !== undefined) {
140
- const { module } = connection;
141
- if (modules === undefined) {
142
- modules = new Map();
143
- blockModulesMap.set(block, modules);
144
- }
145
- const old = modules.get(module);
146
- if (old !== undefined) {
147
- old.push(connection);
148
- } else {
149
- modules.set(module, [connection]);
150
- }
111
+ if (blockCache !== block) {
112
+ modules = blockModulesMap.get((blockCache = block));
113
+ }
114
+
115
+ const i = index << 2;
116
+ modules[i] = m;
117
+ modules[i + 1] = state;
118
+ }
119
+
120
+ for (const modules of arrays) {
121
+ if (modules.length === 0) continue;
122
+ let indexMap;
123
+ let length = 0;
124
+ outer: for (let j = 0; j < modules.length; j += 2) {
125
+ const m = modules[j];
126
+ if (m === undefined) continue;
127
+ const state = modules[j + 1];
128
+ if (indexMap === undefined) {
129
+ let i = 0;
130
+ for (; i < length; i += 2) {
131
+ if (modules[i] === m) {
132
+ const merged = modules[i + 1];
133
+ if (merged === true) continue outer;
134
+ modules[i + 1] = ModuleGraphConnection.addConnectionStates(
135
+ merged,
136
+ state
137
+ );
151
138
  }
152
139
  }
153
- }
154
-
155
- if (block.blocks) {
156
- for (const b of block.blocks) {
157
- blockQueue.add(b);
140
+ modules[length] = m;
141
+ length++;
142
+ modules[length] = state;
143
+ length++;
144
+ if (length > 30) {
145
+ // To avoid worse case performance, we will use an index map for
146
+ // linear cost access, which allows to maintain O(n) complexity
147
+ // while keeping allocations down to a minimum
148
+ indexMap = new Map();
149
+ for (let i = 0; i < length; i += 2) {
150
+ indexMap.set(modules[i], i + 1);
151
+ }
152
+ }
153
+ } else {
154
+ const idx = indexMap.get(m);
155
+ if (idx !== undefined) {
156
+ const merged = modules[idx];
157
+ if (merged === true) continue outer;
158
+ modules[idx] = ModuleGraphConnection.addConnectionStates(
159
+ merged,
160
+ state
161
+ );
162
+ } else {
163
+ modules[length] = m;
164
+ length++;
165
+ modules[length] = state;
166
+ indexMap.set(m, length);
167
+ length++;
158
168
  }
159
169
  }
160
170
  }
171
+ modules.length = length;
161
172
  }
162
-
163
- return blockModulesMap;
164
173
  };
165
174
 
166
175
  /**
@@ -182,10 +191,55 @@ const visitModules = (
182
191
  blocksWithNestedBlocks,
183
192
  allCreatedChunkGroups
184
193
  ) => {
185
- const { moduleGraph, chunkGraph } = compilation;
194
+ const { moduleGraph, chunkGraph, moduleMemCaches } = compilation;
186
195
 
187
- logger.time("visitModules: prepare");
188
- const blockModulesMap = extractBlockModulesMap(compilation);
196
+ const blockModulesRuntimeMap = new Map();
197
+
198
+ /** @type {RuntimeSpec | false} */
199
+ let blockModulesMapRuntime = false;
200
+ let blockModulesMap;
201
+
202
+ /**
203
+ *
204
+ * @param {DependenciesBlock} block block
205
+ * @param {RuntimeSpec} runtime runtime
206
+ * @returns {(Module | ConnectionState)[]} block modules in flatten tuples
207
+ */
208
+ const getBlockModules = (block, runtime) => {
209
+ if (blockModulesMapRuntime !== runtime) {
210
+ blockModulesMap = blockModulesRuntimeMap.get(runtime);
211
+ if (blockModulesMap === undefined) {
212
+ blockModulesMap = new Map();
213
+ blockModulesRuntimeMap.set(runtime, blockModulesMap);
214
+ }
215
+ }
216
+ let blockModules = blockModulesMap.get(block);
217
+ if (blockModules !== undefined) return blockModules;
218
+ const module = /** @type {Module} */ (block.getRootBlock());
219
+ const memCache = moduleMemCaches && moduleMemCaches.get(module);
220
+ if (memCache !== undefined) {
221
+ const map = memCache.provide(
222
+ "bundleChunkGraph.blockModules",
223
+ runtime,
224
+ () => {
225
+ logger.time("visitModules: prepare");
226
+ const map = new Map();
227
+ extractBlockModules(module, moduleGraph, runtime, map);
228
+ logger.timeAggregate("visitModules: prepare");
229
+ return map;
230
+ }
231
+ );
232
+ for (const [block, blockModules] of map)
233
+ blockModulesMap.set(block, blockModules);
234
+ return map.get(block);
235
+ } else {
236
+ logger.time("visitModules: prepare");
237
+ extractBlockModules(module, moduleGraph, runtime, blockModulesMap);
238
+ blockModules = blockModulesMap.get(block);
239
+ logger.timeAggregate("visitModules: prepare");
240
+ return blockModules;
241
+ }
242
+ };
189
243
 
190
244
  let statProcessedQueueItems = 0;
191
245
  let statProcessedBlocks = 0;
@@ -308,9 +362,7 @@ const visitModules = (
308
362
  /** @type {QueueItem[]} */
309
363
  let queueDelayed = [];
310
364
 
311
- logger.timeEnd("visitModules: prepare");
312
-
313
- /** @type {[Module, ModuleGraphConnection[]][]} */
365
+ /** @type {[Module, ConnectionState][]} */
314
366
  const skipConnectionBuffer = [];
315
367
  /** @type {Module[]} */
316
368
  const skipBuffer = [];
@@ -478,21 +530,23 @@ const visitModules = (
478
530
  const processBlock = block => {
479
531
  statProcessedBlocks++;
480
532
  // get prepared block info
481
- const blockModules = blockModulesMap.get(block);
533
+ const blockModules = getBlockModules(block, chunkGroupInfo.runtime);
482
534
 
483
535
  if (blockModules !== undefined) {
484
- const { minAvailableModules, runtime } = chunkGroupInfo;
536
+ const { minAvailableModules } = chunkGroupInfo;
485
537
  // Buffer items because order need to be reversed to get indices correct
486
538
  // Traverse all referenced modules
487
- for (const entry of blockModules) {
488
- const [refModule, connections] = entry;
539
+ for (let i = 0; i < blockModules.length; i += 2) {
540
+ const refModule = /** @type {Module} */ (blockModules[i]);
489
541
  if (chunkGraph.isModuleInChunk(refModule, chunk)) {
490
542
  // skip early if already connected
491
543
  continue;
492
544
  }
493
- const activeState = getActiveStateOfConnections(connections, runtime);
545
+ const activeState = /** @type {ConnectionState} */ (
546
+ blockModules[i + 1]
547
+ );
494
548
  if (activeState !== true) {
495
- skipConnectionBuffer.push(entry);
549
+ skipConnectionBuffer.push([refModule, activeState]);
496
550
  if (activeState === false) continue;
497
551
  }
498
552
  if (
@@ -562,12 +616,15 @@ const visitModules = (
562
616
  const processEntryBlock = block => {
563
617
  statProcessedBlocks++;
564
618
  // get prepared block info
565
- const blockModules = blockModulesMap.get(block);
619
+ const blockModules = getBlockModules(block, chunkGroupInfo.runtime);
566
620
 
567
621
  if (blockModules !== undefined) {
568
622
  // Traverse all referenced modules
569
- for (const [refModule, connections] of blockModules) {
570
- const activeState = getActiveStateOfConnections(connections, undefined);
623
+ for (let i = 0; i < blockModules.length; i += 2) {
624
+ const refModule = /** @type {Module} */ (blockModules[i]);
625
+ const activeState = /** @type {ConnectionState} */ (
626
+ blockModules[i + 1]
627
+ );
571
628
  // enqueue, then add and enter to be in the correct order
572
629
  // this is relevant with circular dependencies
573
630
  queueBuffer.push({
@@ -1059,10 +1116,9 @@ const visitModules = (
1059
1116
 
1060
1117
  // 2. Reconsider skipped connections
1061
1118
  if (info.skippedModuleConnections !== undefined) {
1062
- const { minAvailableModules, runtime } = info;
1119
+ const { minAvailableModules } = info;
1063
1120
  for (const entry of info.skippedModuleConnections) {
1064
- const [module, connections] = entry;
1065
- const activeState = getActiveStateOfConnections(connections, runtime);
1121
+ const [module, activeState] = entry;
1066
1122
  if (activeState === false) continue;
1067
1123
  if (activeState === true) {
1068
1124
  info.skippedModuleConnections.delete(entry);
@@ -1114,6 +1170,7 @@ const visitModules = (
1114
1170
  while (queue.length || queueConnect.size) {
1115
1171
  logger.time("visitModules: visiting");
1116
1172
  processQueue();
1173
+ logger.timeAggregateEnd("visitModules: prepare");
1117
1174
  logger.timeEnd("visitModules: visiting");
1118
1175
 
1119
1176
  if (chunkGroupsForCombining.size > 0) {
@@ -137,11 +137,9 @@ class ArrayPushCallbackChunkFormatPlugin {
137
137
  "ArrayPushCallbackChunkFormatPlugin",
138
138
  (chunk, hash, { chunkGraph, runtimeTemplate }) => {
139
139
  if (chunk.hasRuntime()) return;
140
- hash.update("ArrayPushCallbackChunkFormatPlugin");
141
- hash.update("1");
142
- hash.update(`${runtimeTemplate.outputOptions.chunkLoadingGlobal}`);
143
- hash.update(`${runtimeTemplate.outputOptions.hotUpdateGlobal}`);
144
- hash.update(`${runtimeTemplate.outputOptions.globalObject}`);
140
+ hash.update(
141
+ `ArrayPushCallbackChunkFormatPlugin1${runtimeTemplate.outputOptions.chunkLoadingGlobal}${runtimeTemplate.outputOptions.hotUpdateGlobal}${runtimeTemplate.outputOptions.globalObject}`
142
+ );
145
143
  const entries = Array.from(
146
144
  chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
147
145
  );
@@ -155,6 +155,7 @@ class WebpackLogger {
155
155
  if (this[TIMERS_AGGREGATES_SYMBOL] === undefined) return;
156
156
  const time = this[TIMERS_AGGREGATES_SYMBOL].get(label);
157
157
  if (time === undefined) return;
158
+ this[TIMERS_AGGREGATES_SYMBOL].delete(label);
158
159
  this[LOG_SYMBOL](LogType.time, [label, ...time]);
159
160
  }
160
161
  }
@@ -19,6 +19,7 @@ const builtins = [
19
19
  "constants",
20
20
  "crypto",
21
21
  "dgram",
22
+ "diagnostics_channel",
22
23
  "dns",
23
24
  "dns/promises",
24
25
  "domain",
@@ -30,6 +30,7 @@ class EnsureChunkConditionsPlugin {
30
30
  /** @type {Set<ChunkGroup>} */
31
31
  const chunkGroups = new Set();
32
32
  for (const module of compilation.modules) {
33
+ if (!module.hasChunkCondition()) continue;
33
34
  for (const chunk of chunkGraph.getModuleChunksIterable(module)) {
34
35
  if (!module.chunkCondition(chunk, compilation)) {
35
36
  sourceChunks.add(chunk);
@@ -157,6 +157,11 @@ class MangleExportsPlugin {
157
157
  compilation.hooks.optimizeCodeGeneration.tap(
158
158
  "MangleExportsPlugin",
159
159
  modules => {
160
+ if (compilation.moduleMemCaches) {
161
+ throw new Error(
162
+ "optimization.mangleExports can't be used with cacheUnaffected as export mangling is a global effect"
163
+ );
164
+ }
160
165
  for (const module of modules) {
161
166
  const isNamespace =
162
167
  module.buildMeta && module.buildMeta.exportsType === "namespace";