webpack 5.90.2 → 5.90.3
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.
- package/lib/Compilation.js +1 -1
- package/lib/ContextModule.js +2 -1
- package/lib/CssModule.js +0 -3
- package/lib/DelegatedModule.js +2 -1
- package/lib/DllModule.js +2 -1
- package/lib/ExternalModule.js +2 -1
- package/lib/Module.js +24 -3
- package/lib/MultiCompiler.js +36 -10
- package/lib/NormalModule.js +236 -85
- package/lib/NormalModuleFactory.js +162 -31
- package/lib/RawModule.js +2 -1
- package/lib/ResolverFactory.js +2 -0
- package/lib/RuntimeModule.js +2 -1
- package/lib/Stats.js +2 -2
- package/lib/asset/RawDataUrlModule.js +2 -1
- package/lib/buildChunkGraph.js +111 -336
- package/lib/container/ContainerEntryModule.js +2 -1
- package/lib/container/FallbackModule.js +2 -1
- package/lib/container/RemoteModule.js +2 -1
- package/lib/css/CssLoadingRuntimeModule.js +1 -1
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +15 -5
- package/lib/dependencies/WorkerDependency.js +1 -1
- package/lib/dependencies/WorkerPlugin.js +4 -4
- package/lib/hmr/LazyCompilationPlugin.js +2 -1
- package/lib/optimize/ConcatenatedModule.js +2 -1
- package/lib/sharing/ConsumeSharedModule.js +2 -1
- package/lib/sharing/ProvideSharedModule.js +2 -1
- package/lib/util/memoize.js +2 -0
- package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +2 -1
- package/lib/webpack.js +5 -3
- package/package.json +1 -1
- package/types.d.ts +122 -78
package/lib/buildChunkGraph.js
CHANGED
@@ -34,18 +34,15 @@ const { getEntryRuntime, mergeRuntime } = require("./util/runtime");
|
|
34
34
|
* @property {ChunkGroupInfo} chunkGroupInfo
|
35
35
|
*/
|
36
36
|
|
37
|
-
/** @typedef {Set<Module> & { plus: Set<Module> }} ModuleSetPlus */
|
38
|
-
|
39
37
|
/**
|
40
38
|
* @typedef {Object} ChunkGroupInfo
|
41
39
|
* @property {ChunkGroup} chunkGroup the chunk group
|
42
40
|
* @property {RuntimeSpec} runtime the runtimes
|
43
|
-
* @property {
|
44
|
-
* @property {
|
45
|
-
* @property {ModuleSetPlus[]} availableModulesToBeMerged enqueued updates to the minimal set of available modules
|
41
|
+
* @property {bigint | undefined} minAvailableModules current minimal set of modules available at this point
|
42
|
+
* @property {bigint[]} availableModulesToBeMerged enqueued updates to the minimal set of available modules
|
46
43
|
* @property {Set<Module>=} skippedItems modules that were skipped because module is already available in parent chunks (need to reconsider when minAvailableModules is shrinking)
|
47
44
|
* @property {Set<[Module, ModuleGraphConnection[]]>=} skippedModuleConnections referenced modules that where skipped because they were not active in this runtime
|
48
|
-
* @property {
|
45
|
+
* @property {bigint | undefined} resultingAvailableModules set of modules available including modules from this chunk group
|
49
46
|
* @property {Set<ChunkGroupInfo> | undefined} children set of children chunk groups, that will be revisited when availableModules shrink
|
50
47
|
* @property {Set<ChunkGroupInfo> | undefined} availableSources set of chunk groups that are the source for minAvailableModules
|
51
48
|
* @property {Set<ChunkGroupInfo> | undefined} availableChildren set of chunk groups which depend on the this chunk group as availableSource
|
@@ -61,17 +58,16 @@ const { getEntryRuntime, mergeRuntime } = require("./util/runtime");
|
|
61
58
|
* @property {ChunkGroup} chunkGroup referenced chunk group
|
62
59
|
*/
|
63
60
|
|
64
|
-
const
|
65
|
-
|
61
|
+
const ZERO_BIGINT = BigInt(0);
|
62
|
+
const ONE_BIGINT = BigInt(1);
|
66
63
|
|
67
64
|
/**
|
68
|
-
* @param {
|
69
|
-
* @param {
|
70
|
-
* @returns {
|
65
|
+
* @param {bigint} mask The mask to test
|
66
|
+
* @param {number} ordinal The ordinal of the bit to test
|
67
|
+
* @returns {boolean} If the ordinal-th bit is set in the mask
|
71
68
|
*/
|
72
|
-
const
|
73
|
-
|
74
|
-
};
|
69
|
+
const isOrdinalSetInMask = (mask, ordinal) =>
|
70
|
+
BigInt.asUintN(1, mask >> BigInt(ordinal)) !== ZERO_BIGINT;
|
75
71
|
|
76
72
|
/**
|
77
73
|
* @param {ModuleGraphConnection[]} connections list of connections
|
@@ -209,6 +205,7 @@ const extractBlockModules = (module, moduleGraph, runtime, blockModulesMap) => {
|
|
209
205
|
* @param {Map<AsyncDependenciesBlock, BlockChunkGroupConnection[]>} blockConnections connection for blocks
|
210
206
|
* @param {Set<DependenciesBlock>} blocksWithNestedBlocks flag for blocks that have nested blocks
|
211
207
|
* @param {Set<ChunkGroup>} allCreatedChunkGroups filled with all chunk groups that are created here
|
208
|
+
* @param {Map<Chunk, bigint>} maskByChunk module content mask by chunk
|
212
209
|
*/
|
213
210
|
const visitModules = (
|
214
211
|
logger,
|
@@ -217,7 +214,8 @@ const visitModules = (
|
|
217
214
|
chunkGroupInfoMap,
|
218
215
|
blockConnections,
|
219
216
|
blocksWithNestedBlocks,
|
220
|
-
allCreatedChunkGroups
|
217
|
+
allCreatedChunkGroups,
|
218
|
+
maskByChunk
|
221
219
|
) => {
|
222
220
|
const { moduleGraph, chunkGraph, moduleMemCaches } = compilation;
|
223
221
|
|
@@ -228,6 +226,30 @@ const visitModules = (
|
|
228
226
|
/** @type {Map<DependenciesBlock, (Module | ConnectionState)[]>} */
|
229
227
|
let blockModulesMap;
|
230
228
|
|
229
|
+
/** @type {Map<Module, number>} */
|
230
|
+
const ordinalByModule = new Map();
|
231
|
+
|
232
|
+
/**
|
233
|
+
* @param {Module} module The module to look up
|
234
|
+
* @returns {number} The ordinal of the module in masks
|
235
|
+
*/
|
236
|
+
const getModuleOrdinal = module => {
|
237
|
+
let ordinal = ordinalByModule.get(module);
|
238
|
+
if (ordinal === undefined) {
|
239
|
+
ordinal = ordinalByModule.size;
|
240
|
+
ordinalByModule.set(module, ordinal);
|
241
|
+
}
|
242
|
+
return ordinal;
|
243
|
+
};
|
244
|
+
|
245
|
+
for (const chunk of compilation.chunks) {
|
246
|
+
let mask = ZERO_BIGINT;
|
247
|
+
for (const m of chunkGraph.getChunkModulesIterable(chunk)) {
|
248
|
+
mask |= ONE_BIGINT << BigInt(getModuleOrdinal(m));
|
249
|
+
}
|
250
|
+
maskByChunk.set(chunk, mask);
|
251
|
+
}
|
252
|
+
|
231
253
|
/**
|
232
254
|
*
|
233
255
|
* @param {DependenciesBlock} block block
|
@@ -331,7 +353,6 @@ const visitModules = (
|
|
331
353
|
chunkGroup,
|
332
354
|
runtime,
|
333
355
|
minAvailableModules: undefined,
|
334
|
-
minAvailableModulesOwned: false,
|
335
356
|
availableModulesToBeMerged: [],
|
336
357
|
skippedItems: undefined,
|
337
358
|
resultingAvailableModules: undefined,
|
@@ -354,15 +375,12 @@ const visitModules = (
|
|
354
375
|
// minAvailableModules for child entrypoints are unknown yet, set to undefined.
|
355
376
|
// This means no module is added until other sets are merged into
|
356
377
|
// this minAvailableModules (by the parent entrypoints)
|
357
|
-
const skippedItems = new Set();
|
358
|
-
for (const module of modules) {
|
359
|
-
skippedItems.add(module);
|
360
|
-
}
|
378
|
+
const skippedItems = new Set(modules);
|
361
379
|
chunkGroupInfo.skippedItems = skippedItems;
|
362
380
|
chunkGroupsForCombining.add(chunkGroupInfo);
|
363
381
|
} else {
|
364
382
|
// The application may start here: We start with an empty list of available modules
|
365
|
-
chunkGroupInfo.minAvailableModules =
|
383
|
+
chunkGroupInfo.minAvailableModules = ZERO_BIGINT;
|
366
384
|
const chunk = chunkGroup.getEntrypointChunk();
|
367
385
|
for (const module of modules) {
|
368
386
|
queue.push({
|
@@ -450,12 +468,12 @@ const visitModules = (
|
|
450
468
|
b.loc,
|
451
469
|
b.request
|
452
470
|
);
|
471
|
+
maskByChunk.set(entrypoint.chunks[0], ZERO_BIGINT);
|
453
472
|
entrypoint.index = nextChunkGroupIndex++;
|
454
473
|
cgi = {
|
455
474
|
chunkGroup: entrypoint,
|
456
475
|
runtime: entrypoint.options.runtime || entrypoint.name,
|
457
|
-
minAvailableModules:
|
458
|
-
minAvailableModulesOwned: false,
|
476
|
+
minAvailableModules: ZERO_BIGINT,
|
459
477
|
availableModulesToBeMerged: [],
|
460
478
|
skippedItems: undefined,
|
461
479
|
resultingAvailableModules: undefined,
|
@@ -490,7 +508,7 @@ const visitModules = (
|
|
490
508
|
queueDelayed.push({
|
491
509
|
action: PROCESS_ENTRY_BLOCK,
|
492
510
|
block: b,
|
493
|
-
module
|
511
|
+
module,
|
494
512
|
chunk: entrypoint.chunks[0],
|
495
513
|
chunkGroup: entrypoint,
|
496
514
|
chunkGroupInfo: cgi
|
@@ -500,7 +518,7 @@ const visitModules = (
|
|
500
518
|
queue.push({
|
501
519
|
action: PROCESS_BLOCK,
|
502
520
|
block: b,
|
503
|
-
module
|
521
|
+
module,
|
504
522
|
chunk,
|
505
523
|
chunkGroup,
|
506
524
|
chunkGroupInfo
|
@@ -514,12 +532,12 @@ const visitModules = (
|
|
514
532
|
b.loc,
|
515
533
|
b.request
|
516
534
|
);
|
535
|
+
maskByChunk.set(c.chunks[0], ZERO_BIGINT);
|
517
536
|
c.index = nextChunkGroupIndex++;
|
518
537
|
cgi = {
|
519
538
|
chunkGroup: c,
|
520
539
|
runtime: chunkGroupInfo.runtime,
|
521
540
|
minAvailableModules: undefined,
|
522
|
-
minAvailableModulesOwned: undefined,
|
523
541
|
availableModulesToBeMerged: [],
|
524
542
|
skippedItems: undefined,
|
525
543
|
resultingAvailableModules: undefined,
|
@@ -584,7 +602,7 @@ const visitModules = (
|
|
584
602
|
queueDelayed.push({
|
585
603
|
action: PROCESS_BLOCK,
|
586
604
|
block: b,
|
587
|
-
module
|
605
|
+
module,
|
588
606
|
chunk: c.chunks[0],
|
589
607
|
chunkGroup: c,
|
590
608
|
chunkGroupInfo: /** @type {ChunkGroupInfo} */ (cgi)
|
@@ -607,12 +625,17 @@ const visitModules = (
|
|
607
625
|
const { minAvailableModules } = chunkGroupInfo;
|
608
626
|
// Buffer items because order need to be reversed to get indices correct
|
609
627
|
// Traverse all referenced modules
|
610
|
-
for (let i = 0
|
628
|
+
for (let i = 0, len = blockModules.length; i < len; i += 3) {
|
611
629
|
const refModule = /** @type {Module} */ (blockModules[i]);
|
612
|
-
|
630
|
+
// For single comparisons this might be cheaper
|
631
|
+
const isModuleInChunk = chunkGraph.isModuleInChunk(refModule, chunk);
|
632
|
+
|
633
|
+
if (isModuleInChunk) {
|
613
634
|
// skip early if already connected
|
614
635
|
continue;
|
615
636
|
}
|
637
|
+
|
638
|
+
const refOrdinal = /** @type {number} */ getModuleOrdinal(refModule);
|
616
639
|
const activeState = /** @type {ConnectionState} */ (
|
617
640
|
blockModules[i + 1]
|
618
641
|
);
|
@@ -623,12 +646,7 @@ const visitModules = (
|
|
623
646
|
skipConnectionBuffer.push([refModule, connections]);
|
624
647
|
// We skip inactive connections
|
625
648
|
if (activeState === false) continue;
|
626
|
-
}
|
627
|
-
if (
|
628
|
-
activeState === true &&
|
629
|
-
(minAvailableModules.has(refModule) ||
|
630
|
-
minAvailableModules.plus.has(refModule))
|
631
|
-
) {
|
649
|
+
} else if (isOrdinalSetInMask(minAvailableModules, refOrdinal)) {
|
632
650
|
// already in parent chunks, skip it for now
|
633
651
|
skipBuffer.push(refModule);
|
634
652
|
continue;
|
@@ -694,15 +712,15 @@ const visitModules = (
|
|
694
712
|
const blockModules = getBlockModules(block, chunkGroupInfo.runtime);
|
695
713
|
|
696
714
|
if (blockModules !== undefined) {
|
697
|
-
// Traverse all referenced modules
|
698
|
-
for (let i =
|
715
|
+
// Traverse all referenced modules in reverse order
|
716
|
+
for (let i = blockModules.length - 3; i >= 0; i -= 3) {
|
699
717
|
const refModule = /** @type {Module} */ (blockModules[i]);
|
700
718
|
const activeState = /** @type {ConnectionState} */ (
|
701
719
|
blockModules[i + 1]
|
702
720
|
);
|
703
721
|
// enqueue, then add and enter to be in the correct order
|
704
722
|
// this is relevant with circular dependencies
|
705
|
-
|
723
|
+
queue.push({
|
706
724
|
action:
|
707
725
|
activeState === true ? ADD_AND_ENTER_ENTRY_MODULE : PROCESS_BLOCK,
|
708
726
|
block: refModule,
|
@@ -712,13 +730,6 @@ const visitModules = (
|
|
712
730
|
chunkGroupInfo
|
713
731
|
});
|
714
732
|
}
|
715
|
-
// Add buffered items in reverse order
|
716
|
-
if (queueBuffer.length > 0) {
|
717
|
-
for (let i = queueBuffer.length - 1; i >= 0; i--) {
|
718
|
-
queue.push(queueBuffer[i]);
|
719
|
-
}
|
720
|
-
queueBuffer.length = 0;
|
721
|
-
}
|
722
733
|
}
|
723
734
|
|
724
735
|
// Traverse all Blocks
|
@@ -750,12 +761,18 @@ const visitModules = (
|
|
750
761
|
);
|
751
762
|
// fallthrough
|
752
763
|
case ADD_AND_ENTER_MODULE: {
|
753
|
-
|
764
|
+
const isModuleInChunk = chunkGraph.isModuleInChunk(module, chunk);
|
765
|
+
|
766
|
+
if (isModuleInChunk) {
|
754
767
|
// already connected, skip it
|
755
768
|
break;
|
756
769
|
}
|
757
770
|
// We connect Module and Chunk
|
758
771
|
chunkGraph.connectChunkAndModule(chunk, module);
|
772
|
+
const moduleOrdinal = getModuleOrdinal(module);
|
773
|
+
let chunkMask = maskByChunk.get(chunk);
|
774
|
+
chunkMask |= ONE_BIGINT << BigInt(moduleOrdinal);
|
775
|
+
maskByChunk.set(chunk, chunkMask);
|
759
776
|
}
|
760
777
|
// fallthrough
|
761
778
|
case ENTER_MODULE: {
|
@@ -812,44 +829,22 @@ const visitModules = (
|
|
812
829
|
}
|
813
830
|
};
|
814
831
|
|
832
|
+
/**
|
833
|
+
* @param {ChunkGroupInfo} chunkGroupInfo The info object for the chunk group
|
834
|
+
* @returns {bigint} The mask of available modules after the chunk group
|
835
|
+
*/
|
815
836
|
const calculateResultingAvailableModules = chunkGroupInfo => {
|
816
|
-
if (chunkGroupInfo.resultingAvailableModules)
|
837
|
+
if (chunkGroupInfo.resultingAvailableModules !== undefined)
|
817
838
|
return chunkGroupInfo.resultingAvailableModules;
|
818
839
|
|
819
|
-
|
820
|
-
|
821
|
-
// Create a new Set of available modules at this point
|
822
|
-
// We want to be as lazy as possible. There are multiple ways doing this:
|
823
|
-
// Note that resultingAvailableModules is stored as "(a) + (b)" as it's a ModuleSetPlus
|
824
|
-
// - resultingAvailableModules = (modules of chunk) + (minAvailableModules + minAvailableModules.plus)
|
825
|
-
// - resultingAvailableModules = (minAvailableModules + modules of chunk) + (minAvailableModules.plus)
|
826
|
-
// We choose one depending on the size of minAvailableModules vs minAvailableModules.plus
|
827
|
-
|
828
|
-
let resultingAvailableModules;
|
829
|
-
if (minAvailableModules.size > minAvailableModules.plus.size) {
|
830
|
-
// resultingAvailableModules = (modules of chunk) + (minAvailableModules + minAvailableModules.plus)
|
831
|
-
resultingAvailableModules =
|
832
|
-
/** @type {Set<Module> & {plus: Set<Module>}} */ (new Set());
|
833
|
-
for (const module of minAvailableModules.plus)
|
834
|
-
minAvailableModules.add(module);
|
835
|
-
minAvailableModules.plus = EMPTY_SET;
|
836
|
-
resultingAvailableModules.plus = minAvailableModules;
|
837
|
-
chunkGroupInfo.minAvailableModulesOwned = false;
|
838
|
-
} else {
|
839
|
-
// resultingAvailableModules = (minAvailableModules + modules of chunk) + (minAvailableModules.plus)
|
840
|
-
resultingAvailableModules =
|
841
|
-
/** @type {Set<Module> & {plus: Set<Module>}} */ (
|
842
|
-
new Set(minAvailableModules)
|
843
|
-
);
|
844
|
-
resultingAvailableModules.plus = minAvailableModules.plus;
|
845
|
-
}
|
840
|
+
let resultingAvailableModules = chunkGroupInfo.minAvailableModules;
|
846
841
|
|
847
842
|
// add the modules from the chunk group to the set
|
848
843
|
for (const chunk of chunkGroupInfo.chunkGroup.chunks) {
|
849
|
-
|
850
|
-
|
851
|
-
}
|
844
|
+
const mask = maskByChunk.get(chunk);
|
845
|
+
resultingAvailableModules |= mask;
|
852
846
|
}
|
847
|
+
|
853
848
|
return (chunkGroupInfo.resultingAvailableModules =
|
854
849
|
resultingAvailableModules);
|
855
850
|
};
|
@@ -896,232 +891,24 @@ const visitModules = (
|
|
896
891
|
// Execute the merge
|
897
892
|
for (const info of chunkGroupsForMerging) {
|
898
893
|
const availableModulesToBeMerged = info.availableModulesToBeMerged;
|
899
|
-
|
894
|
+
const cachedMinAvailableModules = info.minAvailableModules;
|
895
|
+
let minAvailableModules = cachedMinAvailableModules;
|
900
896
|
|
901
897
|
statMergedAvailableModuleSets += availableModulesToBeMerged.length;
|
902
898
|
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
// the list didn't shrink.
|
907
|
-
if (availableModulesToBeMerged.length > 1) {
|
908
|
-
availableModulesToBeMerged.sort(bySetSize);
|
909
|
-
}
|
910
|
-
let changed = false;
|
911
|
-
merge: for (const availableModules of availableModulesToBeMerged) {
|
912
|
-
if (cachedMinAvailableModules === undefined) {
|
913
|
-
cachedMinAvailableModules = availableModules;
|
914
|
-
info.minAvailableModules = cachedMinAvailableModules;
|
915
|
-
info.minAvailableModulesOwned = false;
|
916
|
-
changed = true;
|
899
|
+
for (const availableModules of availableModulesToBeMerged) {
|
900
|
+
if (minAvailableModules === undefined) {
|
901
|
+
minAvailableModules = availableModules;
|
917
902
|
} else {
|
918
|
-
|
919
|
-
// We own it and can modify it
|
920
|
-
if (cachedMinAvailableModules.plus === availableModules.plus) {
|
921
|
-
for (const m of cachedMinAvailableModules) {
|
922
|
-
if (!availableModules.has(m)) {
|
923
|
-
cachedMinAvailableModules.delete(m);
|
924
|
-
changed = true;
|
925
|
-
}
|
926
|
-
}
|
927
|
-
} else {
|
928
|
-
for (const m of cachedMinAvailableModules) {
|
929
|
-
if (!availableModules.has(m) && !availableModules.plus.has(m)) {
|
930
|
-
cachedMinAvailableModules.delete(m);
|
931
|
-
changed = true;
|
932
|
-
}
|
933
|
-
}
|
934
|
-
for (const m of cachedMinAvailableModules.plus) {
|
935
|
-
if (!availableModules.has(m) && !availableModules.plus.has(m)) {
|
936
|
-
// We can't remove modules from the plus part
|
937
|
-
// so we need to merge plus into the normal part to allow modifying it
|
938
|
-
const iterator =
|
939
|
-
cachedMinAvailableModules.plus[Symbol.iterator]();
|
940
|
-
// fast forward add all modules until m
|
941
|
-
/** @type {IteratorResult<Module>} */
|
942
|
-
let it;
|
943
|
-
while (!(it = iterator.next()).done) {
|
944
|
-
const module = it.value;
|
945
|
-
if (module === m) break;
|
946
|
-
cachedMinAvailableModules.add(module);
|
947
|
-
}
|
948
|
-
// check the remaining modules before adding
|
949
|
-
while (!(it = iterator.next()).done) {
|
950
|
-
const module = it.value;
|
951
|
-
if (
|
952
|
-
availableModules.has(module) ||
|
953
|
-
availableModules.plus.has(module)
|
954
|
-
) {
|
955
|
-
cachedMinAvailableModules.add(module);
|
956
|
-
}
|
957
|
-
}
|
958
|
-
cachedMinAvailableModules.plus = EMPTY_SET;
|
959
|
-
changed = true;
|
960
|
-
continue merge;
|
961
|
-
}
|
962
|
-
}
|
963
|
-
}
|
964
|
-
} else if (cachedMinAvailableModules.plus === availableModules.plus) {
|
965
|
-
// Common and fast case when the plus part is shared
|
966
|
-
// We only need to care about the normal part
|
967
|
-
if (availableModules.size < cachedMinAvailableModules.size) {
|
968
|
-
// the new availableModules is smaller so it's faster to
|
969
|
-
// fork from the new availableModules
|
970
|
-
statForkedAvailableModules++;
|
971
|
-
statForkedAvailableModulesCount += availableModules.size;
|
972
|
-
statForkedMergedModulesCount += cachedMinAvailableModules.size;
|
973
|
-
// construct a new Set as intersection of cachedMinAvailableModules and availableModules
|
974
|
-
const newSet = /** @type {ModuleSetPlus} */ (new Set());
|
975
|
-
newSet.plus = availableModules.plus;
|
976
|
-
for (const m of availableModules) {
|
977
|
-
if (cachedMinAvailableModules.has(m)) {
|
978
|
-
newSet.add(m);
|
979
|
-
}
|
980
|
-
}
|
981
|
-
statForkedResultModulesCount += newSet.size;
|
982
|
-
cachedMinAvailableModules = newSet;
|
983
|
-
info.minAvailableModulesOwned = true;
|
984
|
-
info.minAvailableModules = newSet;
|
985
|
-
changed = true;
|
986
|
-
continue merge;
|
987
|
-
}
|
988
|
-
for (const m of cachedMinAvailableModules) {
|
989
|
-
if (!availableModules.has(m)) {
|
990
|
-
// cachedMinAvailableModules need to be modified
|
991
|
-
// but we don't own it
|
992
|
-
statForkedAvailableModules++;
|
993
|
-
statForkedAvailableModulesCount +=
|
994
|
-
cachedMinAvailableModules.size;
|
995
|
-
statForkedMergedModulesCount += availableModules.size;
|
996
|
-
// construct a new Set as intersection of cachedMinAvailableModules and availableModules
|
997
|
-
// as the plus part is equal we can just take over this one
|
998
|
-
const newSet = /** @type {ModuleSetPlus} */ (new Set());
|
999
|
-
newSet.plus = availableModules.plus;
|
1000
|
-
const iterator = cachedMinAvailableModules[Symbol.iterator]();
|
1001
|
-
// fast forward add all modules until m
|
1002
|
-
/** @type {IteratorResult<Module>} */
|
1003
|
-
let it;
|
1004
|
-
while (!(it = iterator.next()).done) {
|
1005
|
-
const module = it.value;
|
1006
|
-
if (module === m) break;
|
1007
|
-
newSet.add(module);
|
1008
|
-
}
|
1009
|
-
// check the remaining modules before adding
|
1010
|
-
while (!(it = iterator.next()).done) {
|
1011
|
-
const module = it.value;
|
1012
|
-
if (availableModules.has(module)) {
|
1013
|
-
newSet.add(module);
|
1014
|
-
}
|
1015
|
-
}
|
1016
|
-
statForkedResultModulesCount += newSet.size;
|
1017
|
-
cachedMinAvailableModules = newSet;
|
1018
|
-
info.minAvailableModulesOwned = true;
|
1019
|
-
info.minAvailableModules = newSet;
|
1020
|
-
changed = true;
|
1021
|
-
continue merge;
|
1022
|
-
}
|
1023
|
-
}
|
1024
|
-
} else {
|
1025
|
-
for (const m of cachedMinAvailableModules) {
|
1026
|
-
if (!availableModules.has(m) && !availableModules.plus.has(m)) {
|
1027
|
-
// cachedMinAvailableModules need to be modified
|
1028
|
-
// but we don't own it
|
1029
|
-
statForkedAvailableModules++;
|
1030
|
-
statForkedAvailableModulesCount +=
|
1031
|
-
cachedMinAvailableModules.size;
|
1032
|
-
statForkedAvailableModulesCountPlus +=
|
1033
|
-
cachedMinAvailableModules.plus.size;
|
1034
|
-
statForkedMergedModulesCount += availableModules.size;
|
1035
|
-
statForkedMergedModulesCountPlus += availableModules.plus.size;
|
1036
|
-
// construct a new Set as intersection of cachedMinAvailableModules and availableModules
|
1037
|
-
const newSet = /** @type {ModuleSetPlus} */ (new Set());
|
1038
|
-
newSet.plus = EMPTY_SET;
|
1039
|
-
const iterator = cachedMinAvailableModules[Symbol.iterator]();
|
1040
|
-
// fast forward add all modules until m
|
1041
|
-
/** @type {IteratorResult<Module>} */
|
1042
|
-
let it;
|
1043
|
-
while (!(it = iterator.next()).done) {
|
1044
|
-
const module = it.value;
|
1045
|
-
if (module === m) break;
|
1046
|
-
newSet.add(module);
|
1047
|
-
}
|
1048
|
-
// check the remaining modules before adding
|
1049
|
-
while (!(it = iterator.next()).done) {
|
1050
|
-
const module = it.value;
|
1051
|
-
if (
|
1052
|
-
availableModules.has(module) ||
|
1053
|
-
availableModules.plus.has(module)
|
1054
|
-
) {
|
1055
|
-
newSet.add(module);
|
1056
|
-
}
|
1057
|
-
}
|
1058
|
-
// also check all modules in cachedMinAvailableModules.plus
|
1059
|
-
for (const module of cachedMinAvailableModules.plus) {
|
1060
|
-
if (
|
1061
|
-
availableModules.has(module) ||
|
1062
|
-
availableModules.plus.has(module)
|
1063
|
-
) {
|
1064
|
-
newSet.add(module);
|
1065
|
-
}
|
1066
|
-
}
|
1067
|
-
statForkedResultModulesCount += newSet.size;
|
1068
|
-
cachedMinAvailableModules = newSet;
|
1069
|
-
info.minAvailableModulesOwned = true;
|
1070
|
-
info.minAvailableModules = newSet;
|
1071
|
-
changed = true;
|
1072
|
-
continue merge;
|
1073
|
-
}
|
1074
|
-
}
|
1075
|
-
for (const m of cachedMinAvailableModules.plus) {
|
1076
|
-
if (!availableModules.has(m) && !availableModules.plus.has(m)) {
|
1077
|
-
// cachedMinAvailableModules need to be modified
|
1078
|
-
// but we don't own it
|
1079
|
-
statForkedAvailableModules++;
|
1080
|
-
statForkedAvailableModulesCount +=
|
1081
|
-
cachedMinAvailableModules.size;
|
1082
|
-
statForkedAvailableModulesCountPlus +=
|
1083
|
-
cachedMinAvailableModules.plus.size;
|
1084
|
-
statForkedMergedModulesCount += availableModules.size;
|
1085
|
-
statForkedMergedModulesCountPlus += availableModules.plus.size;
|
1086
|
-
// construct a new Set as intersection of cachedMinAvailableModules and availableModules
|
1087
|
-
// we already know that all modules directly from cachedMinAvailableModules are in availableModules too
|
1088
|
-
const newSet = /** @type {ModuleSetPlus} */ (
|
1089
|
-
new Set(cachedMinAvailableModules)
|
1090
|
-
);
|
1091
|
-
newSet.plus = EMPTY_SET;
|
1092
|
-
const iterator =
|
1093
|
-
cachedMinAvailableModules.plus[Symbol.iterator]();
|
1094
|
-
// fast forward add all modules until m
|
1095
|
-
/** @type {IteratorResult<Module>} */
|
1096
|
-
let it;
|
1097
|
-
while (!(it = iterator.next()).done) {
|
1098
|
-
const module = it.value;
|
1099
|
-
if (module === m) break;
|
1100
|
-
newSet.add(module);
|
1101
|
-
}
|
1102
|
-
// check the remaining modules before adding
|
1103
|
-
while (!(it = iterator.next()).done) {
|
1104
|
-
const module = it.value;
|
1105
|
-
if (
|
1106
|
-
availableModules.has(module) ||
|
1107
|
-
availableModules.plus.has(module)
|
1108
|
-
) {
|
1109
|
-
newSet.add(module);
|
1110
|
-
}
|
1111
|
-
}
|
1112
|
-
statForkedResultModulesCount += newSet.size;
|
1113
|
-
cachedMinAvailableModules = newSet;
|
1114
|
-
info.minAvailableModulesOwned = true;
|
1115
|
-
info.minAvailableModules = newSet;
|
1116
|
-
changed = true;
|
1117
|
-
continue merge;
|
1118
|
-
}
|
1119
|
-
}
|
1120
|
-
}
|
903
|
+
minAvailableModules &= availableModules;
|
1121
904
|
}
|
1122
905
|
}
|
906
|
+
|
907
|
+
const changed = minAvailableModules !== cachedMinAvailableModules;
|
908
|
+
|
1123
909
|
availableModulesToBeMerged.length = 0;
|
1124
910
|
if (changed) {
|
911
|
+
info.minAvailableModules = minAvailableModules;
|
1125
912
|
info.resultingAvailableModules = undefined;
|
1126
913
|
outdatedChunkGroupInfo.add(info);
|
1127
914
|
}
|
@@ -1134,34 +921,24 @@ const visitModules = (
|
|
1134
921
|
for (const source of /** @type {Set<ChunkGroupInfo>} */ (
|
1135
922
|
info.availableSources
|
1136
923
|
)) {
|
1137
|
-
if (
|
924
|
+
if (source.minAvailableModules === undefined) {
|
1138
925
|
chunkGroupsForCombining.delete(info);
|
1139
926
|
break;
|
1140
927
|
}
|
1141
928
|
}
|
1142
929
|
}
|
930
|
+
|
1143
931
|
for (const info of chunkGroupsForCombining) {
|
1144
|
-
|
1145
|
-
availableModules.plus = EMPTY_SET;
|
1146
|
-
const mergeSet = set => {
|
1147
|
-
if (set.size > availableModules.plus.size) {
|
1148
|
-
for (const item of availableModules.plus) availableModules.add(item);
|
1149
|
-
availableModules.plus = set;
|
1150
|
-
} else {
|
1151
|
-
for (const item of set) availableModules.add(item);
|
1152
|
-
}
|
1153
|
-
};
|
932
|
+
let availableModules = ZERO_BIGINT;
|
1154
933
|
// combine minAvailableModules from all resultingAvailableModules
|
1155
934
|
for (const source of /** @type {Set<ChunkGroupInfo>} */ (
|
1156
935
|
info.availableSources
|
1157
936
|
)) {
|
1158
937
|
const resultingAvailableModules =
|
1159
938
|
calculateResultingAvailableModules(source);
|
1160
|
-
|
1161
|
-
mergeSet(resultingAvailableModules.plus);
|
939
|
+
availableModules |= resultingAvailableModules;
|
1162
940
|
}
|
1163
941
|
info.minAvailableModules = availableModules;
|
1164
|
-
info.minAvailableModulesOwned = false;
|
1165
942
|
info.resultingAvailableModules = undefined;
|
1166
943
|
outdatedChunkGroupInfo.add(info);
|
1167
944
|
}
|
@@ -1175,13 +952,11 @@ const visitModules = (
|
|
1175
952
|
// 1. Reconsider skipped items
|
1176
953
|
if (info.skippedItems !== undefined) {
|
1177
954
|
const minAvailableModules =
|
1178
|
-
/** @type {
|
955
|
+
/** @type {bigint} */
|
1179
956
|
(info.minAvailableModules);
|
1180
957
|
for (const module of info.skippedItems) {
|
1181
|
-
|
1182
|
-
|
1183
|
-
!minAvailableModules.plus.has(module)
|
1184
|
-
) {
|
958
|
+
const ordinal = getModuleOrdinal(module);
|
959
|
+
if (!isOrdinalSetInMask(minAvailableModules, ordinal)) {
|
1185
960
|
queue.push({
|
1186
961
|
action: ADD_AND_ENTER_MODULE,
|
1187
962
|
block: module,
|
@@ -1198,7 +973,7 @@ const visitModules = (
|
|
1198
973
|
// 2. Reconsider skipped connections
|
1199
974
|
if (info.skippedModuleConnections !== undefined) {
|
1200
975
|
const minAvailableModules =
|
1201
|
-
/** @type {
|
976
|
+
/** @type {bigint} */
|
1202
977
|
(info.minAvailableModules);
|
1203
978
|
for (const entry of info.skippedModuleConnections) {
|
1204
979
|
const [module, connections] = entry;
|
@@ -1208,15 +983,12 @@ const visitModules = (
|
|
1208
983
|
);
|
1209
984
|
if (activeState === false) continue;
|
1210
985
|
if (activeState === true) {
|
986
|
+
const ordinal = getModuleOrdinal(module);
|
1211
987
|
info.skippedModuleConnections.delete(entry);
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
minAvailableModules.plus.has(module))
|
1217
|
-
) {
|
1218
|
-
info.skippedItems.add(module);
|
1219
|
-
continue;
|
988
|
+
if (isOrdinalSetInMask(minAvailableModules, ordinal)) {
|
989
|
+
info.skippedItems.add(module);
|
990
|
+
continue;
|
991
|
+
}
|
1220
992
|
}
|
1221
993
|
queue.push({
|
1222
994
|
action: activeState === true ? ADD_AND_ENTER_MODULE : PROCESS_BLOCK,
|
@@ -1307,7 +1079,7 @@ const visitModules = (
|
|
1307
1079
|
let preOrderIndex = 0;
|
1308
1080
|
let postOrderIndex = 0;
|
1309
1081
|
|
1310
|
-
const process = (current, visited
|
1082
|
+
const process = (current, visited) => {
|
1311
1083
|
if (visited.has(current)) {
|
1312
1084
|
return;
|
1313
1085
|
}
|
@@ -1319,14 +1091,14 @@ const visitModules = (
|
|
1319
1091
|
return;
|
1320
1092
|
}
|
1321
1093
|
|
1322
|
-
for (let i = 0
|
1323
|
-
const refModule = /** @type {Module} */ (blockModules[i]);
|
1094
|
+
for (let i = 0, len = blockModules.length; i < len; i += 3) {
|
1324
1095
|
const activeState = /** @type {ConnectionState} */ (
|
1325
1096
|
blockModules[i + 1]
|
1326
1097
|
);
|
1327
1098
|
if (activeState === false) {
|
1328
1099
|
continue;
|
1329
1100
|
}
|
1101
|
+
const refModule = /** @type {Module} */ (blockModules[i]);
|
1330
1102
|
|
1331
1103
|
if (refModule) {
|
1332
1104
|
chunkGroup.setModulePreOrderIndex(refModule, preOrderIndex++);
|
@@ -1336,9 +1108,10 @@ const visitModules = (
|
|
1336
1108
|
}
|
1337
1109
|
};
|
1338
1110
|
|
1339
|
-
process(block);
|
1111
|
+
process(block, new Set());
|
1340
1112
|
}
|
1341
1113
|
outdatedOrderIndexChunkGroups.clear();
|
1114
|
+
ordinalByModule.clear();
|
1342
1115
|
|
1343
1116
|
logger.log(
|
1344
1117
|
`${statProcessedQueueItems} queue items processed (${statProcessedBlocks} blocks)`
|
@@ -1357,13 +1130,13 @@ const visitModules = (
|
|
1357
1130
|
* @param {Compilation} compilation the compilation
|
1358
1131
|
* @param {Set<DependenciesBlock>} blocksWithNestedBlocks flag for blocks that have nested blocks
|
1359
1132
|
* @param {Map<AsyncDependenciesBlock, BlockChunkGroupConnection[]>} blockConnections connection for blocks
|
1360
|
-
* @param {Map<
|
1133
|
+
* @param {Map<Chunk, bigint>} maskByChunk mapping from chunk to module mask
|
1361
1134
|
*/
|
1362
1135
|
const connectChunkGroups = (
|
1363
1136
|
compilation,
|
1364
1137
|
blocksWithNestedBlocks,
|
1365
1138
|
blockConnections,
|
1366
|
-
|
1139
|
+
maskByChunk
|
1367
1140
|
) => {
|
1368
1141
|
const { chunkGraph } = compilation;
|
1369
1142
|
|
@@ -1371,15 +1144,13 @@ const connectChunkGroups = (
|
|
1371
1144
|
* Helper function to check if all modules of a chunk are available
|
1372
1145
|
*
|
1373
1146
|
* @param {ChunkGroup} chunkGroup the chunkGroup to scan
|
1374
|
-
* @param {
|
1147
|
+
* @param {bigint} availableModules the comparator set
|
1375
1148
|
* @returns {boolean} return true if all modules of a chunk are available
|
1376
1149
|
*/
|
1377
1150
|
const areModulesAvailable = (chunkGroup, availableModules) => {
|
1378
1151
|
for (const chunk of chunkGroup.chunks) {
|
1379
|
-
|
1380
|
-
|
1381
|
-
return false;
|
1382
|
-
}
|
1152
|
+
const chunkMask = maskByChunk.get(chunk);
|
1153
|
+
if ((chunkMask & availableModules) !== chunkMask) return false;
|
1383
1154
|
}
|
1384
1155
|
return true;
|
1385
1156
|
};
|
@@ -1464,6 +1235,9 @@ const buildChunkGraph = (compilation, inputEntrypointsAndModules) => {
|
|
1464
1235
|
/** @type {Set<DependenciesBlock>} */
|
1465
1236
|
const blocksWithNestedBlocks = new Set();
|
1466
1237
|
|
1238
|
+
/** @type {Map<Chunk, bigint>} */
|
1239
|
+
const maskByChunk = new Map();
|
1240
|
+
|
1467
1241
|
// PART ONE
|
1468
1242
|
|
1469
1243
|
logger.time("visitModules");
|
@@ -1474,7 +1248,8 @@ const buildChunkGraph = (compilation, inputEntrypointsAndModules) => {
|
|
1474
1248
|
chunkGroupInfoMap,
|
1475
1249
|
blockConnections,
|
1476
1250
|
blocksWithNestedBlocks,
|
1477
|
-
allCreatedChunkGroups
|
1251
|
+
allCreatedChunkGroups,
|
1252
|
+
maskByChunk
|
1478
1253
|
);
|
1479
1254
|
logger.timeEnd("visitModules");
|
1480
1255
|
|
@@ -1485,7 +1260,7 @@ const buildChunkGraph = (compilation, inputEntrypointsAndModules) => {
|
|
1485
1260
|
compilation,
|
1486
1261
|
blocksWithNestedBlocks,
|
1487
1262
|
blockConnections,
|
1488
|
-
|
1263
|
+
maskByChunk
|
1489
1264
|
);
|
1490
1265
|
logger.timeEnd("connectChunkGroups");
|
1491
1266
|
|