MinChunkSizePlugin.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. class MinChunkSizePlugin {
  9. constructor(options) {
  10. validateOptions(schema, options, "Min Chunk Size Plugin");
  11. this.options = options;
  12. }
  13. apply(compiler) {
  14. const options = this.options;
  15. const minChunkSize = options.minChunkSize;
  16. compiler.hooks.compilation.tap("MinChunkSizePlugin", compilation => {
  17. compilation.hooks.optimizeChunksAdvanced.tap(
  18. "MinChunkSizePlugin",
  19. chunks => {
  20. const equalOptions = {
  21. chunkOverhead: 1,
  22. entryChunkMultiplicator: 1
  23. };
  24. const sortedSizeFilteredExtendedPairCombinations = chunks
  25. .reduce((combinations, a, idx) => {
  26. // create combination pairs
  27. for (let i = 0; i < idx; i++) {
  28. const b = chunks[i];
  29. combinations.push([b, a]);
  30. }
  31. return combinations;
  32. }, [])
  33. .filter(pair => {
  34. // check if one of the chunks sizes is smaller than the minChunkSize
  35. const p0SmallerThanMinChunkSize =
  36. pair[0].size(equalOptions) < minChunkSize;
  37. const p1SmallerThanMinChunkSize =
  38. pair[1].size(equalOptions) < minChunkSize;
  39. return p0SmallerThanMinChunkSize || p1SmallerThanMinChunkSize;
  40. })
  41. .map(pair => {
  42. // extend combination pairs with size and integrated size
  43. const a = pair[0].size(options);
  44. const b = pair[1].size(options);
  45. const ab = pair[0].integratedSize(pair[1], options);
  46. return [a + b - ab, ab, pair[0], pair[1]];
  47. })
  48. .filter(pair => {
  49. // filter pairs that do not have an integratedSize
  50. // meaning they can NOT be integrated!
  51. return pair[1] !== false;
  52. })
  53. .sort((a, b) => {
  54. // sadly javascript does an inplace sort here
  55. // sort by size
  56. const diff = b[0] - a[0];
  57. if (diff !== 0) return diff;
  58. return a[1] - b[1];
  59. });
  60. if (sortedSizeFilteredExtendedPairCombinations.length === 0) return;
  61. const pair = sortedSizeFilteredExtendedPairCombinations[0];
  62. pair[2].integrate(pair[3], "min-size");
  63. chunks.splice(chunks.indexOf(pair[3]), 1);
  64. return true;
  65. }
  66. );
  67. });
  68. }
  69. }
  70. module.exports = MinChunkSizePlugin;