webpack/lib/optimize/AggressiveMergingPlugin.js

92 lines
2.3 KiB
JavaScript
Raw Normal View History

/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
2018-07-30 23:08:51 +08:00
"use strict";
const { STAGE_ADVANCED } = require("../OptimizationStages");
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Compiler")} Compiler */
class AggressiveMergingPlugin {
constructor(options) {
2018-02-25 09:00:20 +08:00
if (
(options !== undefined && typeof options !== "object") ||
Array.isArray(options)
) {
throw new Error(
"Argument should be an options object. To use defaults, pass in nothing.\nFor more info on options, see https://webpack.js.org/plugins/"
);
}
this.options = options || {};
}
/**
* @param {Compiler} compiler webpack compiler
* @returns {void}
*/
apply(compiler) {
const options = this.options;
const minSizeReduce = options.minSizeReduce || 1.5;
2018-02-25 09:00:20 +08:00
compiler.hooks.thisCompilation.tap(
"AggressiveMergingPlugin",
compilation => {
compilation.hooks.optimizeChunks.tap(
/** @type {TODO} */ ({
name: "AggressiveMergingPlugin",
stage: STAGE_ADVANCED
}),
2018-02-25 09:00:20 +08:00
chunks => {
const chunkGraph = compilation.chunkGraph;
/** @type {{a: Chunk, b: Chunk, improvement: number}[]} */
2018-02-25 09:00:20 +08:00
let combinations = [];
chunks.forEach((a, idx) => {
if (a.canBeInitial()) return;
for (let i = 0; i < idx; i++) {
const b = chunks[i];
if (b.canBeInitial()) continue;
if (!chunkGraph.canChunksBeIntegrated(a, b)) {
continue;
}
const aSize = chunkGraph.getChunkSize(b, {
chunkOverhead: 0
});
const bSize = chunkGraph.getChunkSize(a, {
chunkOverhead: 0
});
const abSize = chunkGraph.getIntegratedChunksSize(b, a, {
chunkOverhead: 0
});
const improvement = (aSize + bSize) / abSize;
2018-02-25 09:00:20 +08:00
combinations.push({
a,
b,
improvement
2018-02-25 09:00:20 +08:00
});
}
2017-07-19 02:18:30 +08:00
});
2018-02-25 09:00:20 +08:00
combinations.sort((a, b) => {
return b.improvement - a.improvement;
});
2018-02-25 09:00:20 +08:00
const pair = combinations[0];
2018-02-25 09:00:20 +08:00
if (!pair) return;
if (pair.improvement < minSizeReduce) return;
chunkGraph.integrateChunks(pair.b, pair.a);
chunks.splice(chunks.indexOf(pair.a), 1);
return true;
2018-02-25 09:00:20 +08:00
}
);
}
);
}
}
module.exports = AggressiveMergingPlugin;