Merge pull request #11533 from webpack/bugfix/split-chunk-min-size

when splitChunks entry violates minSize or minRemainingSize retry without offending modules
This commit is contained in:
Tobias Koppers 2020-09-25 17:34:12 +02:00 committed by GitHub
commit 02b8036966
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 127 additions and 9 deletions

View File

@ -330,6 +330,24 @@ const checkMinSize = (sizes, minSize) => {
return true;
};
/**
* @param {SplitChunksSizes} sizes the sizes
* @param {SplitChunksSizes} minSize the min sizes
* @returns {undefined | string[]} list of size types that are below min size
*/
const getViolatingMinSizes = (sizes, minSize) => {
let list;
for (const key of Object.keys(minSize)) {
const size = sizes[key];
if (size === undefined || size === 0) continue;
if (size < minSize[key]) {
if (list === undefined) list = [key];
else list.push(key);
}
}
return list;
};
/**
* @param {SplitChunksSizes} sizes the sizes
* @returns {number} the total size
@ -1130,12 +1148,40 @@ module.exports = class SplitChunksPlugin {
logger.time("queue");
/**
* @param {ChunksInfoItem} info entry
* @param {string[]} sourceTypes source types to be removed
*/
const removeModulesWithSourceType = (info, sourceTypes) => {
for (const module of info.modules) {
const types = module.getSourceTypes();
if (sourceTypes.some(type => types.has(type))) {
info.modules.delete(module);
for (const type of types) {
info.sizes[type] -= module.size(type);
}
}
}
};
/**
* @param {ChunksInfoItem} info entry
* @returns {boolean} true, if entry become empty
*/
const removeMinSizeViolatingModules = info => {
if (!info.cacheGroup._validateSize) return false;
const violatingSizes = getViolatingMinSizes(
info.sizes,
info.cacheGroup.minSize
);
if (violatingSizes === undefined) return false;
removeModulesWithSourceType(info, violatingSizes);
return info.modules.size === 0;
};
// Filter items were size < minSize
for (const [key, info] of chunksInfoMap) {
if (
info.cacheGroup._validateSize &&
!checkMinSize(info.sizes, info.cacheGroup.minSize)
) {
if (removeMinSizeViolatingModules(info)) {
chunksInfoMap.delete(key);
}
}
@ -1298,7 +1344,21 @@ module.exports = class SplitChunksPlugin {
}
}
}
if (!checkMinSize(chunkSizes, item.cacheGroup.minRemainingSize)) {
const violatingSizes = getViolatingMinSizes(
chunkSizes,
item.cacheGroup.minRemainingSize
);
if (violatingSizes !== undefined) {
const oldModulesSize = item.modules.size;
removeModulesWithSourceType(item, violatingSizes);
if (
item.modules.size > 0 &&
item.modules.size !== oldModulesSize
) {
// queue this item again to be processed again
// without violating modules
chunksInfoMap.set(bestEntryKey, item);
}
continue;
}
}
@ -1407,11 +1467,9 @@ module.exports = class SplitChunksPlugin {
chunksInfoMap.delete(key);
continue;
}
if (
info.cacheGroup._validateSize &&
!checkMinSize(info.sizes, info.cacheGroup.minSize)
) {
if (removeMinSizeViolatingModules(info)) {
chunksInfoMap.delete(key);
continue;
}
}
}

View File

@ -0,0 +1,5 @@
export default "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

View File

@ -0,0 +1,2 @@
import "./big-module";
import "./wasm.wat";

View File

@ -0,0 +1,2 @@
import "./big-module";
import "./wasm.wat";

View File

@ -0,0 +1,4 @@
it("should", async () => {
import("./chunk1");
import("./chunk2");
});

View File

@ -0,0 +1,5 @@
module.exports = {
findBundle: function (i, options) {
return ["test.js", "main.js"];
}
};

View File

@ -0,0 +1,9 @@
(module
(func $add (export "add") (param $p0 i32) (param $p1 i32) (result i32)
(i32.add
(get_local $p0)
(get_local $p1)
)
)
)

View File

@ -0,0 +1,33 @@
/** @type {import("../../../../").Configuration} */
module.exports = {
entry: "./index",
module: {
rules: [
{
test: /\.wat$/,
loader: "wast-loader",
type: "webassembly/async"
}
]
},
output: {
filename: "[name].js"
},
optimization: {
splitChunks: {
cacheGroups: {
test: {
name: "test",
minChunks: 2,
minSize: {
javascript: 100,
webassembly: 100
}
}
}
}
},
experiments: {
asyncWebAssembly: true
}
};