webpack/lib/optimize/AggressiveMergingPlugin.js

99 lines
2.4 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 */
2023-06-04 01:52:25 +08:00
/**
2024-06-11 21:09:50 +08:00
* @typedef {object} AggressiveMergingPluginOptions
2023-06-04 01:52:25 +08:00
* @property {number=} minSizeReduce minimal size reduction to trigger merging
*/
class AggressiveMergingPlugin {
2023-06-04 01:52:25 +08:00
/**
2025-04-16 22:04:11 +08:00
* @param {AggressiveMergingPluginOptions=} options options object
2023-06-04 01:52:25 +08:00
*/
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 || {};
}
/**
2020-04-23 16:48:36 +08:00
* Apply the plugin
* @param {Compiler} compiler the compiler instance
* @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(
2018-12-09 19:54:17 +08:00
{
name: "AggressiveMergingPlugin",
stage: STAGE_ADVANCED
2018-12-09 19:54:17 +08:00
},
2018-02-25 09:00:20 +08:00
chunks => {
const chunkGraph = compilation.chunkGraph;
/** @type {{a: Chunk, b: Chunk, improvement: number}[]} */
2024-07-31 04:09:42 +08:00
const combinations = [];
2018-09-06 22:59:11 +08:00
for (const a of chunks) {
if (a.canBeInitial()) continue;
for (const b of chunks) {
2018-02-25 09:00:20 +08:00
if (b.canBeInitial()) continue;
2018-09-06 22:59:11 +08:00
if (b === a) break;
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
});
}
2018-09-06 22:59:11 +08:00
}
2024-07-31 11:31:11 +08:00
combinations.sort((a, b) => 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);
2018-09-06 22:59:11 +08:00
compilation.chunks.delete(pair.a);
return true;
2018-02-25 09:00:20 +08:00
}
);
}
);
}
}
module.exports = AggressiveMergingPlugin;