You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
2.5 KiB

4 years ago
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const validateOptions = require("schema-utils");
  7. const schema = require("../../schemas/plugins/optimize/MinChunkSizePlugin.json");
  8. /** @typedef {import("../../declarations/plugins/optimize/MinChunkSizePlugin").MinChunkSizePluginOptions} MinChunkSizePluginOptions */
  9. class MinChunkSizePlugin {
  10. /**
  11. * @param {MinChunkSizePluginOptions} options options object
  12. */
  13. constructor(options) {
  14. validateOptions(schema, options, "Min Chunk Size Plugin");
  15. this.options = options;
  16. }
  17. apply(compiler) {
  18. const options = this.options;
  19. const minChunkSize = options.minChunkSize;
  20. compiler.hooks.compilation.tap("MinChunkSizePlugin", compilation => {
  21. compilation.hooks.optimizeChunksAdvanced.tap(
  22. "MinChunkSizePlugin",
  23. chunks => {
  24. const equalOptions = {
  25. chunkOverhead: 1,
  26. entryChunkMultiplicator: 1
  27. };
  28. const sortedSizeFilteredExtendedPairCombinations = chunks
  29. .reduce((combinations, a, idx) => {
  30. // create combination pairs
  31. for (let i = 0; i < idx; i++) {
  32. const b = chunks[i];
  33. combinations.push([b, a]);
  34. }
  35. return combinations;
  36. }, [])
  37. .filter(pair => {
  38. // check if one of the chunks sizes is smaller than the minChunkSize
  39. const p0SmallerThanMinChunkSize =
  40. pair[0].size(equalOptions) < minChunkSize;
  41. const p1SmallerThanMinChunkSize =
  42. pair[1].size(equalOptions) < minChunkSize;
  43. return p0SmallerThanMinChunkSize || p1SmallerThanMinChunkSize;
  44. })
  45. .map(pair => {
  46. // extend combination pairs with size and integrated size
  47. const a = pair[0].size(options);
  48. const b = pair[1].size(options);
  49. const ab = pair[0].integratedSize(pair[1], options);
  50. return [a + b - ab, ab, pair[0], pair[1]];
  51. })
  52. .filter(pair => {
  53. // filter pairs that do not have an integratedSize
  54. // meaning they can NOT be integrated!
  55. return pair[1] !== false;
  56. })
  57. .sort((a, b) => {
  58. // sadly javascript does an inplace sort here
  59. // sort by size
  60. const diff = b[0] - a[0];
  61. if (diff !== 0) return diff;
  62. return a[1] - b[1];
  63. });
  64. if (sortedSizeFilteredExtendedPairCombinations.length === 0) return;
  65. const pair = sortedSizeFilteredExtendedPairCombinations[0];
  66. pair[2].integrate(pair[3], "min-size");
  67. chunks.splice(chunks.indexOf(pair[3]), 1);
  68. return true;
  69. }
  70. );
  71. });
  72. }
  73. }
  74. module.exports = MinChunkSizePlugin;