/* MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ "use strict"; const validateOptions = require("schema-utils"); const schema = require("../../schemas/plugins/optimize/LimitChunkCountPlugin.json"); /** @typedef {import("../../declarations/plugins/optimize/LimitChunkCountPlugin").LimitChunkCountPluginOptions} LimitChunkCountPluginOptions */ class LimitChunkCountPlugin { /** * @param {LimitChunkCountPluginOptions=} options options object */ constructor(options) { if (!options) options = {}; validateOptions(schema, options, "Limit Chunk Count Plugin"); this.options = options; } apply(compiler) { const options = this.options; compiler.hooks.compilation.tap("LimitChunkCountPlugin", compilation => { compilation.hooks.optimizeChunksAdvanced.tap( "LimitChunkCountPlugin", chunks => { const maxChunks = options.maxChunks; if (!maxChunks) return; if (maxChunks < 1) return; if (chunks.length <= maxChunks) return; const orderedChunks = chunks.slice().sort((a, b) => a.compareTo(b)); const sortedExtendedPairCombinations = orderedChunks .reduce((combinations, a, idx) => { // create combination pairs for (let i = 0; i < idx; i++) { const b = orderedChunks[i]; combinations.push([b, a]); } return combinations; }, []) .map(pair => { // extend combination pairs with size and integrated size const a = pair[0].size(options); const b = pair[1].size(options); const ab = pair[0].integratedSize(pair[1], options); return [a + b - ab, ab, pair[0], pair[1], a, b]; }) .filter(extendedPair => { // filter pairs that do not have an integratedSize // meaning they can NOT be integrated! return extendedPair[1] !== false; }) .sort((a, b) => { // sadly javascript does an inplace sort here // sort them by size const diff1 = b[0] - a[0]; if (diff1 !== 0) return diff1; const diff2 = a[1] - b[1]; if (diff2 !== 0) return diff2; const diff3 = a[2].compareTo(b[2]); if (diff3 !== 0) return diff3; return a[3].compareTo(b[3]); }); const pair = sortedExtendedPairCombinations[0]; if (pair && pair[2].integrate(pair[3], "limit")) { chunks.splice(chunks.indexOf(pair[3]), 1); return true; } } ); }); } } module.exports = LimitChunkCountPlugin;