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.

@@ -33,8 +33,6 @@ class AsyncDependenciesBlock extends DependenciesBlock {
33
33
  this.groupOptions = groupOptions;
34
34
  this.loc = loc;
35
35
  this.request = request;
36
- /** @type {DependenciesBlock} */
37
- this.parent = undefined;
38
36
  this._stringifiedGroupOptions = undefined;
39
37
  }
40
38
 
@@ -66,9 +64,10 @@ class AsyncDependenciesBlock extends DependenciesBlock {
66
64
  if (this._stringifiedGroupOptions === undefined) {
67
65
  this._stringifiedGroupOptions = JSON.stringify(this.groupOptions);
68
66
  }
69
- hash.update(this._stringifiedGroupOptions);
70
67
  const chunkGroup = chunkGraph.getBlockChunkGroup(this);
71
- hash.update(chunkGroup ? chunkGroup.id : "");
68
+ hash.update(
69
+ `${this._stringifiedGroupOptions}${chunkGroup ? chunkGroup.id : ""}`
70
+ );
72
71
  super.updateHash(hash, context);
73
72
  }
74
73
 
package/lib/Chunk.js CHANGED
@@ -539,9 +539,9 @@ class Chunk {
539
539
  * @returns {void}
540
540
  */
541
541
  updateHash(hash, chunkGraph) {
542
- hash.update(`${this.id} `);
543
- hash.update(this.ids ? this.ids.join(",") : "");
544
- hash.update(`${this.name || ""} `);
542
+ hash.update(
543
+ `${this.id} ${this.ids ? this.ids.join() : ""} ${this.name || ""} `
544
+ );
545
545
  const xor = new StringXor();
546
546
  for (const m of chunkGraph.getChunkModulesIterable(this)) {
547
547
  xor.add(chunkGraph.getModuleHash(m, this.runtime));
@@ -550,9 +550,7 @@ class Chunk {
550
550
  const entryModules =
551
551
  chunkGraph.getChunkEntryModulesWithChunkGroupIterable(this);
552
552
  for (const [m, chunkGroup] of entryModules) {
553
- hash.update("entry");
554
- hash.update(`${chunkGraph.getModuleId(m)}`);
555
- hash.update(chunkGroup.id);
553
+ hash.update(`entry${chunkGraph.getModuleId(m)}${chunkGroup.id}`);
556
554
  }
557
555
  }
558
556
 
@@ -0,0 +1,187 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const SortableSet = require("./util/SortableSet");
9
+
10
+ /** @typedef {import("./Chunk")} Chunk */
11
+
12
+ /**
13
+ * @template T
14
+ * @param {SortableSet<T>} set the set
15
+ * @returns {T[]} set as array
16
+ */
17
+ const getArray = set => {
18
+ return Array.from(set);
19
+ };
20
+
21
+ let debugId = 1;
22
+
23
+ class ChunkCombination {
24
+ constructor() {
25
+ this.debugId = debugId++;
26
+ this.size = 0;
27
+ /**
28
+ * (do not modify)
29
+ * @type {SortableSet<Chunk>}
30
+ */
31
+ this._chunks = new SortableSet();
32
+ /** @type {ChunkCombination} */
33
+ this._parent = undefined;
34
+ this._lastChunk = undefined;
35
+ /** @type {WeakMap<Chunk, ChunkCombination>} */
36
+ this._addMap = new WeakMap();
37
+ /** @type {WeakMap<Chunk, ChunkCombination>} */
38
+ this._removeCache = new WeakMap();
39
+ }
40
+
41
+ /**
42
+ * @returns {Iterable<Chunk>} iterable of chunks
43
+ */
44
+ get chunksIterable() {
45
+ return this._chunks;
46
+ }
47
+
48
+ /**
49
+ * @param {Chunk} chunk chunk to add
50
+ * @returns {ChunkCombination} new chunk combination
51
+ */
52
+ with(chunk) {
53
+ if (this._chunks.has(chunk)) return this;
54
+ let next = this._addMap.get(chunk);
55
+ if (next !== undefined) return next;
56
+ // must insert chunks in order to maintain order-independent identity of ChunkCombination
57
+ if (!this._parent || this._lastChunk.debugId < chunk.debugId) {
58
+ next = new ChunkCombination();
59
+ for (const chunk of this._chunks) {
60
+ next._chunks.add(chunk);
61
+ }
62
+ next._chunks.add(chunk);
63
+ next._removeCache.set(chunk, this);
64
+ next.size = this.size + 1;
65
+ next._parent = this;
66
+ next._lastChunk = chunk;
67
+ } else {
68
+ next = this._parent.with(chunk).with(this._lastChunk);
69
+ }
70
+ this._addMap.set(chunk, next);
71
+ return next;
72
+ }
73
+
74
+ /**
75
+ * @param {Chunk} chunk chunk to remove
76
+ * @returns {ChunkCombination} new chunk combination
77
+ */
78
+ without(chunk) {
79
+ if (!this._chunks.has(chunk)) return this;
80
+ let next = this._removeCache.get(chunk);
81
+ if (next !== undefined) return next;
82
+ const stack = [this._lastChunk];
83
+ let current = this._parent;
84
+ while (current._lastChunk !== chunk) {
85
+ stack.push(current._lastChunk);
86
+ current = current._parent;
87
+ }
88
+ next = current._parent;
89
+ while (stack.length) next = next.with(stack.pop());
90
+ this._removeCache.set(chunk, next);
91
+ return next;
92
+ }
93
+
94
+ withAll(other) {
95
+ if (other.size === 0) return this;
96
+ if (this.size === 0) return other;
97
+ const stack = [];
98
+ /** @type {ChunkCombination} */
99
+ let current = this;
100
+ for (;;) {
101
+ if (current._lastChunk.debugId < other._lastChunk.debugId) {
102
+ stack.push(other._lastChunk);
103
+ other = other._parent;
104
+ if (other.size === 0) {
105
+ while (stack.length) current = current.with(stack.pop());
106
+ return current;
107
+ }
108
+ } else {
109
+ stack.push(current._lastChunk);
110
+ current = current._parent;
111
+ if (current.size === 0) {
112
+ while (stack.length) other = other.with(stack.pop());
113
+ return other;
114
+ }
115
+ }
116
+ }
117
+ }
118
+
119
+ hasSharedChunks(other) {
120
+ if (this.size > other.size) {
121
+ const chunks = this._chunks;
122
+ for (const chunk of other._chunks) {
123
+ if (chunks.has(chunk)) return true;
124
+ }
125
+ } else {
126
+ const chunks = other._chunks;
127
+ for (const chunk of this._chunks) {
128
+ if (chunks.has(chunk)) return true;
129
+ }
130
+ }
131
+ return false;
132
+ }
133
+
134
+ /**
135
+ * @param {ChunkCombination} other other combination
136
+ * @returns {boolean} true, when other is a subset of this combination
137
+ */
138
+ isSubset(other) {
139
+ // TODO: This could be more efficient when using the debugId order of the combinations
140
+ /** @type {ChunkCombination} */
141
+ let current = this;
142
+ let otherSize = other.size;
143
+ let currentSize = current.size;
144
+ if (otherSize === 0) return true;
145
+ for (;;) {
146
+ if (currentSize === 0) return false;
147
+ if (otherSize === 1) {
148
+ if (currentSize === 1) {
149
+ return current._lastChunk === other._lastChunk;
150
+ } else {
151
+ return current._chunks.has(other._lastChunk);
152
+ }
153
+ }
154
+ if (otherSize * 8 < currentSize) {
155
+ // go for the Set access when current >> other
156
+ const chunks = current._chunks;
157
+ for (const item of other._chunks) {
158
+ if (!chunks.has(item)) return false;
159
+ }
160
+ return true;
161
+ }
162
+ const otherId = other._lastChunk.debugId;
163
+ // skip over nodes in current that have higher ids
164
+ while (otherId < current._lastChunk.debugId) {
165
+ current = current._parent;
166
+ currentSize--;
167
+ if (currentSize === 0) return false;
168
+ }
169
+ if (otherId > current._lastChunk.debugId) {
170
+ return false;
171
+ }
172
+ other = other._parent;
173
+ otherSize--;
174
+ if (otherSize === 0) return true;
175
+ current = current._parent;
176
+ currentSize--;
177
+ }
178
+ }
179
+
180
+ getChunks() {
181
+ return this._chunks.getFromUnorderedCache(getArray);
182
+ }
183
+ }
184
+
185
+ ChunkCombination.empty = new ChunkCombination();
186
+
187
+ module.exports = ChunkCombination;
package/lib/ChunkGraph.js CHANGED
@@ -6,6 +6,7 @@
6
6
  "use strict";
7
7
 
8
8
  const util = require("util");
9
+ const ChunkCombination = require("./ChunkCombination");
9
10
  const Entrypoint = require("./Entrypoint");
10
11
  const ModuleGraphConnection = require("./ModuleGraphConnection");
11
12
  const { first } = require("./util/SetHelpers");
@@ -40,6 +41,8 @@ const {
40
41
  /** @type {ReadonlySet<string>} */
41
42
  const EMPTY_SET = new Set();
42
43
 
44
+ const EMPTY_RUNTIME_SPEC_SET = new RuntimeSpecSet();
45
+
43
46
  const ZERO_BIG_INT = BigInt(0);
44
47
 
45
48
  const compareModuleIterables = compareIterables(compareModulesByIdentifier);
@@ -177,8 +180,7 @@ const isAvailableChunk = (a, b) => {
177
180
 
178
181
  class ChunkGraphModule {
179
182
  constructor() {
180
- /** @type {SortableSet<Chunk>} */
181
- this.chunks = new SortableSet();
183
+ this.chunkCombination = ChunkCombination.empty;
182
184
  /** @type {Set<Chunk> | undefined} */
183
185
  this.entryInChunks = undefined;
184
186
  /** @type {Set<Chunk> | undefined} */
@@ -235,16 +237,6 @@ class ChunkGraph {
235
237
  this._hashFunction = hashFunction;
236
238
 
237
239
  this._getGraphRoots = this._getGraphRoots.bind(this);
238
-
239
- // Caching
240
- this._cacheChunkGraphModuleKey1 = undefined;
241
- this._cacheChunkGraphModuleValue1 = undefined;
242
- this._cacheChunkGraphModuleKey2 = undefined;
243
- this._cacheChunkGraphModuleValue2 = undefined;
244
- this._cacheChunkGraphChunkKey1 = undefined;
245
- this._cacheChunkGraphChunkValue1 = undefined;
246
- this._cacheChunkGraphChunkKey2 = undefined;
247
- this._cacheChunkGraphChunkValue2 = undefined;
248
240
  }
249
241
 
250
242
  /**
@@ -253,19 +245,11 @@ class ChunkGraph {
253
245
  * @returns {ChunkGraphModule} internal module
254
246
  */
255
247
  _getChunkGraphModule(module) {
256
- if (this._cacheChunkGraphModuleKey1 === module)
257
- return this._cacheChunkGraphModuleValue1;
258
- if (this._cacheChunkGraphModuleKey2 === module)
259
- return this._cacheChunkGraphModuleValue2;
260
248
  let cgm = this._modules.get(module);
261
249
  if (cgm === undefined) {
262
250
  cgm = new ChunkGraphModule();
263
251
  this._modules.set(module, cgm);
264
252
  }
265
- this._cacheChunkGraphModuleKey2 = this._cacheChunkGraphModuleKey1;
266
- this._cacheChunkGraphModuleValue2 = this._cacheChunkGraphModuleValue1;
267
- this._cacheChunkGraphModuleKey1 = module;
268
- this._cacheChunkGraphModuleValue1 = cgm;
269
253
  return cgm;
270
254
  }
271
255
 
@@ -275,19 +259,11 @@ class ChunkGraph {
275
259
  * @returns {ChunkGraphChunk} internal chunk
276
260
  */
277
261
  _getChunkGraphChunk(chunk) {
278
- if (this._cacheChunkGraphChunkKey1 === chunk)
279
- return this._cacheChunkGraphChunkValue1;
280
- if (this._cacheChunkGraphChunkKey2 === chunk)
281
- return this._cacheChunkGraphChunkValue2;
282
262
  let cgc = this._chunks.get(chunk);
283
263
  if (cgc === undefined) {
284
264
  cgc = new ChunkGraphChunk();
285
265
  this._chunks.set(chunk, cgc);
286
266
  }
287
- this._cacheChunkGraphChunkKey2 = this._cacheChunkGraphChunkKey1;
288
- this._cacheChunkGraphChunkValue2 = this._cacheChunkGraphChunkValue1;
289
- this._cacheChunkGraphChunkKey1 = chunk;
290
- this._cacheChunkGraphChunkValue1 = cgc;
291
267
  return cgc;
292
268
  }
293
269
 
@@ -327,7 +303,7 @@ class ChunkGraph {
327
303
  connectChunkAndModule(chunk, module) {
328
304
  const cgm = this._getChunkGraphModule(module);
329
305
  const cgc = this._getChunkGraphChunk(chunk);
330
- cgm.chunks.add(chunk);
306
+ cgm.chunkCombination = cgm.chunkCombination.with(chunk);
331
307
  cgc.modules.add(module);
332
308
  }
333
309
 
@@ -340,7 +316,7 @@ class ChunkGraph {
340
316
  const cgm = this._getChunkGraphModule(module);
341
317
  const cgc = this._getChunkGraphChunk(chunk);
342
318
  cgc.modules.delete(module);
343
- cgm.chunks.delete(chunk);
319
+ cgm.chunkCombination = cgm.chunkCombination.without(chunk);
344
320
  }
345
321
 
346
322
  /**
@@ -351,7 +327,7 @@ class ChunkGraph {
351
327
  const cgc = this._getChunkGraphChunk(chunk);
352
328
  for (const module of cgc.modules) {
353
329
  const cgm = this._getChunkGraphModule(module);
354
- cgm.chunks.delete(chunk);
330
+ cgm.chunkCombination = cgm.chunkCombination.without(chunk);
355
331
  }
356
332
  cgc.modules.clear();
357
333
  chunk.disconnectFromGroups();
@@ -418,13 +394,13 @@ class ChunkGraph {
418
394
  const oldCgm = this._getChunkGraphModule(oldModule);
419
395
  const newCgm = this._getChunkGraphModule(newModule);
420
396
 
421
- for (const chunk of oldCgm.chunks) {
397
+ for (const chunk of oldCgm.chunkCombination._chunks) {
422
398
  const cgc = this._getChunkGraphChunk(chunk);
423
399
  cgc.modules.delete(oldModule);
424
400
  cgc.modules.add(newModule);
425
- newCgm.chunks.add(chunk);
401
+ newCgm.chunkCombination = newCgm.chunkCombination.with(chunk);
426
402
  }
427
- oldCgm.chunks.clear();
403
+ oldCgm.chunkCombination = ChunkCombination.empty;
428
404
 
429
405
  if (oldCgm.entryInChunks !== undefined) {
430
406
  if (newCgm.entryInChunks === undefined) {
@@ -511,13 +487,22 @@ class ChunkGraph {
511
487
  return cgm.entryInChunks !== undefined;
512
488
  }
513
489
 
490
+ /**
491
+ * @param {Module} module the module
492
+ * @returns {ChunkCombination} chunk combination (do not modify)
493
+ */
494
+ getModuleChunkCombination(module) {
495
+ const cgm = this._getChunkGraphModule(module);
496
+ return cgm.chunkCombination;
497
+ }
498
+
514
499
  /**
515
500
  * @param {Module} module the module
516
501
  * @returns {Iterable<Chunk>} iterable of chunks (do not modify)
517
502
  */
518
503
  getModuleChunksIterable(module) {
519
504
  const cgm = this._getChunkGraphModule(module);
520
- return cgm.chunks;
505
+ return cgm.chunkCombination._chunks;
521
506
  }
522
507
 
523
508
  /**
@@ -527,8 +512,9 @@ class ChunkGraph {
527
512
  */
528
513
  getOrderedModuleChunksIterable(module, sortFn) {
529
514
  const cgm = this._getChunkGraphModule(module);
530
- cgm.chunks.sortWith(sortFn);
531
- return cgm.chunks;
515
+ const chunks = cgm.chunkCombination._chunks;
516
+ chunks.sortWith(sortFn);
517
+ return chunks;
532
518
  }
533
519
 
534
520
  /**
@@ -537,7 +523,7 @@ class ChunkGraph {
537
523
  */
538
524
  getModuleChunks(module) {
539
525
  const cgm = this._getChunkGraphModule(module);
540
- return cgm.chunks.getFromCache(getArray);
526
+ return cgm.chunkCombination.getChunks();
541
527
  }
542
528
 
543
529
  /**
@@ -546,7 +532,7 @@ class ChunkGraph {
546
532
  */
547
533
  getNumberOfModuleChunks(module) {
548
534
  const cgm = this._getChunkGraphModule(module);
549
- return cgm.chunks.size;
535
+ return cgm.chunkCombination.size;
550
536
  }
551
537
 
552
538
  /**
@@ -555,7 +541,10 @@ class ChunkGraph {
555
541
  */
556
542
  getModuleRuntimes(module) {
557
543
  const cgm = this._getChunkGraphModule(module);
558
- return cgm.chunks.getFromUnorderedCache(getModuleRuntimes);
544
+ if (cgm.chunkCombination.size === 0) return EMPTY_RUNTIME_SPEC_SET;
545
+ return cgm.chunkCombination._chunks.getFromUnorderedCache(
546
+ getModuleRuntimes
547
+ );
559
548
  }
560
549
 
561
550
  /**
@@ -919,8 +908,7 @@ class ChunkGraph {
919
908
  // Merge runtime
920
909
  chunkA.runtime = mergeRuntime(chunkA.runtime, chunkB.runtime);
921
910
 
922
- // getChunkModules is used here to create a clone, because disconnectChunkAndModule modifies
923
- for (const module of this.getChunkModules(chunkB)) {
911
+ for (const module of this.getChunkModulesIterable(chunkB)) {
924
912
  this.disconnectChunkAndModule(chunkB, module);
925
913
  this.connectChunkAndModule(chunkA, module);
926
914
  }
@@ -1499,8 +1487,7 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
1499
1487
  }
1500
1488
  const graphHash = cgm.graphHashes.provide(runtime, () => {
1501
1489
  const hash = createHash(this._hashFunction);
1502
- hash.update(`${cgm.id}`);
1503
- hash.update(`${this.moduleGraph.isAsync(module)}`);
1490
+ hash.update(`${cgm.id}${this.moduleGraph.isAsync(module)}`);
1504
1491
  this.moduleGraph.getExportsInfo(module).updateHash(hash, runtime);
1505
1492
  return BigInt(`0x${/** @type {string} */ (hash.digest("hex"))}`);
1506
1493
  });