1 | /*
|
---|
2 | MIT License http://www.opensource.org/licenses/mit-license.php
|
---|
3 | Author Tobias Koppers @sokra
|
---|
4 | */
|
---|
5 |
|
---|
6 | "use strict";
|
---|
7 |
|
---|
8 | const { STAGE_ADVANCED } = require("../OptimizationStages");
|
---|
9 | const createSchemaValidation = require("../util/create-schema-validation");
|
---|
10 |
|
---|
11 | /** @typedef {import("../../declarations/plugins/optimize/MinChunkSizePlugin").MinChunkSizePluginOptions} MinChunkSizePluginOptions */
|
---|
12 | /** @typedef {import("../Chunk")} Chunk */
|
---|
13 | /** @typedef {import("../Compiler")} Compiler */
|
---|
14 |
|
---|
15 | const validate = createSchemaValidation(
|
---|
16 | require("../../schemas/plugins/optimize/MinChunkSizePlugin.check.js"),
|
---|
17 | () => require("../../schemas/plugins/optimize/MinChunkSizePlugin.json"),
|
---|
18 | {
|
---|
19 | name: "Min Chunk Size Plugin",
|
---|
20 | baseDataPath: "options"
|
---|
21 | }
|
---|
22 | );
|
---|
23 |
|
---|
24 | class MinChunkSizePlugin {
|
---|
25 | /**
|
---|
26 | * @param {MinChunkSizePluginOptions} options options object
|
---|
27 | */
|
---|
28 | constructor(options) {
|
---|
29 | validate(options);
|
---|
30 | this.options = options;
|
---|
31 | }
|
---|
32 |
|
---|
33 | /**
|
---|
34 | * Apply the plugin
|
---|
35 | * @param {Compiler} compiler the compiler instance
|
---|
36 | * @returns {void}
|
---|
37 | */
|
---|
38 | apply(compiler) {
|
---|
39 | const options = this.options;
|
---|
40 | const minChunkSize = options.minChunkSize;
|
---|
41 | compiler.hooks.compilation.tap("MinChunkSizePlugin", compilation => {
|
---|
42 | compilation.hooks.optimizeChunks.tap(
|
---|
43 | {
|
---|
44 | name: "MinChunkSizePlugin",
|
---|
45 | stage: STAGE_ADVANCED
|
---|
46 | },
|
---|
47 | chunks => {
|
---|
48 | const chunkGraph = compilation.chunkGraph;
|
---|
49 | const equalOptions = {
|
---|
50 | chunkOverhead: 1,
|
---|
51 | entryChunkMultiplicator: 1
|
---|
52 | };
|
---|
53 |
|
---|
54 | const chunkSizesMap = new Map();
|
---|
55 | /** @type {[Chunk, Chunk][]} */
|
---|
56 | const combinations = [];
|
---|
57 | /** @type {Chunk[]} */
|
---|
58 | const smallChunks = [];
|
---|
59 | const visitedChunks = [];
|
---|
60 | for (const a of chunks) {
|
---|
61 | // check if one of the chunks sizes is smaller than the minChunkSize
|
---|
62 | // and filter pairs that can NOT be integrated!
|
---|
63 | if (chunkGraph.getChunkSize(a, equalOptions) < minChunkSize) {
|
---|
64 | smallChunks.push(a);
|
---|
65 | for (const b of visitedChunks) {
|
---|
66 | if (chunkGraph.canChunksBeIntegrated(b, a))
|
---|
67 | combinations.push([b, a]);
|
---|
68 | }
|
---|
69 | } else {
|
---|
70 | for (const b of smallChunks) {
|
---|
71 | if (chunkGraph.canChunksBeIntegrated(b, a))
|
---|
72 | combinations.push([b, a]);
|
---|
73 | }
|
---|
74 | }
|
---|
75 | chunkSizesMap.set(a, chunkGraph.getChunkSize(a, options));
|
---|
76 | visitedChunks.push(a);
|
---|
77 | }
|
---|
78 |
|
---|
79 | const sortedSizeFilteredExtendedPairCombinations = combinations
|
---|
80 | .map(pair => {
|
---|
81 | // extend combination pairs with size and integrated size
|
---|
82 | const a = chunkSizesMap.get(pair[0]);
|
---|
83 | const b = chunkSizesMap.get(pair[1]);
|
---|
84 | const ab = chunkGraph.getIntegratedChunksSize(
|
---|
85 | pair[0],
|
---|
86 | pair[1],
|
---|
87 | options
|
---|
88 | );
|
---|
89 | /** @type {[number, number, Chunk, Chunk]} */
|
---|
90 | const extendedPair = [a + b - ab, ab, pair[0], pair[1]];
|
---|
91 | return extendedPair;
|
---|
92 | })
|
---|
93 | .sort((a, b) => {
|
---|
94 | // sadly javascript does an in place sort here
|
---|
95 | // sort by size
|
---|
96 | const diff = b[0] - a[0];
|
---|
97 | if (diff !== 0) return diff;
|
---|
98 | return a[1] - b[1];
|
---|
99 | });
|
---|
100 |
|
---|
101 | if (sortedSizeFilteredExtendedPairCombinations.length === 0) return;
|
---|
102 |
|
---|
103 | const pair = sortedSizeFilteredExtendedPairCombinations[0];
|
---|
104 |
|
---|
105 | chunkGraph.integrateChunks(pair[2], pair[3]);
|
---|
106 | compilation.chunks.delete(pair[3]);
|
---|
107 | return true;
|
---|
108 | }
|
---|
109 | );
|
---|
110 | });
|
---|
111 | }
|
---|
112 | }
|
---|
113 | module.exports = MinChunkSizePlugin;
|
---|