OccurrenceChunkIdsPlugin.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { compareChunksNatural } = require("../util/comparators");
  7. const { assignAscendingChunkIds } = require("./IdHelpers");
  8. /**
  9. * @import {
  10. * OccurrenceChunkIdsPluginOptions
  11. * } from "../../declarations/plugins/ids/OccurrenceChunkIdsPlugin"
  12. */
  13. /** @import Chunk from "../Chunk" */
  14. /** @import Compiler from "../Compiler" */
  15. const PLUGIN_NAME = "OccurrenceChunkIdsPlugin";
  16. class OccurrenceChunkIdsPlugin {
  17. /**
  18. * Creates an instance of OccurrenceChunkIdsPlugin.
  19. * @param {OccurrenceChunkIdsPluginOptions=} options options object
  20. */
  21. constructor(options = {}) {
  22. /** @type {OccurrenceChunkIdsPluginOptions} */
  23. this.options = options;
  24. }
  25. /**
  26. * Applies the plugin by registering its hooks on the compiler.
  27. * @param {Compiler} compiler the compiler instance
  28. * @returns {void}
  29. */
  30. apply(compiler) {
  31. compiler.hooks.validate.tap(PLUGIN_NAME, () => {
  32. compiler.validate(
  33. () =>
  34. require("../../schemas/plugins/ids/OccurrenceChunkIdsPlugin.json"),
  35. this.options,
  36. {
  37. name: "Occurrence Order Chunk Ids Plugin",
  38. baseDataPath: "options"
  39. },
  40. (options) =>
  41. require("../../schemas/plugins/ids/OccurrenceChunkIdsPlugin.check")(
  42. options
  43. )
  44. );
  45. });
  46. compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
  47. compilation.hooks.chunkIds.tap(PLUGIN_NAME, (chunks) => {
  48. const chunkGraph = compilation.chunkGraph;
  49. /** @type {Map<Chunk, number>} */
  50. const occursInInitialChunksMap = new Map();
  51. const compareNatural = compareChunksNatural(chunkGraph);
  52. for (const c of chunks) {
  53. let occurs = 0;
  54. for (const chunkGroup of c.groupsIterable) {
  55. for (const parent of chunkGroup.parentsIterable) {
  56. if (parent.isInitial()) occurs++;
  57. }
  58. }
  59. occursInInitialChunksMap.set(c, occurs);
  60. }
  61. /** @type {Chunk[]} */
  62. const chunksInOccurrenceOrder = [...chunks].sort((a, b) => {
  63. if (this.options.prioritiseInitial) {
  64. const aEntryOccurs =
  65. /** @type {number} */
  66. (occursInInitialChunksMap.get(a));
  67. const bEntryOccurs =
  68. /** @type {number} */
  69. (occursInInitialChunksMap.get(b));
  70. if (aEntryOccurs > bEntryOccurs) return -1;
  71. if (aEntryOccurs < bEntryOccurs) return 1;
  72. }
  73. const aOccurs = a.getNumberOfGroups();
  74. const bOccurs = b.getNumberOfGroups();
  75. if (aOccurs > bOccurs) return -1;
  76. if (aOccurs < bOccurs) return 1;
  77. return compareNatural(a, b);
  78. });
  79. assignAscendingChunkIds(chunksInOccurrenceOrder, compilation);
  80. });
  81. });
  82. }
  83. }
  84. module.exports = OccurrenceChunkIdsPlugin;