@depup/webpack 5.109.0-depup.0 → 5.109.2-depup.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.
- package/README.md +4 -4
- package/bin/webpack.js +12 -0
- package/changes.json +4 -4
- package/lib/ChunkGraph.js +17 -15
- package/lib/CleanPlugin.js +11 -9
- package/lib/CompatibilityPlugin.js +31 -0
- package/lib/Compilation.js +21 -5
- package/lib/Compiler.js +16 -4
- package/lib/DefinePlugin.js +47 -20
- package/lib/ExportsInfo.js +22 -5
- package/lib/ExternalModule.js +10 -7
- package/lib/FileSystemInfo.js +126 -26
- package/lib/FlagDependencyUsagePlugin.js +33 -12
- package/lib/InitFragment.js +20 -32
- package/lib/ModuleFilenameHelpers.js +13 -2
- package/lib/NormalModule.js +80 -71
- package/lib/NormalModuleFactory.js +8 -2
- package/lib/RuntimePlugin.js +40 -113
- package/lib/Template.js +23 -3
- package/lib/cache/PackFileCacheStrategy.js +259 -5
- package/lib/config/defaults.js +21 -2
- package/lib/container/HoistContainerReferencesPlugin.js +47 -55
- package/lib/container/ModuleFederationPlugin.js +15 -9
- package/lib/css/CssGenerator.js +8 -2
- package/lib/css/CssLoadingRuntimeModule.js +25 -12
- package/lib/css/CssModulesPlugin.js +29 -18
- package/lib/css/CssParser.js +135 -50
- package/lib/css/syntax.js +862 -765
- package/lib/dependencies/CommonJsExportRequireDependency.js +19 -0
- package/lib/dependencies/CommonJsFullRequireDependency.js +33 -4
- package/lib/dependencies/CommonJsImportsParserPlugin.js +2 -0
- package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +2 -1
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +17 -9
- package/lib/dependencies/HarmonyImportDependency.js +1 -1
- package/lib/dependencies/HarmonyImportGuard.js +2 -1
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -7
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +15 -9
- package/lib/hmr/lazyCompilationBackend.js +19 -4
- package/lib/html/HtmlGenerator.js +23 -3
- package/lib/html/HtmlModulesPlugin.js +30 -12
- package/lib/html/syntax.js +2485 -2399
- package/lib/ids/IdHelpers.js +24 -10
- package/lib/javascript/JavascriptModulesPlugin.js +83 -49
- package/lib/javascript/JavascriptParser.js +49 -13
- package/lib/javascript/syntax.js +700 -43
- package/lib/node/ReadFileCompileAsyncWasmPlugin.js +10 -2
- package/lib/node/ReadFileCompileWasmPlugin.js +10 -2
- package/lib/optimize/AggressiveMergingPlugin.js +19 -15
- package/lib/optimize/ConcatenatedModule.js +19 -15
- package/lib/optimize/ModuleConcatenationPlugin.js +73 -24
- package/lib/optimize/RealContentHashPlugin.js +10 -7
- package/lib/optimize/SplitChunksPlugin.js +146 -44
- package/lib/prefetch/ResourceHintPlugin.js +96 -72
- package/lib/serialization/BinaryMiddleware.js +270 -938
- package/lib/serialization/FileMiddleware.js +299 -60
- package/lib/stats/DefaultStatsFactoryPlugin.js +204 -198
- package/lib/stats/DefaultStatsPrinterPlugin.js +24 -166
- package/lib/stats/StatsFactory.js +31 -9
- package/lib/util/identifier.js +21 -1
- package/package.json +10 -10
- package/schemas/WebpackOptions.json +110 -55
- package/types.d.ts +832 -247
|
@@ -77,7 +77,11 @@ class ReadFileCompileAsyncWasmPlugin {
|
|
|
77
77
|
"",
|
|
78
78
|
"// Fake fetch response",
|
|
79
79
|
"resolve({",
|
|
80
|
-
Template.indent([
|
|
80
|
+
Template.indent([
|
|
81
|
+
// Return a real ArrayBuffer: some runtimes (e.g. Deno)
|
|
82
|
+
// reject a Node Buffer view here as "not a buffer source".
|
|
83
|
+
"arrayBuffer() { return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength); }"
|
|
84
|
+
]),
|
|
81
85
|
"});"
|
|
82
86
|
]),
|
|
83
87
|
"});"
|
|
@@ -99,7 +103,11 @@ class ReadFileCompileAsyncWasmPlugin {
|
|
|
99
103
|
"",
|
|
100
104
|
"// Fake fetch response",
|
|
101
105
|
"resolve({",
|
|
102
|
-
Template.indent([
|
|
106
|
+
Template.indent([
|
|
107
|
+
// Return a real ArrayBuffer: some runtimes (e.g. Deno)
|
|
108
|
+
// reject a Node Buffer view here as "not a buffer source".
|
|
109
|
+
"arrayBuffer() { return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength); }"
|
|
110
|
+
]),
|
|
103
111
|
"});"
|
|
104
112
|
]),
|
|
105
113
|
"});"
|
|
@@ -77,7 +77,11 @@ class ReadFileCompileWasmPlugin {
|
|
|
77
77
|
"",
|
|
78
78
|
"// Fake fetch response",
|
|
79
79
|
"resolve({",
|
|
80
|
-
Template.indent([
|
|
80
|
+
Template.indent([
|
|
81
|
+
// Return a real ArrayBuffer: some runtimes (e.g. Deno)
|
|
82
|
+
// reject a Node Buffer view here as "not a buffer source".
|
|
83
|
+
"arrayBuffer() { return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength); }"
|
|
84
|
+
]),
|
|
81
85
|
"});"
|
|
82
86
|
]),
|
|
83
87
|
"});"
|
|
@@ -99,7 +103,11 @@ class ReadFileCompileWasmPlugin {
|
|
|
99
103
|
"",
|
|
100
104
|
"// Fake fetch response",
|
|
101
105
|
"resolve({",
|
|
102
|
-
Template.indent([
|
|
106
|
+
Template.indent([
|
|
107
|
+
// Return a real ArrayBuffer: some runtimes (e.g. Deno)
|
|
108
|
+
// reject a Node Buffer view here as "not a buffer source".
|
|
109
|
+
"arrayBuffer() { return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength); }"
|
|
110
|
+
]),
|
|
103
111
|
"});"
|
|
104
112
|
]),
|
|
105
113
|
"});"
|
|
@@ -53,8 +53,16 @@ class AggressiveMergingPlugin {
|
|
|
53
53
|
},
|
|
54
54
|
(chunks) => {
|
|
55
55
|
const chunkGraph = compilation.chunkGraph;
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
// Only the single best pair is merged per pass (the hook re-runs
|
|
57
|
+
// after each merge), so track the max directly instead of building
|
|
58
|
+
// and sorting the full O(chunks²) list of pairs every pass. A strict
|
|
59
|
+
// `>` keeps the first-encountered best, matching the previous stable
|
|
60
|
+
// descending sort's `[0]`.
|
|
61
|
+
/** @type {Chunk | undefined} */
|
|
62
|
+
let bestA;
|
|
63
|
+
/** @type {Chunk | undefined} */
|
|
64
|
+
let bestB;
|
|
65
|
+
let bestImprovement = -Infinity;
|
|
58
66
|
for (const a of chunks) {
|
|
59
67
|
if (a.canBeInitial()) continue;
|
|
60
68
|
for (const b of chunks) {
|
|
@@ -73,23 +81,19 @@ class AggressiveMergingPlugin {
|
|
|
73
81
|
chunkOverhead: 0
|
|
74
82
|
});
|
|
75
83
|
const improvement = (aSize + bSize) / abSize;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
84
|
+
if (improvement > bestImprovement) {
|
|
85
|
+
bestImprovement = improvement;
|
|
86
|
+
bestA = a;
|
|
87
|
+
bestB = b;
|
|
88
|
+
}
|
|
81
89
|
}
|
|
82
90
|
}
|
|
83
91
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const pair = combinations[0];
|
|
87
|
-
|
|
88
|
-
if (!pair) return;
|
|
89
|
-
if (pair.improvement < minSizeReduce) return;
|
|
92
|
+
if (bestA === undefined) return;
|
|
93
|
+
if (bestImprovement < minSizeReduce) return;
|
|
90
94
|
|
|
91
|
-
chunkGraph.integrateChunks(
|
|
92
|
-
compilation.chunks.delete(
|
|
95
|
+
chunkGraph.integrateChunks(/** @type {Chunk} */ (bestB), bestA);
|
|
96
|
+
compilation.chunks.delete(bestA);
|
|
93
97
|
return true;
|
|
94
98
|
}
|
|
95
99
|
);
|
|
@@ -99,6 +99,7 @@ const { InlinedUsedName } = require("./InlineExports");
|
|
|
99
99
|
/** @typedef {import("../javascript/JavascriptModulesPlugin").Variable} Variable */
|
|
100
100
|
/** @typedef {import("../javascript/JavascriptParser").Program} Program */
|
|
101
101
|
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
|
|
102
|
+
/** @typedef {import("estree").Identifier} Identifier */
|
|
102
103
|
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
|
|
103
104
|
/** @typedef {import("../util/Hash")} Hash */
|
|
104
105
|
/** @typedef {import("../util/Hash").HashFunction} HashFunction */
|
|
@@ -1011,16 +1012,17 @@ class ConcatenatedModule extends Module {
|
|
|
1011
1012
|
}
|
|
1012
1013
|
}
|
|
1013
1014
|
|
|
1014
|
-
// populate dependencies
|
|
1015
|
-
for (const d of m.dependencies
|
|
1016
|
-
(
|
|
1017
|
-
!Dependency.canConcatenate(
|
|
1015
|
+
// populate dependencies — keep only deps that leave the concat set
|
|
1016
|
+
for (const d of m.dependencies) {
|
|
1017
|
+
if (
|
|
1018
|
+
!Dependency.canConcatenate(d) ||
|
|
1018
1019
|
!this._modules.has(
|
|
1019
1020
|
/** @type {Module} */
|
|
1020
|
-
(compilation.moduleGraph.getModule(
|
|
1021
|
+
(compilation.moduleGraph.getModule(d))
|
|
1021
1022
|
)
|
|
1022
|
-
|
|
1023
|
-
|
|
1023
|
+
) {
|
|
1024
|
+
this.dependencies.push(d);
|
|
1025
|
+
}
|
|
1024
1026
|
}
|
|
1025
1027
|
// populate codeGenerationDependencies — the inner modules'
|
|
1026
1028
|
// templates are applied during ConcatenatedModule.codeGeneration,
|
|
@@ -1753,10 +1755,12 @@ class ConcatenatedModule extends Module {
|
|
|
1753
1755
|
const newName = _findNewName(name, info, references);
|
|
1754
1756
|
if (newName) {
|
|
1755
1757
|
const source = /** @type {ReplaceSource} */ (info.source);
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1758
|
+
/** @type {Set<Identifier>} */
|
|
1759
|
+
const allIdentifiers = new Set();
|
|
1760
|
+
for (const r of references) allIdentifiers.add(r.identifier);
|
|
1761
|
+
for (const identifier of variable.identifiers) {
|
|
1762
|
+
allIdentifiers.add(identifier);
|
|
1763
|
+
}
|
|
1760
1764
|
for (const identifier of allIdentifiers) {
|
|
1761
1765
|
const r = /** @type {Range} */ (identifier.range);
|
|
1762
1766
|
const path = getPathInAst(
|
|
@@ -1889,11 +1893,11 @@ class ConcatenatedModule extends Module {
|
|
|
1889
1893
|
const referencesByName = new Map();
|
|
1890
1894
|
for (const reference of globalScope.through) {
|
|
1891
1895
|
const name = reference.identifier.name;
|
|
1892
|
-
|
|
1893
|
-
|
|
1896
|
+
let references = referencesByName.get(name);
|
|
1897
|
+
if (references === undefined) {
|
|
1898
|
+
referencesByName.set(name, (references = []));
|
|
1894
1899
|
}
|
|
1895
|
-
|
|
1896
|
-
(referencesByName.get(name)).push(reference);
|
|
1900
|
+
references.push(reference);
|
|
1897
1901
|
}
|
|
1898
1902
|
for (const [name, references] of referencesByName) {
|
|
1899
1903
|
const match = ConcatenationScope.matchModuleReference(name);
|
|
@@ -70,6 +70,23 @@ const getMergedModuleRuntime = (chunkGraph, cache, module) => {
|
|
|
70
70
|
* @property {number} added
|
|
71
71
|
*/
|
|
72
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Record why `module` can't be added (so retried lookups hit the cache), bump
|
|
75
|
+
* the matching statistic, and return the problem to bubble up the recursion.
|
|
76
|
+
* Only reached on failure, so it stays off the hot success path.
|
|
77
|
+
* @param {Map<Module, Problem>} failureCache per-module failure cache
|
|
78
|
+
* @param {Statistics} statistics running statistics
|
|
79
|
+
* @param {keyof Statistics} statKey statistic to increment
|
|
80
|
+
* @param {Module} module the module that couldn't be added
|
|
81
|
+
* @param {Problem} problem the failure to cache and return
|
|
82
|
+
* @returns {Problem} the same problem
|
|
83
|
+
*/
|
|
84
|
+
const cacheFailure = (failureCache, statistics, statKey, module, problem) => {
|
|
85
|
+
statistics[statKey]++;
|
|
86
|
+
failureCache.set(module, problem);
|
|
87
|
+
return problem;
|
|
88
|
+
};
|
|
89
|
+
|
|
73
90
|
/**
|
|
74
91
|
* Format bailout reason.
|
|
75
92
|
* @param {string} msg message
|
|
@@ -687,9 +704,13 @@ class ModuleConcatenationPlugin {
|
|
|
687
704
|
|
|
688
705
|
// Not possible to add?
|
|
689
706
|
if (!possibleModules.has(module)) {
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
707
|
+
return cacheFailure(
|
|
708
|
+
failureCache,
|
|
709
|
+
statistics,
|
|
710
|
+
"invalidModule",
|
|
711
|
+
module,
|
|
712
|
+
module
|
|
713
|
+
);
|
|
693
714
|
}
|
|
694
715
|
|
|
695
716
|
// A deferred import must stay a concatenation boundary: concatenating a
|
|
@@ -707,9 +728,13 @@ class ModuleConcatenationPlugin {
|
|
|
707
728
|
`Module ${module.readableIdentifier(
|
|
708
729
|
requestShortener
|
|
709
730
|
)} imports a module in this configuration via import defer`;
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
731
|
+
return cacheFailure(
|
|
732
|
+
failureCache,
|
|
733
|
+
statistics,
|
|
734
|
+
"incorrectDependency",
|
|
735
|
+
module,
|
|
736
|
+
problem
|
|
737
|
+
);
|
|
713
738
|
}
|
|
714
739
|
|
|
715
740
|
// Module must be in the correct chunks
|
|
@@ -741,9 +766,13 @@ class ModuleConcatenationPlugin {
|
|
|
741
766
|
", "
|
|
742
767
|
)}, module is in chunk(s) ${chunks.join(", ")})`;
|
|
743
768
|
};
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
769
|
+
return cacheFailure(
|
|
770
|
+
failureCache,
|
|
771
|
+
statistics,
|
|
772
|
+
"incorrectChunks",
|
|
773
|
+
module,
|
|
774
|
+
problem
|
|
775
|
+
);
|
|
747
776
|
}
|
|
748
777
|
|
|
749
778
|
const moduleGraph = compilation.moduleGraph;
|
|
@@ -782,9 +811,13 @@ class ModuleConcatenationPlugin {
|
|
|
782
811
|
: "in an unsupported way"
|
|
783
812
|
}`;
|
|
784
813
|
};
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
814
|
+
return cacheFailure(
|
|
815
|
+
failureCache,
|
|
816
|
+
statistics,
|
|
817
|
+
"incorrectDependency",
|
|
818
|
+
module,
|
|
819
|
+
problem
|
|
820
|
+
);
|
|
788
821
|
}
|
|
789
822
|
}
|
|
790
823
|
|
|
@@ -841,9 +874,13 @@ class ModuleConcatenationPlugin {
|
|
|
841
874
|
", "
|
|
842
875
|
)}`;
|
|
843
876
|
};
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
877
|
+
return cacheFailure(
|
|
878
|
+
failureCache,
|
|
879
|
+
statistics,
|
|
880
|
+
"incorrectChunksOfImporter",
|
|
881
|
+
module,
|
|
882
|
+
problem
|
|
883
|
+
);
|
|
847
884
|
}
|
|
848
885
|
|
|
849
886
|
/** @type {Map<Module, ReadonlyArray<ModuleGraph.ModuleGraphConnection>>} */
|
|
@@ -893,9 +930,13 @@ class ModuleConcatenationPlugin {
|
|
|
893
930
|
", "
|
|
894
931
|
)}`;
|
|
895
932
|
};
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
933
|
+
return cacheFailure(
|
|
934
|
+
failureCache,
|
|
935
|
+
statistics,
|
|
936
|
+
"incorrectModuleDependency",
|
|
937
|
+
module,
|
|
938
|
+
problem
|
|
939
|
+
);
|
|
899
940
|
}
|
|
900
941
|
|
|
901
942
|
if (runtime !== undefined && typeof runtime !== "string") {
|
|
@@ -946,9 +987,13 @@ class ModuleConcatenationPlugin {
|
|
|
946
987
|
/** @type {RuntimeSpec} */ (runtimeCondition)
|
|
947
988
|
)})`
|
|
948
989
|
).join(", ")}`;
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
990
|
+
return cacheFailure(
|
|
991
|
+
failureCache,
|
|
992
|
+
statistics,
|
|
993
|
+
"incorrectRuntimeCondition",
|
|
994
|
+
module,
|
|
995
|
+
problem
|
|
996
|
+
);
|
|
952
997
|
}
|
|
953
998
|
}
|
|
954
999
|
|
|
@@ -981,9 +1026,13 @@ class ModuleConcatenationPlugin {
|
|
|
981
1026
|
);
|
|
982
1027
|
if (problem) {
|
|
983
1028
|
if (backup !== undefined) config.rollback(backup);
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
1029
|
+
return cacheFailure(
|
|
1030
|
+
failureCache,
|
|
1031
|
+
statistics,
|
|
1032
|
+
"importerFailed",
|
|
1033
|
+
module,
|
|
1034
|
+
problem
|
|
1035
|
+
);
|
|
987
1036
|
}
|
|
988
1037
|
}
|
|
989
1038
|
|
|
@@ -166,10 +166,16 @@ const toCachedSource = (source) => {
|
|
|
166
166
|
* @property {Hashes} hashes
|
|
167
167
|
*/
|
|
168
168
|
|
|
169
|
+
const createCompilationHooks = () => ({
|
|
170
|
+
/**
|
|
171
|
+
* @type {SyncBailHook<[Buffer[], string], string | void>}
|
|
172
|
+
* @since 5.8.0
|
|
173
|
+
*/
|
|
174
|
+
updateHash: new SyncBailHook(["content", "oldHash"])
|
|
175
|
+
});
|
|
176
|
+
|
|
169
177
|
/**
|
|
170
|
-
*
|
|
171
|
-
* @typedef {object} CompilationHooks
|
|
172
|
-
* @property {SyncBailHook<[Buffer[], string], string | void>} updateHash
|
|
178
|
+
* @typedef {ReturnType<typeof createCompilationHooks>} CompilationHooks
|
|
173
179
|
*/
|
|
174
180
|
|
|
175
181
|
/**
|
|
@@ -554,10 +560,7 @@ ${referencingAssets
|
|
|
554
560
|
}
|
|
555
561
|
|
|
556
562
|
RealContentHashPlugin.getCompilationHooks = createHooksRegistry(
|
|
557
|
-
|
|
558
|
-
/** @type {CompilationHooks} */ ({
|
|
559
|
-
updateHash: new SyncBailHook(["content", "oldHash"])
|
|
560
|
-
})
|
|
563
|
+
createCompilationHooks
|
|
561
564
|
);
|
|
562
565
|
|
|
563
566
|
module.exports = RealContentHashPlugin;
|
|
@@ -182,7 +182,6 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
|
|
|
182
182
|
* @property {string=} name
|
|
183
183
|
* @property {SplitChunksSizes} sizes
|
|
184
184
|
* @property {ChunkSet} chunks
|
|
185
|
-
* @property {ChunkSet} reusableChunks
|
|
186
185
|
* @property {Set<bigint | Chunk>} chunksKeys
|
|
187
186
|
*/
|
|
188
187
|
|
|
@@ -229,7 +228,6 @@ const getRequests = (chunk) => {
|
|
|
229
228
|
/**
|
|
230
229
|
* Returns result.
|
|
231
230
|
* @template {object} T
|
|
232
|
-
* @template {object} R
|
|
233
231
|
* @param {T} obj obj an object
|
|
234
232
|
* @param {(obj: T[keyof T], key: keyof T) => T[keyof T]} fn fn
|
|
235
233
|
* @returns {T} result
|
|
@@ -314,6 +312,9 @@ const ASYNC_CHUNK_FILTER = (chunk) => !chunk.canBeInitial();
|
|
|
314
312
|
*/
|
|
315
313
|
const ALL_CHUNK_FILTER = (_chunk) => true;
|
|
316
314
|
|
|
315
|
+
/** Placeholder until a chunk set group is filled and its signatures are written. */
|
|
316
|
+
const EMPTY_SIGNATURES = new Uint32Array(0);
|
|
317
|
+
|
|
317
318
|
/**
|
|
318
319
|
* Returns normalized representation.
|
|
319
320
|
* @param {OptimizationSplitChunksSizes | undefined} value the sizes
|
|
@@ -902,15 +903,21 @@ module.exports = class SplitChunksPlugin {
|
|
|
902
903
|
// Give each selected chunk an index (to create strings from chunks)
|
|
903
904
|
/** @type {Map<Chunk, bigint>} */
|
|
904
905
|
const chunkIndexMap = new Map();
|
|
906
|
+
// Dense per-chunk index, folded into the 64 bit membership
|
|
907
|
+
// signatures that reject non-subsets in getCombinations
|
|
908
|
+
/** @type {Map<Chunk, number>} */
|
|
909
|
+
const chunkSignatureBitMap = new Map();
|
|
905
910
|
const ZERO = BigInt("0");
|
|
906
911
|
const ONE = BigInt("1");
|
|
907
912
|
const START = ONE << BigInt("31");
|
|
908
913
|
let index = START;
|
|
914
|
+
let denseIndex = 0;
|
|
909
915
|
for (const chunk of chunks) {
|
|
910
916
|
chunkIndexMap.set(
|
|
911
917
|
chunk,
|
|
912
918
|
index | BigInt((Math.random() * 0x7fffffff) | 0)
|
|
913
919
|
);
|
|
920
|
+
chunkSignatureBitMap.set(chunk, denseIndex++ & 63);
|
|
914
921
|
index <<= ONE;
|
|
915
922
|
}
|
|
916
923
|
/**
|
|
@@ -1011,7 +1018,36 @@ module.exports = class SplitChunksPlugin {
|
|
|
1011
1018
|
return { chunkSetsInGraph, singleChunkSets };
|
|
1012
1019
|
});
|
|
1013
1020
|
|
|
1014
|
-
/**
|
|
1021
|
+
/**
|
|
1022
|
+
* Chunk sets of equal size, with a 64 bit membership signature
|
|
1023
|
+
* per set stored as two words at `2 * i` in `signatures`.
|
|
1024
|
+
* @typedef {object} ChunkSetGroup
|
|
1025
|
+
* @property {ChunkSet[]} sets the chunk sets
|
|
1026
|
+
* @property {Uint32Array} signatures two signature words per set
|
|
1027
|
+
*/
|
|
1028
|
+
|
|
1029
|
+
/** @typedef {Map<CountOfChunk, ChunkSetGroup>} ChunkSetsByCount */
|
|
1030
|
+
|
|
1031
|
+
// holds the signature of the set currently being combined; transient
|
|
1032
|
+
const signatureScratch = new Uint32Array(2);
|
|
1033
|
+
|
|
1034
|
+
/**
|
|
1035
|
+
* Folds a chunk set into a 64 bit membership signature.
|
|
1036
|
+
* @param {ChunkSet} chunksSet set of chunks
|
|
1037
|
+
* @param {Uint32Array} out target array
|
|
1038
|
+
* @param {number} offset index of the first of the two words
|
|
1039
|
+
* @returns {void}
|
|
1040
|
+
*/
|
|
1041
|
+
const writeSignature = (chunksSet, out, offset) => {
|
|
1042
|
+
out[offset] = 0;
|
|
1043
|
+
out[offset + 1] = 0;
|
|
1044
|
+
for (const chunk of chunksSet) {
|
|
1045
|
+
const bit = /** @type {number} */ (
|
|
1046
|
+
chunkSignatureBitMap.get(chunk)
|
|
1047
|
+
);
|
|
1048
|
+
out[offset + (bit >> 5)] |= 1 << (bit & 31);
|
|
1049
|
+
}
|
|
1050
|
+
};
|
|
1015
1051
|
|
|
1016
1052
|
// group these set of chunks by count
|
|
1017
1053
|
// to allow to check less sets via isSubset
|
|
@@ -1026,12 +1062,20 @@ module.exports = class SplitChunksPlugin {
|
|
|
1026
1062
|
const chunkSetsByCount = new Map();
|
|
1027
1063
|
for (const chunksSet of chunkSets) {
|
|
1028
1064
|
const count = chunksSet.size;
|
|
1029
|
-
let
|
|
1030
|
-
if (
|
|
1031
|
-
|
|
1032
|
-
chunkSetsByCount.set(count,
|
|
1065
|
+
let group = chunkSetsByCount.get(count);
|
|
1066
|
+
if (group === undefined) {
|
|
1067
|
+
group = { sets: [], signatures: EMPTY_SIGNATURES };
|
|
1068
|
+
chunkSetsByCount.set(count, group);
|
|
1033
1069
|
}
|
|
1034
|
-
|
|
1070
|
+
group.sets.push(chunksSet);
|
|
1071
|
+
}
|
|
1072
|
+
for (const group of chunkSetsByCount.values()) {
|
|
1073
|
+
const { sets } = group;
|
|
1074
|
+
const signatures = new Uint32Array(sets.length * 2);
|
|
1075
|
+
for (let i = 0; i < sets.length; i++) {
|
|
1076
|
+
writeSignature(sets[i], signatures, i * 2);
|
|
1077
|
+
}
|
|
1078
|
+
group.signatures = signatures;
|
|
1035
1079
|
}
|
|
1036
1080
|
return chunkSetsByCount;
|
|
1037
1081
|
};
|
|
@@ -1077,10 +1121,24 @@ module.exports = class SplitChunksPlugin {
|
|
|
1077
1121
|
(chunkSets.get(key));
|
|
1078
1122
|
/** @type {Combinations} */
|
|
1079
1123
|
const array = [chunksSet];
|
|
1080
|
-
|
|
1124
|
+
writeSignature(chunksSet, signatureScratch, 0);
|
|
1125
|
+
const selfLow = signatureScratch[0];
|
|
1126
|
+
const selfHigh = signatureScratch[1];
|
|
1127
|
+
for (const [count, group] of chunkSetsByCount) {
|
|
1081
1128
|
// "equal" is not needed because they would have been merge in the first step
|
|
1082
1129
|
if (count < chunksSet.size) {
|
|
1083
|
-
|
|
1130
|
+
const { sets, signatures } = group;
|
|
1131
|
+
for (let i = 0; i < sets.length; i++) {
|
|
1132
|
+
// a subset cannot hold a signature bit the superset lacks,
|
|
1133
|
+
// so this rejects nearly every candidate without touching the Set
|
|
1134
|
+
const offset = i * 2;
|
|
1135
|
+
if (
|
|
1136
|
+
(signatures[offset] & ~selfLow) !== 0 ||
|
|
1137
|
+
(signatures[offset + 1] & ~selfHigh) !== 0
|
|
1138
|
+
) {
|
|
1139
|
+
continue;
|
|
1140
|
+
}
|
|
1141
|
+
const set = sets[i];
|
|
1084
1142
|
if (isSubset(chunksSet, set)) {
|
|
1085
1143
|
array.push(set);
|
|
1086
1144
|
}
|
|
@@ -1187,6 +1245,31 @@ module.exports = class SplitChunksPlugin {
|
|
|
1187
1245
|
/** @type {Map<string, ChunksInfoItem>} */
|
|
1188
1246
|
const chunksInfoMap = new Map();
|
|
1189
1247
|
|
|
1248
|
+
// The unnamed key is derived only from cache group and chunk set, so it
|
|
1249
|
+
// repeats for every module sharing that pair — build the string once
|
|
1250
|
+
/** @type {Map<CacheGroup, Map<bigint | Chunk, string>>} */
|
|
1251
|
+
const unnamedKeyCache = new Map();
|
|
1252
|
+
|
|
1253
|
+
/**
|
|
1254
|
+
* Returns the chunksInfoMap key for a cache group and chunk set.
|
|
1255
|
+
* @param {CacheGroup} cacheGroup the current cache group
|
|
1256
|
+
* @param {bigint | Chunk} selectedChunksKey a key of selectedChunks
|
|
1257
|
+
* @returns {string} key into chunksInfoMap
|
|
1258
|
+
*/
|
|
1259
|
+
const getUnnamedKey = (cacheGroup, selectedChunksKey) => {
|
|
1260
|
+
let byChunksKey = unnamedKeyCache.get(cacheGroup);
|
|
1261
|
+
if (byChunksKey === undefined) {
|
|
1262
|
+
byChunksKey = new Map();
|
|
1263
|
+
unnamedKeyCache.set(cacheGroup, byChunksKey);
|
|
1264
|
+
}
|
|
1265
|
+
let key = byChunksKey.get(selectedChunksKey);
|
|
1266
|
+
if (key === undefined) {
|
|
1267
|
+
key = `${cacheGroup.key} chunks:${keyToString(selectedChunksKey)}`;
|
|
1268
|
+
byChunksKey.set(selectedChunksKey, key);
|
|
1269
|
+
}
|
|
1270
|
+
return key;
|
|
1271
|
+
};
|
|
1272
|
+
|
|
1190
1273
|
/**
|
|
1191
1274
|
* Adds module to chunks info map.
|
|
1192
1275
|
* @param {CacheGroup} cacheGroup the current cache group
|
|
@@ -1270,11 +1353,9 @@ module.exports = class SplitChunksPlugin {
|
|
|
1270
1353
|
// When it has a name we use the name as key
|
|
1271
1354
|
// Otherwise we create the key from chunks and cache group key
|
|
1272
1355
|
// This automatically merges equal names
|
|
1273
|
-
const key =
|
|
1274
|
-
cacheGroup.key
|
|
1275
|
-
(
|
|
1276
|
-
? ` name:${name}`
|
|
1277
|
-
: ` chunks:${keyToString(selectedChunksKey)}`);
|
|
1356
|
+
const key = name
|
|
1357
|
+
? `${cacheGroup.key} name:${name}`
|
|
1358
|
+
: getUnnamedKey(cacheGroup, selectedChunksKey);
|
|
1278
1359
|
// Add module to maps
|
|
1279
1360
|
let info = chunksInfoMap.get(key);
|
|
1280
1361
|
if (info === undefined) {
|
|
@@ -1290,7 +1371,6 @@ module.exports = class SplitChunksPlugin {
|
|
|
1290
1371
|
name,
|
|
1291
1372
|
sizes: {},
|
|
1292
1373
|
chunks: new Set(),
|
|
1293
|
-
reusableChunks: new Set(),
|
|
1294
1374
|
chunksKeys: new Set()
|
|
1295
1375
|
})
|
|
1296
1376
|
);
|
|
@@ -1316,6 +1396,35 @@ module.exports = class SplitChunksPlugin {
|
|
|
1316
1396
|
chunkGraph
|
|
1317
1397
|
};
|
|
1318
1398
|
|
|
1399
|
+
/**
|
|
1400
|
+
* Returns combinations of the chunks the module is in.
|
|
1401
|
+
* @param {Module} module the module
|
|
1402
|
+
* @returns {Combinations} chunk combinations
|
|
1403
|
+
*/
|
|
1404
|
+
const computeCombinations = (module) =>
|
|
1405
|
+
getCombinations(getKey(chunkGraph.getModuleChunksIterable(module)));
|
|
1406
|
+
|
|
1407
|
+
/**
|
|
1408
|
+
* Returns combinations of the module's chunks grouped by used exports.
|
|
1409
|
+
* @param {Module} module the module
|
|
1410
|
+
* @returns {Set<ChunkSet | Chunk>} chunk combinations
|
|
1411
|
+
*/
|
|
1412
|
+
const computeCombinationsByUsedExports = (module) => {
|
|
1413
|
+
// fill the groupedByExportsMap
|
|
1414
|
+
getExportsChunkSetsInGraph();
|
|
1415
|
+
/** @type {Set<ChunkSet | Chunk>} */
|
|
1416
|
+
const set = new Set();
|
|
1417
|
+
const groupedByUsedExports =
|
|
1418
|
+
/** @type {Iterable<Chunk[]>} */
|
|
1419
|
+
(groupedByExportsMap.get(module));
|
|
1420
|
+
for (const chunks of groupedByUsedExports) {
|
|
1421
|
+
for (const comb of getExportsCombinations(getKey(chunks))) {
|
|
1422
|
+
set.add(comb);
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
return set;
|
|
1426
|
+
};
|
|
1427
|
+
|
|
1319
1428
|
logger.timeEnd("prepare");
|
|
1320
1429
|
|
|
1321
1430
|
logger.time("modules");
|
|
@@ -1328,38 +1437,29 @@ module.exports = class SplitChunksPlugin {
|
|
|
1328
1437
|
continue;
|
|
1329
1438
|
}
|
|
1330
1439
|
|
|
1331
|
-
//
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
});
|
|
1337
|
-
|
|
1338
|
-
// Prepare some values (usedExports = true)
|
|
1339
|
-
const getCombsByUsedExports = memoize(() => {
|
|
1340
|
-
// fill the groupedByExportsMap
|
|
1341
|
-
getExportsChunkSetsInGraph();
|
|
1342
|
-
/** @type {Set<ChunkSet | Chunk>} */
|
|
1343
|
-
const set = new Set();
|
|
1344
|
-
const groupedByUsedExports =
|
|
1345
|
-
/** @type {Iterable<Chunk[]>} */
|
|
1346
|
-
(groupedByExportsMap.get(module));
|
|
1347
|
-
for (const chunks of groupedByUsedExports) {
|
|
1348
|
-
const chunksKey = getKey(chunks);
|
|
1349
|
-
for (const comb of getExportsCombinations(chunksKey)) {
|
|
1350
|
-
set.add(comb);
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
return set;
|
|
1354
|
-
});
|
|
1440
|
+
// Computed at most once per module, on first use by a cache group
|
|
1441
|
+
/** @type {Combinations | undefined} */
|
|
1442
|
+
let combsCache;
|
|
1443
|
+
/** @type {Set<ChunkSet | Chunk> | undefined} */
|
|
1444
|
+
let combsByUsedExportsCache;
|
|
1355
1445
|
|
|
1356
1446
|
let cacheGroupIndex = 0;
|
|
1357
1447
|
for (const cacheGroupSource of cacheGroups) {
|
|
1358
1448
|
const cacheGroup = this._getCacheGroup(cacheGroupSource);
|
|
1359
1449
|
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1450
|
+
let combs;
|
|
1451
|
+
if (cacheGroup.usedExports) {
|
|
1452
|
+
if (combsByUsedExportsCache === undefined) {
|
|
1453
|
+
combsByUsedExportsCache =
|
|
1454
|
+
computeCombinationsByUsedExports(module);
|
|
1455
|
+
}
|
|
1456
|
+
combs = combsByUsedExportsCache;
|
|
1457
|
+
} else {
|
|
1458
|
+
if (combsCache === undefined) {
|
|
1459
|
+
combsCache = computeCombinations(module);
|
|
1460
|
+
}
|
|
1461
|
+
combs = combsCache;
|
|
1462
|
+
}
|
|
1363
1463
|
// For all combination of chunk selection
|
|
1364
1464
|
for (const chunkCombination of combs) {
|
|
1365
1465
|
// Break if minimum number of chunks is not reached
|
|
@@ -1577,12 +1677,14 @@ module.exports = class SplitChunksPlugin {
|
|
|
1577
1677
|
}
|
|
1578
1678
|
if (usedChunks.size >= item.cacheGroup.minChunks) {
|
|
1579
1679
|
const chunksArr = [...usedChunks];
|
|
1680
|
+
// invariant across the module loop below
|
|
1681
|
+
const usedChunksKey = getKey(usedChunks);
|
|
1580
1682
|
for (const module of item.modules) {
|
|
1581
1683
|
addModuleToChunksInfoMap(
|
|
1582
1684
|
item.cacheGroup,
|
|
1583
1685
|
item.cacheGroupIndex,
|
|
1584
1686
|
chunksArr,
|
|
1585
|
-
|
|
1687
|
+
usedChunksKey,
|
|
1586
1688
|
module
|
|
1587
1689
|
);
|
|
1588
1690
|
}
|