Skip to content

Commit

Permalink
Add maxAsyncSize and maxInitialSize options
Browse files Browse the repository at this point in the history
  • Loading branch information
ooflorent committed Dec 11, 2018
1 parent 5f26040 commit 2a10b12
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 47 deletions.
16 changes: 16 additions & 0 deletions declarations/WebpackOptions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,14 @@ export interface OptimizationSplitChunksOptions {
* Sets the name delimiter for created chunks
*/
automaticNameDelimiter?: string;
/**
* Maximal size hint for the on-demand chunks
*/
maxAsyncSize?: OptimizationSplitChunksSizes;
/**
* Maximal size hint for the initial chunks
*/
maxInitialSize?: OptimizationSplitChunksSizes;
/**
* Maximal size hint for the created chunks
*/
Expand Down Expand Up @@ -989,10 +997,18 @@ export interface OptimizationSplitChunksCacheGroup {
* Maximum number of requests which are accepted for on-demand loading
*/
maxAsyncRequests?: number;
/**
* Maximal size hint for the on-demand chunks
*/
maxAsyncSize?: OptimizationSplitChunksSizes;
/**
* Maximum number of initial chunks which are accepted for an entry point
*/
maxInitialRequests?: number;
/**
* Maximal size hint for the initial chunks
*/
maxInitialSize?: OptimizationSplitChunksSizes;
/**
* Maximal size hint for the created chunks
*/
Expand Down
1 change: 0 additions & 1 deletion lib/WebpackOptionsDefaulter.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
this.set("optimization.splitChunks.maxAsyncRequests", "make", options => {
return isProductionLikeMode(options) ? 6 : Infinity;
});
this.set("optimization.splitChunks.maxAsyncSize", 100000);
this.set("optimization.splitChunks.automaticNameDelimiter", "-");
this.set("optimization.splitChunks.maxInitialRequests", "make", options => {
return isProductionLikeMode(options) ? 4 : Infinity;
Expand Down
137 changes: 91 additions & 46 deletions lib/optimize/SplitChunksPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
* @returns {boolean}
*/

/**
* @callback CombineSizeFunction
* @param {number} a
* @param {number} b
* @returns {number}
*/

/**
* @typedef {Object} CacheGroupSource
* @property {string=} key
Expand All @@ -52,7 +59,8 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
* @property {ChunkFilterFunction=} chunksFilter
* @property {boolean=} enforce
* @property {SplitChunksSizes} minSize
* @property {SplitChunksSizes} maxSize
* @property {SplitChunksSizes} maxAsyncSize
* @property {SplitChunksSizes} maxInitialSize
* @property {number=} minChunks
* @property {number=} maxAsyncRequests
* @property {number=} maxInitialRequests
Expand All @@ -71,7 +79,6 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
* @property {boolean=} enforce
* @property {SplitChunksSizes} minSize
* @property {SplitChunksSizes} minSizeForMaxSize
* @property {SplitChunksSizes} maxSize
* @property {SplitChunksSizes} maxAsyncSize
* @property {SplitChunksSizes} maxInitialSize
* @property {number=} minChunks
Expand All @@ -86,7 +93,8 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
/**
* @typedef {Object} FallbackCacheGroup
* @property {SplitChunksSizes} minSize
* @property {SplitChunksSizes} maxSize
* @property {SplitChunksSizes} maxAsyncSize
* @property {SplitChunksSizes} maxInitialSize
* @property {string} automaticNameDelimiter
*/

Expand Down Expand Up @@ -115,7 +123,6 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
* @typedef {Object} SplitChunksOptions
* @property {ChunkFilterFunction} chunksFilter
* @property {SplitChunksSizes} minSize
* @property {SplitChunksSizes} maxSize
* @property {SplitChunksSizes} maxInitialSize
* @property {SplitChunksSizes} maxAsyncSize
* @property {number} minChunks
Expand Down Expand Up @@ -230,32 +237,35 @@ const ALL_CHUNK_FILTER = chunk => true;
*/
const normalizeSizes = value => {
if (typeof value === "number") {
const obj = Object.create(null);
obj.javascript = value;
return obj;
return {
javascript: value
};
} else if (typeof value === "object" && value !== null) {
return Object.assign(Object.create(null), value);
return Object.assign({}, value);
} else {
return Object.create(null);
return {};
}
};

/**
* @param {OptimizationSplitChunksSizes} value the sizes
* @param {OptimizationSplitChunksSizes} defaultValue the default sizes
* @param {...OptimizationSplitChunksSizes} sizes the sizes
* @returns {SplitChunksSizes} the merged sizes
*/
const mergeSizes = (value, defaultValue) => {
if (value === undefined) return normalizeSizes(defaultValue);
const sizes = normalizeSizes(value);
const defaultSizes = normalizeSizes(defaultValue);
return Object.assign(Object.create(null), defaultSizes, sizes);
const mergeSizes = (...sizes) => {
return Object.assign({}, ...sizes.map(normalizeSizes).reverse());
};

/**
* @param {SplitChunksSizes} a first sizes
* @param {SplitChunksSizes} b second sizes
* @param {CombineSizeFunction} combine a function to combine sizes
* @returns {SplitChunksSizes} the combine sizes
*/
const combineSizes = (a, b, combine) => {
const aKeys = new Set(Object.keys(a));
const bKeys = new Set(Object.keys(b));
const result = Object.create(null);
/** @type {SplitChunksSizes} */
const result = {};
for (const key of aKeys) {
if (bKeys.has(key)) {
result[key] = combine(a[key], b[key]);
Expand Down Expand Up @@ -385,6 +395,8 @@ const normalizeCacheGroups = (cacheGroups, name) => {
enforce: option.enforce,
minSize: option.minSize,
maxSize: option.maxSize,
maxAsyncSize: option.maxAsyncSize,
maxInitialSize: option.maxInitialSize,
minChunks: option.minChunks,
maxAsyncRequests: option.maxAsyncRequests,
maxInitialRequests: option.maxInitialRequests,
Expand Down Expand Up @@ -465,7 +477,8 @@ const createCacheGroupSource = options => {
chunksFilter: normalizeChunksFilter(options.chunks),
enforce: options.enforce,
minSize: normalizeSizes(options.minSize),
maxSize: normalizeSizes(options.maxSize),
maxAsyncSize: mergeSizes(options.maxAsyncSize, options.maxSize),
maxInitialSize: mergeSizes(options.maxInitialSize, options.maxSize),
minChunks: options.minChunks,
maxAsyncRequests: options.maxAsyncRequests,
maxInitialRequests: options.maxInitialRequests,
Expand All @@ -487,9 +500,8 @@ module.exports = class SplitChunksPlugin {
this.options = {
chunksFilter: normalizeChunksFilter(options.chunks || "all"),
minSize: normalizeSizes(options.minSize),
maxSize: normalizeSizes(options.maxSize),
maxInitialSize: normalizeSizes(options.maxInitialSize || options.maxSize),
maxAsyncSize: normalizeSizes(options.maxAsyncSize || options.maxSize),
maxInitialSize: normalizeSizes(options.maxInitialSize || options.maxSize),
minChunks: options.minChunks || 1,
maxAsyncRequests: options.maxAsyncRequests || 1,
maxInitialRequests: options.maxInitialRequests || 1,
Expand All @@ -500,7 +512,18 @@ module.exports = class SplitChunksPlugin {
automaticNameDelimiter: options.automaticNameDelimiter,
fallbackCacheGroup: {
minSize: mergeSizes(fallbackCacheGroup.minSize, options.minSize),
maxSize: mergeSizes(fallbackCacheGroup.maxSize, options.maxSize),
maxAsyncSize: mergeSizes(
fallbackCacheGroup.maxAsyncSize,
fallbackCacheGroup.maxSize,
options.maxAsyncSize,
options.maxSize
),
maxInitialSize: mergeSizes(
fallbackCacheGroup.maxInitialSize,
fallbackCacheGroup.maxSize,
options.maxInitialSize,
options.maxSize
),
automaticNameDelimiter:
fallbackCacheGroup.automaticNameDelimiter ||
options.automaticNameDelimiter ||
Expand Down Expand Up @@ -754,30 +777,22 @@ module.exports = class SplitChunksPlugin {
cacheGroupSource.chunksFilter || this.options.chunksFilter,
minSize: mergeSizes(
cacheGroupSource.minSize,
cacheGroupSource.enforce
? Object.create(null)
: this.options.minSize
cacheGroupSource.enforce ? undefined : this.options.minSize
),
minSizeForMaxSize: mergeSizes(
cacheGroupSource.minSize,
this.options.minSize
),
maxSize: mergeSizes(
cacheGroupSource.maxSize,
cacheGroupSource.enforce
? Object.create(null)
: this.options.maxSize
),
maxAsyncSize: mergeSizes(
cacheGroupSource.maxSize,
cacheGroupSource.maxAsyncSize,
cacheGroupSource.enforce
? Object.create(null)
? undefined
: this.options.maxAsyncSize
),
maxInitialSize: mergeSizes(
cacheGroupSource.maxSize,
cacheGroupSource.maxInitialSize,
cacheGroupSource.enforce
? Object.create(null)
? undefined
: this.options.maxInitialSize
),
minChunks:
Expand Down Expand Up @@ -853,7 +868,8 @@ module.exports = class SplitChunksPlugin {
/**
* @typedef {Object} MaxSizeQueueItem
* @property {SplitChunksSizes} minSize
* @property {SplitChunksSizes} maxSize
* @property {SplitChunksSizes} maxAsyncSize
* @property {SplitChunksSizes} maxInitialSize
* @property {string} automaticNameDelimiter
* @property {string[]} keys
*/
Expand Down Expand Up @@ -891,12 +907,16 @@ module.exports = class SplitChunksPlugin {
if (
chunkGraph.getNumberOfChunkModules(chunk) !==
item.modules.size
)
) {
continue;
}
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
continue;
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) continue;
}
for (const module of item.modules) {
if (!chunkGraph.isModuleInChunk(module, chunk))
if (!chunkGraph.isModuleInChunk(module, chunk)) {
continue outer;
}
}
if (!newChunk || !newChunk.name) {
newChunk = chunk;
Expand Down Expand Up @@ -1025,7 +1045,10 @@ module.exports = class SplitChunksPlugin {
}
}

if (Object.keys(item.cacheGroup.maxSize).length > 0) {
if (
Object.keys(item.cacheGroup.maxAsyncSize).length > 0 ||
Object.keys(item.cacheGroup.maxInitialSize).length > 0
) {
const oldMaxSizeSettings = maxSizeQueueMap.get(newChunk);
maxSizeQueueMap.set(newChunk, {
minSize: oldMaxSizeSettings
Expand All @@ -1035,13 +1058,20 @@ module.exports = class SplitChunksPlugin {
Math.max
)
: item.cacheGroup.minSize,
maxSize: oldMaxSizeSettings
maxAsyncSize: oldMaxSizeSettings
? combineSizes(
oldMaxSizeSettings.maxSize,
item.cacheGroup.maxSize,
oldMaxSizeSettings.maxAsyncSize,
item.cacheGroup.maxAsyncSize,
Math.min
)
: item.cacheGroup.maxSize,
: item.cacheGroup.maxAsyncSize,
maxInitialSize: oldMaxSizeSettings
? combineSizes(
oldMaxSizeSettings.maxInitialSize,
item.cacheGroup.maxInitialSize,
Math.min
)
: item.cacheGroup.maxInitialSize,
automaticNameDelimiter: item.cacheGroup.automaticNameDelimiter,
keys: oldMaxSizeSettings
? oldMaxSizeSettings.keys.concat(item.cacheGroup.key)
Expand Down Expand Up @@ -1095,9 +1125,24 @@ module.exports = class SplitChunksPlugin {
// Make sure that maxSize is fulfilled
for (const chunk of Array.from(compilation.chunks)) {
const chunkConfig = maxSizeQueueMap.get(chunk);
const { minSize, maxSize, automaticNameDelimiter } =
chunkConfig || this.options.fallbackCacheGroup;
if (!maxSize || Object.keys(maxSize).length === 0) continue;
const {
minSize,
maxAsyncSize,
maxInitialSize,
automaticNameDelimiter
} = chunkConfig || this.options.fallbackCacheGroup;
/** @type {SplitChunksSizes} */
let maxSize;
if (chunk.isOnlyInitial()) {
maxSize = maxInitialSize;
} else if (chunk.canBeInitial()) {
maxSize = combineSizes(maxAsyncSize, maxInitialSize, Math.min);
} else {
maxSize = maxAsyncSize;
}
if (Object.keys(maxSize).length === 0) {
continue;
}
for (const key of Object.keys(maxSize)) {
const maxSizeValue = maxSize[key];
const minSizeValue = minSize[key];
Expand Down
32 changes: 32 additions & 0 deletions schemas/WebpackOptions.json
Original file line number Diff line number Diff line change
Expand Up @@ -605,11 +605,27 @@
"type": "number",
"minimum": 1
},
"maxAsyncSize": {
"description": "Maximal size hint for the on-demand chunks",
"oneOf": [
{
"$ref": "#/definitions/OptimizationSplitChunksSizes"
}
]
},
"maxInitialRequests": {
"description": "Maximum number of initial chunks which are accepted for an entry point",
"type": "number",
"minimum": 1
},
"maxInitialSize": {
"description": "Maximal size hint for the initial chunks",
"oneOf": [
{
"$ref": "#/definitions/OptimizationSplitChunksSizes"
}
]
},
"maxSize": {
"description": "Maximal size hint for the created chunks",
"oneOf": [
Expand Down Expand Up @@ -745,6 +761,22 @@
"type": "string",
"minLength": 1
},
"maxAsyncSize": {
"description": "Maximal size hint for the on-demand chunks",
"oneOf": [
{
"$ref": "#/definitions/OptimizationSplitChunksSizes"
}
]
},
"maxInitialSize": {
"description": "Maximal size hint for the initial chunks",
"oneOf": [
{
"$ref": "#/definitions/OptimizationSplitChunksSizes"
}
]
},
"maxSize": {
"description": "Maximal size hint for the created chunks",
"oneOf": [
Expand Down

0 comments on commit 2a10b12

Please sign in to comment.