mirror of https://github.com/webpack/webpack.git
improve way of getting combinations of chunks
we no longer require a complexity limit -> maxComplexity removed
This commit is contained in:
parent
cc0d29a90e
commit
244d27a42d
|
@ -168,7 +168,6 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
|
|||
this.set("optimization.usedExports", "make", options => isProductionLikeMode(options));
|
||||
this.set("optimization.concatenateModules", "make", options => isProductionLikeMode(options));
|
||||
this.set("optimization.splitChunks", {});
|
||||
this.set("optimization.splitChunks.maxComplexity", "make", options => isProductionLikeMode(options) ? 3 : 1);
|
||||
this.set("optimization.splitChunks.chunks", "async");
|
||||
this.set("optimization.splitChunks.minSize", 30000);
|
||||
this.set("optimization.splitChunks.minChunks", 1);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
const crypto = require("crypto");
|
||||
const SortableSet = require("../util/SortableSet");
|
||||
const GraphHelpers = require("../GraphHelpers");
|
||||
const isSubset = require("../util/SetHelpers").isSubset;
|
||||
|
||||
const hashFilename = (name) => {
|
||||
return crypto.createHash("md5").update(name).digest("hex").slice(0, 8);
|
||||
|
@ -40,23 +41,6 @@ const isOverlap = (a, b) => {
|
|||
return false;
|
||||
};
|
||||
|
||||
const getCombinations = (array, maxDepth) => {
|
||||
const results = [];
|
||||
getCombinationsInteral(array, maxDepth, results);
|
||||
return results;
|
||||
};
|
||||
|
||||
const getCombinationsInteral = (array, maxDepth, results) => {
|
||||
results.push(array);
|
||||
if(maxDepth === 0 || array.length === 1) {
|
||||
return;
|
||||
}
|
||||
for(let i = 0; i < array.length; i++) {
|
||||
const newArray = array.slice(0, i).concat(array.slice(i + 1, array.length));
|
||||
getCombinationsInteral(newArray, maxDepth - 1, results);
|
||||
}
|
||||
};
|
||||
|
||||
const compareEntries = (a, b) => {
|
||||
// 1. by priority
|
||||
const diffPriority = a.cacheGroup.priority - b.cacheGroup.priority;
|
||||
|
@ -97,7 +81,6 @@ module.exports = class SplitChunksPlugin {
|
|||
|
||||
static normalizeOptions(options) {
|
||||
return {
|
||||
maxComplexity: options.maxComplexity || 0,
|
||||
chunks: options.chunks || "all",
|
||||
minSize: options.minSize || 0,
|
||||
minChunks: options.minChunks || 1,
|
||||
|
@ -227,6 +210,25 @@ module.exports = class SplitChunksPlugin {
|
|||
for(const chunk of chunks) {
|
||||
indexMap.set(chunk, index++);
|
||||
}
|
||||
const getKey = chunks => {
|
||||
return Array.from(chunks, c => indexMap.get(c)).sort().join();
|
||||
};
|
||||
// Create a list of possible combinations
|
||||
const chunkSetsInGraph = new Map(); // Map<string, Set<Chunk>>
|
||||
for(const module of compilation.modules) {
|
||||
const chunkIndices = getKey(module.chunksIterable);
|
||||
chunkSetsInGraph.set(chunkIndices, new Set(module.chunksIterable));
|
||||
}
|
||||
const combinations = new Map(); // Map<string, Set<Chunk>[]>
|
||||
for(const [key, chunksSet] of chunkSetsInGraph) {
|
||||
var array = [];
|
||||
for(const set of chunkSetsInGraph.values()) {
|
||||
if(isSubset(chunksSet, set)) {
|
||||
array.push(set);
|
||||
}
|
||||
}
|
||||
combinations.set(key, array);
|
||||
}
|
||||
// Map a list of chunks to a list of modules
|
||||
// For the key the chunk "index" is used, the value is a SortableSet of modules
|
||||
const chunksInfoMap = new Map();
|
||||
|
@ -249,24 +251,24 @@ module.exports = class SplitChunksPlugin {
|
|||
getName: cacheGroupSource.getName !== undefined ? cacheGroupSource.getName : this.options.getName,
|
||||
reuseExistingChunk: cacheGroupSource.reuseExistingChunk
|
||||
};
|
||||
// Select chunks by configuration
|
||||
const maxSelectedChunks = cacheGroup.chunks === "initial" ? chunks.filter(chunk => chunk.canBeInitial()) :
|
||||
cacheGroup.chunks === "async" ? chunks.filter(chunk => !chunk.canBeInitial()) :
|
||||
chunks;
|
||||
// For all (nearly all) combination of chunk selection
|
||||
for(const selectedChunks of getCombinations(maxSelectedChunks, this.options.maxComplexity)) {
|
||||
// For all combination of chunk selection
|
||||
for(const chunkCombination of combinations.get(getKey(chunks))) {
|
||||
// Get indices of chunks in which this module occurs
|
||||
const chunkIndices = selectedChunks.map(chunk => indexMap.get(chunk));
|
||||
const chunkIndices = Array.from(chunkCombination, chunk => indexMap.get(chunk));
|
||||
// Break if minimum number of chunks is not reached
|
||||
if(chunkIndices.length < cacheGroup.minChunks)
|
||||
continue;
|
||||
// Select chunks by configuration
|
||||
const selectedChunks = cacheGroup.chunks === "initial" ? Array.from(chunkCombination).filter(chunk => chunk.canBeInitial()) :
|
||||
cacheGroup.chunks === "async" ? Array.from(chunkCombination).filter(chunk => !chunk.canBeInitial()) :
|
||||
Array.from(chunkCombination);
|
||||
// Determine name for split chunk
|
||||
const name = cacheGroup.getName(module, selectedChunks, cacheGroup.key);
|
||||
// Create key for maps
|
||||
// When it has a name we use the name as key
|
||||
// Elsewise we create the key from chunks and cache group key
|
||||
// This automatically merges equal names
|
||||
const chunksKey = chunkIndices.sort().join();
|
||||
const chunksKey = getKey(selectedChunks);
|
||||
const key = name && `name:${name}` ||
|
||||
`chunks:${chunksKey} key:${cacheGroup.key}`;
|
||||
// Add module to maps
|
||||
|
|
|
@ -24,3 +24,11 @@ exports.intersect = sets => {
|
|||
}
|
||||
return current;
|
||||
};
|
||||
|
||||
exports.isSubset = (bigSet, smallSet) => {
|
||||
if(bigSet.size < smallSet.size) return false;
|
||||
for(const item of smallSet) {
|
||||
if(!bigSet.has(item)) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
|
|
@ -1335,11 +1335,6 @@
|
|||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"maxComplexity": {
|
||||
"description": "Limits the algorithmic complexity",
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
},
|
||||
"chunks": {
|
||||
"description": "Select chunks for determining shared modules (defaults to \"async\", \"initial\" and \"all\" requires adding these chunks to the HTML)",
|
||||
"enum": [
|
||||
|
|
|
@ -18,7 +18,6 @@ module.exports = {
|
|||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
maxComplexity: 100,
|
||||
minSize: 100
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue