[79a0317] | 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;
|
---|