webpack 5.57.1 → 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.
- package/lib/AsyncDependenciesBlock.js +0 -2
- package/lib/ChunkCombination.js +187 -0
- package/lib/ChunkGraph.js +30 -42
- package/lib/Compilation.js +49 -8
- package/lib/DependenciesBlock.js +9 -0
- package/lib/Dependency.js +2 -0
- package/lib/Module.js +4 -0
- package/lib/ModuleGraph.js +11 -17
- package/lib/NormalModule.js +33 -16
- package/lib/buildChunkGraph.js +157 -100
- package/lib/logging/Logger.js +1 -0
- package/lib/node/NodeTargetPlugin.js +1 -0
- package/lib/optimize/EnsureChunkConditionsPlugin.js +1 -0
- package/lib/optimize/SplitChunksPlugin.js +135 -235
- package/lib/schemes/FileUriPlugin.js +9 -0
- package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +6 -1
- package/package.json +1 -1
- package/types.d.ts +20 -2
@@ -5,11 +5,10 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
-
const
|
8
|
+
const ChunkCombination = require("../ChunkCombination");
|
9
9
|
const { STAGE_ADVANCED } = require("../OptimizationStages");
|
10
10
|
const WebpackError = require("../WebpackError");
|
11
11
|
const { requestToId } = require("../ids/IdHelpers");
|
12
|
-
const { isSubset } = require("../util/SetHelpers");
|
13
12
|
const SortableSet = require("../util/SortableSet");
|
14
13
|
const {
|
15
14
|
compareModulesByIdentifier,
|
@@ -26,6 +25,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
|
|
26
25
|
/** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksOptions} OptimizationSplitChunksOptions */
|
27
26
|
/** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksSizes} OptimizationSplitChunksSizes */
|
28
27
|
/** @typedef {import("../../declarations/WebpackOptions").Output} OutputOptions */
|
28
|
+
/** @typedef {import("../Chunk")} Chunk */
|
29
29
|
/** @typedef {import("../ChunkGraph")} ChunkGraph */
|
30
30
|
/** @typedef {import("../ChunkGroup")} ChunkGroup */
|
31
31
|
/** @typedef {import("../Compilation").AssetInfo} AssetInfo */
|
@@ -155,9 +155,9 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
|
|
155
155
|
* @property {number} cacheGroupIndex
|
156
156
|
* @property {string} name
|
157
157
|
* @property {Record<string, number>} sizes
|
158
|
-
* @property {
|
158
|
+
* @property {ChunkCombination} chunks
|
159
159
|
* @property {Set<Chunk>} reuseableChunks
|
160
|
-
* @property {Set<
|
160
|
+
* @property {Set<ChunkCombination>} chunkCombinations
|
161
161
|
*/
|
162
162
|
|
163
163
|
const defaultGetName = /** @type {GetName} */ (() => {});
|
@@ -204,19 +204,6 @@ const mapObject = (obj, fn) => {
|
|
204
204
|
return newObj;
|
205
205
|
};
|
206
206
|
|
207
|
-
/**
|
208
|
-
* @template T
|
209
|
-
* @param {Set<T>} a set
|
210
|
-
* @param {Set<T>} b other set
|
211
|
-
* @returns {boolean} true if at least one item of a is in b
|
212
|
-
*/
|
213
|
-
const isOverlap = (a, b) => {
|
214
|
-
for (const item of a) {
|
215
|
-
if (b.has(item)) return true;
|
216
|
-
}
|
217
|
-
return false;
|
218
|
-
};
|
219
|
-
|
220
207
|
const compareModuleIterables = compareIterables(compareModulesByIdentifier);
|
221
208
|
|
222
209
|
/**
|
@@ -769,207 +756,132 @@ module.exports = class SplitChunksPlugin {
|
|
769
756
|
logger.time("prepare");
|
770
757
|
const chunkGraph = compilation.chunkGraph;
|
771
758
|
const moduleGraph = compilation.moduleGraph;
|
772
|
-
// Give each selected chunk an index (to create strings from chunks)
|
773
|
-
/** @type {Map<Chunk, bigint>} */
|
774
|
-
const chunkIndexMap = new Map();
|
775
|
-
const ZERO = BigInt("0");
|
776
|
-
const ONE = BigInt("1");
|
777
|
-
let index = ONE;
|
778
|
-
for (const chunk of chunks) {
|
779
|
-
chunkIndexMap.set(chunk, index);
|
780
|
-
index = index << ONE;
|
781
|
-
}
|
782
|
-
/**
|
783
|
-
* @param {Iterable<Chunk>} chunks list of chunks
|
784
|
-
* @returns {bigint | Chunk} key of the chunks
|
785
|
-
*/
|
786
|
-
const getKey = chunks => {
|
787
|
-
const iterator = chunks[Symbol.iterator]();
|
788
|
-
let result = iterator.next();
|
789
|
-
if (result.done) return ZERO;
|
790
|
-
const first = result.value;
|
791
|
-
result = iterator.next();
|
792
|
-
if (result.done) return first;
|
793
|
-
let key =
|
794
|
-
chunkIndexMap.get(first) | chunkIndexMap.get(result.value);
|
795
|
-
while (!(result = iterator.next()).done) {
|
796
|
-
key = key | chunkIndexMap.get(result.value);
|
797
|
-
}
|
798
|
-
return key;
|
799
|
-
};
|
800
|
-
const keyToString = key => {
|
801
|
-
if (typeof key === "bigint") return key.toString(16);
|
802
|
-
return chunkIndexMap.get(key).toString(16);
|
803
|
-
};
|
804
759
|
|
805
|
-
const
|
806
|
-
/** @type {
|
807
|
-
const
|
808
|
-
/** @type {Set<Chunk>} */
|
809
|
-
const singleChunkSets = new Set();
|
760
|
+
const getChunkCombinationsInGraph = memoize(() => {
|
761
|
+
/** @type {Set<ChunkCombination>} */
|
762
|
+
const chunkCombinationsInGraph = new Set();
|
810
763
|
for (const module of compilation.modules) {
|
811
|
-
const
|
812
|
-
|
813
|
-
|
814
|
-
if (!chunkSetsInGraph.has(chunksKey)) {
|
815
|
-
chunkSetsInGraph.set(chunksKey, new Set(chunks));
|
816
|
-
}
|
817
|
-
} else {
|
818
|
-
singleChunkSets.add(chunksKey);
|
819
|
-
}
|
764
|
+
const chunkCombination =
|
765
|
+
chunkGraph.getModuleChunkCombination(module);
|
766
|
+
chunkCombinationsInGraph.add(chunkCombination);
|
820
767
|
}
|
821
|
-
return
|
768
|
+
return chunkCombinationsInGraph;
|
822
769
|
});
|
823
770
|
|
824
771
|
/**
|
825
772
|
* @param {Module} module the module
|
826
|
-
* @returns {Iterable<
|
773
|
+
* @returns {Iterable<ChunkCombination>} groups of chunks with equal exports
|
827
774
|
*/
|
828
775
|
const groupChunksByExports = module => {
|
829
776
|
const exportsInfo = moduleGraph.getExportsInfo(module);
|
830
777
|
const groupedByUsedExports = new Map();
|
831
778
|
for (const chunk of chunkGraph.getModuleChunksIterable(module)) {
|
832
779
|
const key = exportsInfo.getUsageKey(chunk.runtime);
|
833
|
-
const
|
834
|
-
|
835
|
-
|
836
|
-
} else {
|
837
|
-
groupedByUsedExports.set(key, [chunk]);
|
838
|
-
}
|
780
|
+
const combination =
|
781
|
+
groupedByUsedExports.get(key) || ChunkCombination.empty;
|
782
|
+
groupedByUsedExports.set(key, combination.with(chunk));
|
839
783
|
}
|
840
784
|
return groupedByUsedExports.values();
|
841
785
|
};
|
842
786
|
|
843
|
-
/** @type {Map<Module, Iterable<
|
787
|
+
/** @type {Map<Module, Iterable<ChunkCombination>>} */
|
844
788
|
const groupedByExportsMap = new Map();
|
845
789
|
|
846
|
-
const
|
847
|
-
/** @type {
|
848
|
-
const
|
849
|
-
/** @type {Set<Chunk>} */
|
850
|
-
const singleChunkSets = new Set();
|
790
|
+
const getExportsChunkCombinationsInGraph = memoize(() => {
|
791
|
+
/** @type {Set<ChunkCombination>} */
|
792
|
+
const chunkCombinationsInGraph = new Set();
|
851
793
|
for (const module of compilation.modules) {
|
852
794
|
const groupedChunks = Array.from(groupChunksByExports(module));
|
853
795
|
groupedByExportsMap.set(module, groupedChunks);
|
854
|
-
for (const
|
855
|
-
|
856
|
-
singleChunkSets.add(chunks[0]);
|
857
|
-
} else {
|
858
|
-
const chunksKey = /** @type {bigint} */ (getKey(chunks));
|
859
|
-
if (!chunkSetsInGraph.has(chunksKey)) {
|
860
|
-
chunkSetsInGraph.set(chunksKey, new Set(chunks));
|
861
|
-
}
|
862
|
-
}
|
796
|
+
for (const chunkCombination of groupedChunks) {
|
797
|
+
chunkCombinationsInGraph.add(chunkCombination);
|
863
798
|
}
|
864
799
|
}
|
865
|
-
return
|
800
|
+
return chunkCombinationsInGraph;
|
866
801
|
});
|
867
802
|
|
868
803
|
// group these set of chunks by count
|
869
804
|
// to allow to check less sets via isSubset
|
870
805
|
// (only smaller sets can be subset)
|
871
|
-
const
|
872
|
-
/** @type {Map<number,
|
873
|
-
const
|
874
|
-
for (const chunksSet of
|
806
|
+
const groupChunkCombinationsByCount = chunkCombinations => {
|
807
|
+
/** @type {Map<number, ChunkCombination[]>} */
|
808
|
+
const chunkCombinationsByCount = new Map();
|
809
|
+
for (const chunksSet of chunkCombinations) {
|
875
810
|
const count = chunksSet.size;
|
876
|
-
let array =
|
811
|
+
let array = chunkCombinationsByCount.get(count);
|
877
812
|
if (array === undefined) {
|
878
813
|
array = [];
|
879
|
-
|
814
|
+
chunkCombinationsByCount.set(count, array);
|
880
815
|
}
|
881
816
|
array.push(chunksSet);
|
882
817
|
}
|
883
|
-
return
|
818
|
+
return chunkCombinationsByCount;
|
884
819
|
};
|
885
|
-
const
|
886
|
-
|
887
|
-
getChunkSetsInGraph().chunkSetsInGraph.values()
|
888
|
-
)
|
820
|
+
const getChunkCombinationsByCount = memoize(() =>
|
821
|
+
groupChunkCombinationsByCount(getChunkCombinationsInGraph())
|
889
822
|
);
|
890
|
-
const
|
891
|
-
|
892
|
-
getExportsChunkSetsInGraph().chunkSetsInGraph.values()
|
893
|
-
)
|
823
|
+
const getExportsChunkCombinationsByCount = memoize(() =>
|
824
|
+
groupChunkCombinationsByCount(getExportsChunkCombinationsInGraph())
|
894
825
|
);
|
895
826
|
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
/** @type {Map<
|
827
|
+
/**
|
828
|
+
* Create a list of possible combinations
|
829
|
+
* @param {Map<number, ChunkCombination[]>} chunkCombinationsByCount by count
|
830
|
+
* @returns {function(ChunkCombination): ChunkCombination[]} get combinations function
|
831
|
+
*/
|
832
|
+
const createGetCombinations = chunkCombinationsByCount => {
|
833
|
+
/** @type {Map<ChunkCombination, ChunkCombination[]>} */
|
903
834
|
const combinationsCache = new Map();
|
904
835
|
|
905
|
-
|
906
|
-
|
836
|
+
/**
|
837
|
+
* @param {ChunkCombination} chunkCombination chunkCombination
|
838
|
+
* @returns {ChunkCombination[]} combinations
|
839
|
+
*/
|
840
|
+
return chunkCombination => {
|
841
|
+
const cacheEntry = combinationsCache.get(chunkCombination);
|
907
842
|
if (cacheEntry !== undefined) return cacheEntry;
|
908
|
-
if (
|
909
|
-
const result = [
|
910
|
-
combinationsCache.set(
|
843
|
+
if (chunkCombination.size === 1) {
|
844
|
+
const result = [chunkCombination];
|
845
|
+
combinationsCache.set(chunkCombination, result);
|
911
846
|
return result;
|
912
847
|
}
|
913
|
-
|
914
|
-
|
915
|
-
const
|
916
|
-
for (const [count, setArray] of chunkSetsByCount) {
|
848
|
+
/** @type {ChunkCombination[]} */
|
849
|
+
const array = [chunkCombination];
|
850
|
+
for (const [count, setArray] of chunkCombinationsByCount) {
|
917
851
|
// "equal" is not needed because they would have been merge in the first step
|
918
|
-
if (count <
|
852
|
+
if (count < chunkCombination.size) {
|
919
853
|
for (const set of setArray) {
|
920
|
-
if (isSubset(
|
854
|
+
if (chunkCombination.isSubset(set)) {
|
921
855
|
array.push(set);
|
922
856
|
}
|
923
857
|
}
|
924
858
|
}
|
925
859
|
}
|
926
|
-
|
927
|
-
if (chunksSet.has(chunk)) {
|
928
|
-
array.push(chunk);
|
929
|
-
}
|
930
|
-
}
|
931
|
-
combinationsCache.set(key, array);
|
860
|
+
combinationsCache.set(chunkCombination, array);
|
932
861
|
return array;
|
933
862
|
};
|
934
863
|
};
|
935
864
|
|
936
865
|
const getCombinationsFactory = memoize(() => {
|
937
|
-
|
938
|
-
return createGetCombinations(
|
939
|
-
chunkSetsInGraph,
|
940
|
-
singleChunkSets,
|
941
|
-
getChunkSetsByCount()
|
942
|
-
);
|
866
|
+
return createGetCombinations(getChunkCombinationsByCount());
|
943
867
|
});
|
944
868
|
const getCombinations = key => getCombinationsFactory()(key);
|
945
869
|
|
946
870
|
const getExportsCombinationsFactory = memoize(() => {
|
947
|
-
|
948
|
-
getExportsChunkSetsInGraph();
|
949
|
-
return createGetCombinations(
|
950
|
-
chunkSetsInGraph,
|
951
|
-
singleChunkSets,
|
952
|
-
getExportsChunkSetsByCount()
|
953
|
-
);
|
871
|
+
return createGetCombinations(getExportsChunkCombinationsByCount());
|
954
872
|
});
|
955
873
|
const getExportsCombinations = key =>
|
956
874
|
getExportsCombinationsFactory()(key);
|
957
875
|
|
958
|
-
/**
|
959
|
-
* @typedef {Object} SelectedChunksResult
|
960
|
-
* @property {Chunk[]} chunks the list of chunks
|
961
|
-
* @property {bigint | Chunk} key a key of the list
|
962
|
-
*/
|
963
|
-
|
964
|
-
/** @type {WeakMap<Set<Chunk> | Chunk, WeakMap<ChunkFilterFunction, SelectedChunksResult>>} */
|
876
|
+
/** @type {WeakMap<ChunkCombination, WeakMap<ChunkFilterFunction, ChunkCombination>>} */
|
965
877
|
const selectedChunksCacheByChunksSet = new WeakMap();
|
966
878
|
|
967
879
|
/**
|
968
|
-
* get
|
880
|
+
* get chunks by applying the filter function to the list
|
969
881
|
* It is cached for performance reasons
|
970
|
-
* @param {
|
882
|
+
* @param {ChunkCombination} chunks list of chunks
|
971
883
|
* @param {ChunkFilterFunction} chunkFilter filter function for chunks
|
972
|
-
* @returns {
|
884
|
+
* @returns {ChunkCombination} selected chunks
|
973
885
|
*/
|
974
886
|
const getSelectedChunks = (chunks, chunkFilter) => {
|
975
887
|
let entry = selectedChunksCacheByChunksSet.get(chunks);
|
@@ -977,22 +889,16 @@ module.exports = class SplitChunksPlugin {
|
|
977
889
|
entry = new WeakMap();
|
978
890
|
selectedChunksCacheByChunksSet.set(chunks, entry);
|
979
891
|
}
|
980
|
-
/** @type {
|
892
|
+
/** @type {ChunkCombination} */
|
981
893
|
let entry2 = entry.get(chunkFilter);
|
982
894
|
if (entry2 === undefined) {
|
983
|
-
/** @type {
|
984
|
-
|
985
|
-
|
986
|
-
if (chunkFilter(
|
987
|
-
|
988
|
-
for (const chunk of chunks) {
|
989
|
-
if (chunkFilter(chunk)) selectedChunks.push(chunk);
|
990
|
-
}
|
895
|
+
/** @type {ChunkCombination} */
|
896
|
+
let selectedChunks = ChunkCombination.empty;
|
897
|
+
for (const chunk of chunks.chunksIterable) {
|
898
|
+
if (chunkFilter(chunk))
|
899
|
+
selectedChunks = selectedChunks.with(chunk);
|
991
900
|
}
|
992
|
-
entry2 =
|
993
|
-
chunks: selectedChunks,
|
994
|
-
key: getKey(selectedChunks)
|
995
|
-
};
|
901
|
+
entry2 = selectedChunks;
|
996
902
|
entry.set(chunkFilter, entry2);
|
997
903
|
}
|
998
904
|
return entry2;
|
@@ -1011,8 +917,7 @@ module.exports = class SplitChunksPlugin {
|
|
1011
917
|
/**
|
1012
918
|
* @param {CacheGroup} cacheGroup the current cache group
|
1013
919
|
* @param {number} cacheGroupIndex the index of the cache group of ordering
|
1014
|
-
* @param {
|
1015
|
-
* @param {bigint | Chunk} selectedChunksKey a key of selectedChunks
|
920
|
+
* @param {ChunkCombination} selectedChunks chunks selected for this module
|
1016
921
|
* @param {Module} module the current module
|
1017
922
|
* @returns {void}
|
1018
923
|
*/
|
@@ -1020,25 +925,20 @@ module.exports = class SplitChunksPlugin {
|
|
1020
925
|
cacheGroup,
|
1021
926
|
cacheGroupIndex,
|
1022
927
|
selectedChunks,
|
1023
|
-
selectedChunksKey,
|
1024
928
|
module
|
1025
929
|
) => {
|
1026
930
|
// Break if minimum number of chunks is not reached
|
1027
|
-
if (selectedChunks.
|
931
|
+
if (selectedChunks.size < cacheGroup.minChunks) return;
|
1028
932
|
// Determine name for split chunk
|
1029
933
|
const name = cacheGroup.getName(
|
1030
934
|
module,
|
1031
|
-
selectedChunks,
|
935
|
+
selectedChunks.getChunks(),
|
1032
936
|
cacheGroup.key
|
1033
937
|
);
|
1034
938
|
// Check if the name is ok
|
1035
939
|
const existingChunk = compilation.namedChunks.get(name);
|
1036
940
|
if (existingChunk) {
|
1037
|
-
const parentValidationKey = `${name}|${
|
1038
|
-
typeof selectedChunksKey === "bigint"
|
1039
|
-
? selectedChunksKey
|
1040
|
-
: selectedChunksKey.debugId
|
1041
|
-
}`;
|
941
|
+
const parentValidationKey = `${name}|${selectedChunks.debugId}`;
|
1042
942
|
const valid = alreadyValidatedParents.get(parentValidationKey);
|
1043
943
|
if (valid === false) return;
|
1044
944
|
if (valid === undefined) {
|
@@ -1047,7 +947,7 @@ module.exports = class SplitChunksPlugin {
|
|
1047
947
|
let isInAllParents = true;
|
1048
948
|
/** @type {Set<ChunkGroup>} */
|
1049
949
|
const queue = new Set();
|
1050
|
-
for (const chunk of selectedChunks) {
|
950
|
+
for (const chunk of selectedChunks.chunksIterable) {
|
1051
951
|
for (const group of chunk.groupsIterable) {
|
1052
952
|
queue.add(group);
|
1053
953
|
}
|
@@ -1093,9 +993,7 @@ module.exports = class SplitChunksPlugin {
|
|
1093
993
|
// This automatically merges equal names
|
1094
994
|
const key =
|
1095
995
|
cacheGroup.key +
|
1096
|
-
(name
|
1097
|
-
? ` name:${name}`
|
1098
|
-
: ` chunks:${keyToString(selectedChunksKey)}`);
|
996
|
+
(name ? ` name:${name}` : ` chunks:${selectedChunks.debugId}`);
|
1099
997
|
// Add module to maps
|
1100
998
|
let info = chunksInfoMap.get(key);
|
1101
999
|
if (info === undefined) {
|
@@ -1110,9 +1008,9 @@ module.exports = class SplitChunksPlugin {
|
|
1110
1008
|
cacheGroupIndex,
|
1111
1009
|
name,
|
1112
1010
|
sizes: {},
|
1113
|
-
chunks:
|
1011
|
+
chunks: ChunkCombination.empty,
|
1114
1012
|
reuseableChunks: new Set(),
|
1115
|
-
|
1013
|
+
chunkCombinations: new Set()
|
1116
1014
|
})
|
1117
1015
|
);
|
1118
1016
|
}
|
@@ -1123,12 +1021,10 @@ module.exports = class SplitChunksPlugin {
|
|
1123
1021
|
info.sizes[type] = (info.sizes[type] || 0) + module.size(type);
|
1124
1022
|
}
|
1125
1023
|
}
|
1126
|
-
const oldChunksKeysSize = info.
|
1127
|
-
info.
|
1128
|
-
if (oldChunksKeysSize !== info.
|
1129
|
-
|
1130
|
-
info.chunks.add(chunk);
|
1131
|
-
}
|
1024
|
+
const oldChunksKeysSize = info.chunkCombinations.size;
|
1025
|
+
info.chunkCombinations.add(selectedChunks);
|
1026
|
+
if (oldChunksKeysSize !== info.chunkCombinations.size) {
|
1027
|
+
info.chunks = info.chunks.withAll(selectedChunks);
|
1132
1028
|
}
|
1133
1029
|
};
|
1134
1030
|
|
@@ -1149,50 +1045,56 @@ module.exports = class SplitChunksPlugin {
|
|
1149
1045
|
continue;
|
1150
1046
|
}
|
1151
1047
|
|
1152
|
-
|
1153
|
-
|
1154
|
-
const chunks = chunkGraph.getModuleChunksIterable(module);
|
1155
|
-
const chunksKey = getKey(chunks);
|
1156
|
-
return getCombinations(chunksKey);
|
1157
|
-
});
|
1158
|
-
|
1159
|
-
// Prepare some values (usedExports = true)
|
1160
|
-
const getCombsByUsedExports = memoize(() => {
|
1161
|
-
// fill the groupedByExportsMap
|
1162
|
-
getExportsChunkSetsInGraph();
|
1163
|
-
/** @type {Set<Set<Chunk> | Chunk>} */
|
1164
|
-
const set = new Set();
|
1165
|
-
const groupedByUsedExports = groupedByExportsMap.get(module);
|
1166
|
-
for (const chunks of groupedByUsedExports) {
|
1167
|
-
const chunksKey = getKey(chunks);
|
1168
|
-
for (const comb of getExportsCombinations(chunksKey))
|
1169
|
-
set.add(comb);
|
1170
|
-
}
|
1171
|
-
return set;
|
1172
|
-
});
|
1048
|
+
const chunkCombination =
|
1049
|
+
chunkGraph.getModuleChunkCombination(module);
|
1173
1050
|
|
1174
1051
|
let cacheGroupIndex = 0;
|
1175
1052
|
for (const cacheGroupSource of cacheGroups) {
|
1176
1053
|
const cacheGroup = this._getCacheGroup(cacheGroupSource);
|
1177
1054
|
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1055
|
+
// Break if minimum number of chunks is not reached
|
1056
|
+
if (chunkCombination.size < cacheGroup.minChunks) continue;
|
1057
|
+
|
1058
|
+
/** @type {Iterable<ChunkCombination>} */
|
1059
|
+
let combs;
|
1060
|
+
if (cacheGroup.usedExports) {
|
1061
|
+
// fill the groupedByExportsMap
|
1062
|
+
getExportsChunkCombinationsInGraph();
|
1063
|
+
/** @type {Set<ChunkCombination>} */
|
1064
|
+
const set = new Set();
|
1065
|
+
const groupedByUsedExports = groupedByExportsMap.get(module);
|
1066
|
+
for (const chunkCombination of groupedByUsedExports) {
|
1067
|
+
const preSelectedChunks = getSelectedChunks(
|
1068
|
+
chunkCombination,
|
1069
|
+
cacheGroup.chunksFilter
|
1070
|
+
);
|
1071
|
+
// Break if minimum number of chunks is not reached
|
1072
|
+
if (preSelectedChunks.size < cacheGroup.minChunks) continue;
|
1073
|
+
|
1074
|
+
for (const comb of getExportsCombinations(preSelectedChunks))
|
1075
|
+
set.add(comb);
|
1076
|
+
}
|
1077
|
+
combs = set;
|
1078
|
+
} else {
|
1079
|
+
const preSelectedChunks = getSelectedChunks(
|
1080
|
+
chunkCombination,
|
1081
|
+
cacheGroup.chunksFilter
|
1082
|
+
);
|
1083
|
+
// Break if minimum number of chunks is not reached
|
1084
|
+
if (preSelectedChunks.size < cacheGroup.minChunks) continue;
|
1085
|
+
|
1086
|
+
combs = getCombinations(preSelectedChunks);
|
1087
|
+
}
|
1181
1088
|
// For all combination of chunk selection
|
1182
|
-
for (const
|
1089
|
+
for (const selectedChunks of combs) {
|
1183
1090
|
// Break if minimum number of chunks is not reached
|
1184
|
-
const count =
|
1185
|
-
chunkCombination instanceof Chunk ? 1 : chunkCombination.size;
|
1091
|
+
const count = chunkCombination.size;
|
1186
1092
|
if (count < cacheGroup.minChunks) continue;
|
1187
|
-
// Select chunks by configuration
|
1188
|
-
const { chunks: selectedChunks, key: selectedChunksKey } =
|
1189
|
-
getSelectedChunks(chunkCombination, cacheGroup.chunksFilter);
|
1190
1093
|
|
1191
1094
|
addModuleToChunksInfoMap(
|
1192
1095
|
cacheGroup,
|
1193
1096
|
cacheGroupIndex,
|
1194
1097
|
selectedChunks,
|
1195
|
-
selectedChunksKey,
|
1196
1098
|
module
|
1197
1099
|
);
|
1198
1100
|
}
|
@@ -1284,12 +1186,12 @@ module.exports = class SplitChunksPlugin {
|
|
1284
1186
|
const chunkByName = compilation.namedChunks.get(chunkName);
|
1285
1187
|
if (chunkByName !== undefined) {
|
1286
1188
|
newChunk = chunkByName;
|
1287
|
-
const
|
1288
|
-
item.chunks
|
1289
|
-
isExistingChunk
|
1189
|
+
const newChunks = item.chunks.without(newChunk);
|
1190
|
+
isExistingChunk = newChunks !== item.chunks;
|
1191
|
+
if (isExistingChunk) item.chunks = newChunks;
|
1290
1192
|
}
|
1291
1193
|
} else if (item.cacheGroup.reuseExistingChunk) {
|
1292
|
-
outer: for (const chunk of item.chunks) {
|
1194
|
+
outer: for (const chunk of item.chunks.chunksIterable) {
|
1293
1195
|
if (
|
1294
1196
|
chunkGraph.getNumberOfChunkModules(chunk) !==
|
1295
1197
|
item.modules.size
|
@@ -1323,7 +1225,7 @@ module.exports = class SplitChunksPlugin {
|
|
1323
1225
|
}
|
1324
1226
|
}
|
1325
1227
|
if (newChunk) {
|
1326
|
-
item.chunks.
|
1228
|
+
item.chunks = item.chunks.without(newChunk);
|
1327
1229
|
chunkName = undefined;
|
1328
1230
|
isExistingChunk = true;
|
1329
1231
|
isReusedWithAllModules = true;
|
@@ -1334,7 +1236,7 @@ module.exports = class SplitChunksPlugin {
|
|
1334
1236
|
item.cacheGroup._conditionalEnforce &&
|
1335
1237
|
checkMinSize(item.sizes, item.cacheGroup.enforceSizeThreshold);
|
1336
1238
|
|
1337
|
-
|
1239
|
+
let usedChunks = item.chunks;
|
1338
1240
|
|
1339
1241
|
// Check if maxRequests condition can be fulfilled
|
1340
1242
|
if (
|
@@ -1342,7 +1244,7 @@ module.exports = class SplitChunksPlugin {
|
|
1342
1244
|
(Number.isFinite(item.cacheGroup.maxInitialRequests) ||
|
1343
1245
|
Number.isFinite(item.cacheGroup.maxAsyncRequests))
|
1344
1246
|
) {
|
1345
|
-
for (const chunk of usedChunks) {
|
1247
|
+
for (const chunk of usedChunks.chunksIterable) {
|
1346
1248
|
// respect max requests
|
1347
1249
|
const maxRequests = chunk.isOnlyInitial()
|
1348
1250
|
? item.cacheGroup.maxInitialRequests
|
@@ -1356,30 +1258,28 @@ module.exports = class SplitChunksPlugin {
|
|
1356
1258
|
isFinite(maxRequests) &&
|
1357
1259
|
getRequests(chunk) >= maxRequests
|
1358
1260
|
) {
|
1359
|
-
usedChunks.
|
1261
|
+
usedChunks = usedChunks.without(chunk);
|
1360
1262
|
}
|
1361
1263
|
}
|
1362
1264
|
}
|
1363
1265
|
|
1364
|
-
outer: for (const chunk of usedChunks) {
|
1266
|
+
outer: for (const chunk of usedChunks.chunksIterable) {
|
1365
1267
|
for (const module of item.modules) {
|
1366
1268
|
if (chunkGraph.isModuleInChunk(module, chunk)) continue outer;
|
1367
1269
|
}
|
1368
|
-
usedChunks.
|
1270
|
+
usedChunks = usedChunks.without(chunk);
|
1369
1271
|
}
|
1370
1272
|
|
1371
1273
|
// Were some (invalid) chunks removed from usedChunks?
|
1372
1274
|
// => readd all modules to the queue, as things could have been changed
|
1373
|
-
if (usedChunks
|
1374
|
-
if (isExistingChunk) usedChunks.
|
1275
|
+
if (usedChunks !== item.chunks) {
|
1276
|
+
if (isExistingChunk) usedChunks = usedChunks.with(newChunk);
|
1375
1277
|
if (usedChunks.size >= item.cacheGroup.minChunks) {
|
1376
|
-
const chunksArr = Array.from(usedChunks);
|
1377
1278
|
for (const module of item.modules) {
|
1378
1279
|
addModuleToChunksInfoMap(
|
1379
1280
|
item.cacheGroup,
|
1380
1281
|
item.cacheGroupIndex,
|
1381
|
-
|
1382
|
-
getKey(usedChunks),
|
1282
|
+
usedChunks,
|
1383
1283
|
module
|
1384
1284
|
);
|
1385
1285
|
}
|
@@ -1393,7 +1293,7 @@ module.exports = class SplitChunksPlugin {
|
|
1393
1293
|
item.cacheGroup._validateRemainingSize &&
|
1394
1294
|
usedChunks.size === 1
|
1395
1295
|
) {
|
1396
|
-
const [chunk] = usedChunks;
|
1296
|
+
const [chunk] = usedChunks.chunksIterable;
|
1397
1297
|
let chunkSizes = Object.create(null);
|
1398
1298
|
for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
|
1399
1299
|
if (!item.modules.has(module)) {
|
@@ -1427,7 +1327,7 @@ module.exports = class SplitChunksPlugin {
|
|
1427
1327
|
newChunk = compilation.addChunk(chunkName);
|
1428
1328
|
}
|
1429
1329
|
// Walk through all chunks
|
1430
|
-
for (const chunk of usedChunks) {
|
1330
|
+
for (const chunk of usedChunks.chunksIterable) {
|
1431
1331
|
// Add graph connections for splitted chunk
|
1432
1332
|
chunk.split(newChunk);
|
1433
1333
|
}
|
@@ -1457,14 +1357,14 @@ module.exports = class SplitChunksPlugin {
|
|
1457
1357
|
// Add module to new chunk
|
1458
1358
|
chunkGraph.connectChunkAndModule(newChunk, module);
|
1459
1359
|
// Remove module from used chunks
|
1460
|
-
for (const chunk of usedChunks) {
|
1360
|
+
for (const chunk of usedChunks.chunksIterable) {
|
1461
1361
|
chunkGraph.disconnectChunkAndModule(chunk, module);
|
1462
1362
|
}
|
1463
1363
|
}
|
1464
1364
|
} else {
|
1465
1365
|
// Remove all modules from used chunks
|
1466
1366
|
for (const module of item.modules) {
|
1467
|
-
for (const chunk of usedChunks) {
|
1367
|
+
for (const chunk of usedChunks.chunksIterable) {
|
1468
1368
|
chunkGraph.disconnectChunkAndModule(chunk, module);
|
1469
1369
|
}
|
1470
1370
|
}
|
@@ -1506,7 +1406,7 @@ module.exports = class SplitChunksPlugin {
|
|
1506
1406
|
|
1507
1407
|
// remove all modules from other entries and update size
|
1508
1408
|
for (const [key, info] of chunksInfoMap) {
|
1509
|
-
if (
|
1409
|
+
if (info.chunks.hasSharedChunks(usedChunks)) {
|
1510
1410
|
// update modules and total size
|
1511
1411
|
// may remove it from the map when < minSize
|
1512
1412
|
let updated = false;
|
@@ -6,6 +6,7 @@
|
|
6
6
|
"use strict";
|
7
7
|
|
8
8
|
const { URL, fileURLToPath } = require("url");
|
9
|
+
const { NormalModule } = require("..");
|
9
10
|
|
10
11
|
/** @typedef {import("../Compiler")} Compiler */
|
11
12
|
|
@@ -32,6 +33,14 @@ class FileUriPlugin {
|
|
32
33
|
resourceData.resource = path + query + fragment;
|
33
34
|
return true;
|
34
35
|
});
|
36
|
+
const hooks = NormalModule.getCompilationHooks(compilation);
|
37
|
+
hooks.readResource
|
38
|
+
.for(undefined)
|
39
|
+
.tapAsync("FileUriPlugin", (loaderContext, callback) => {
|
40
|
+
const { resourcePath } = loaderContext;
|
41
|
+
loaderContext.addDependency(resourcePath);
|
42
|
+
loaderContext.fs.readFile(resourcePath, callback);
|
43
|
+
});
|
35
44
|
}
|
36
45
|
);
|
37
46
|
}
|