UNPKG

2.3 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const { STAGE_ADVANCED } = require("../OptimizationStages");
9
10/** @typedef {import("../Chunk")} Chunk */
11/** @typedef {import("../Compiler")} Compiler */
12
13class AggressiveMergingPlugin {
14 constructor(options) {
15 if (
16 (options !== undefined && typeof options !== "object") ||
17 Array.isArray(options)
18 ) {
19 throw new Error(
20 "Argument should be an options object. To use defaults, pass in nothing.\nFor more info on options, see https://webpack.js.org/plugins/"
21 );
22 }
23 this.options = options || {};
24 }
25
26 /**
27 * Apply the plugin
28 * @param {Compiler} compiler the compiler instance
29 * @returns {void}
30 */
31 apply(compiler) {
32 const options = this.options;
33 const minSizeReduce = options.minSizeReduce || 1.5;
34
35 compiler.hooks.thisCompilation.tap(
36 "AggressiveMergingPlugin",
37 compilation => {
38 compilation.hooks.optimizeChunks.tap(
39 {
40 name: "AggressiveMergingPlugin",
41 stage: STAGE_ADVANCED
42 },
43 chunks => {
44 const chunkGraph = compilation.chunkGraph;
45 /** @type {{a: Chunk, b: Chunk, improvement: number}[]} */
46 let combinations = [];
47 for (const a of chunks) {
48 if (a.canBeInitial()) continue;
49 for (const b of chunks) {
50 if (b.canBeInitial()) continue;
51 if (b === a) break;
52 if (!chunkGraph.canChunksBeIntegrated(a, b)) {
53 continue;
54 }
55 const aSize = chunkGraph.getChunkSize(b, {
56 chunkOverhead: 0
57 });
58 const bSize = chunkGraph.getChunkSize(a, {
59 chunkOverhead: 0
60 });
61 const abSize = chunkGraph.getIntegratedChunksSize(b, a, {
62 chunkOverhead: 0
63 });
64 const improvement = (aSize + bSize) / abSize;
65 combinations.push({
66 a,
67 b,
68 improvement
69 });
70 }
71 }
72
73 combinations.sort((a, b) => {
74 return b.improvement - a.improvement;
75 });
76
77 const pair = combinations[0];
78
79 if (!pair) return;
80 if (pair.improvement < minSizeReduce) return;
81
82 chunkGraph.integrateChunks(pair.b, pair.a);
83 compilation.chunks.delete(pair.a);
84 return true;
85 }
86 );
87 }
88 );
89 }
90}
91
92module.exports = AggressiveMergingPlugin;