DependenciesBlock.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const makeSerializable = require("./util/makeSerializable");
  7. /** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
  8. /** @typedef {import("./Dependency")} Dependency */
  9. /** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
  10. /** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
  11. /** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
  12. /** @typedef {import("./util/Hash")} Hash */
  13. /** @typedef {(d: Dependency) => boolean} DependencyFilterFunction */
  14. /**
  15. * DependenciesBlock is the base class for all Module classes in webpack. It describes a
  16. * "block" of dependencies which are pointers to other DependenciesBlock instances. For example
  17. * when a Module has a CommonJs require statement, the DependencyBlock for the CommonJs module
  18. * would be added as a dependency to the Module. DependenciesBlock is inherited by two types of classes:
  19. * Module subclasses and AsyncDependenciesBlock subclasses. The only difference between the two is that
  20. * AsyncDependenciesBlock subclasses are used for code-splitting (async boundary) and Module subclasses are not.
  21. */
  22. class DependenciesBlock {
  23. constructor() {
  24. /** @type {Dependency[]} */
  25. this.dependencies = [];
  26. /** @type {AsyncDependenciesBlock[]} */
  27. this.blocks = [];
  28. /** @type {DependenciesBlock | undefined} */
  29. this.parent = undefined;
  30. }
  31. getRootBlock() {
  32. /** @type {DependenciesBlock} */
  33. let current = this;
  34. while (current.parent) current = current.parent;
  35. return current;
  36. }
  37. /**
  38. * Adds a DependencyBlock to DependencyBlock relationship.
  39. * This is used for when a Module has a AsyncDependencyBlock tie (for code-splitting)
  40. * @param {AsyncDependenciesBlock} block block being added
  41. * @returns {void}
  42. */
  43. addBlock(block) {
  44. this.blocks.push(block);
  45. block.parent = this;
  46. }
  47. /**
  48. * Adds the provided dependency to the dependencies block.
  49. * @param {Dependency} dependency dependency being tied to block.
  50. * This is an "edge" pointing to another "node" on module graph.
  51. * @returns {void}
  52. */
  53. addDependency(dependency) {
  54. this.dependencies.push(dependency);
  55. }
  56. /**
  57. * Removes dependency.
  58. * @param {Dependency} dependency dependency being removed
  59. * @returns {void}
  60. */
  61. removeDependency(dependency) {
  62. const idx = this.dependencies.indexOf(dependency);
  63. if (idx >= 0) {
  64. this.dependencies.splice(idx, 1);
  65. }
  66. }
  67. /**
  68. * Clear dependencies and blocks.
  69. * @returns {void}
  70. */
  71. clearDependenciesAndBlocks() {
  72. this.dependencies.length = 0;
  73. this.blocks.length = 0;
  74. }
  75. /**
  76. * Updates the hash with the data contributed by this instance.
  77. * @param {Hash} hash the hash used to track dependencies
  78. * @param {UpdateHashContext} context context
  79. * @returns {void}
  80. */
  81. updateHash(hash, context) {
  82. for (const dep of this.dependencies) {
  83. dep.updateHash(hash, context);
  84. }
  85. for (const block of this.blocks) {
  86. block.updateHash(hash, context);
  87. }
  88. }
  89. /**
  90. * Serializes this instance into the provided serializer context.
  91. * @param {ObjectSerializerContext} context context
  92. */
  93. serialize({ write }) {
  94. write(this.dependencies);
  95. write(this.blocks);
  96. }
  97. /**
  98. * Restores this instance from the provided deserializer context.
  99. * @param {ObjectDeserializerContext} context context
  100. */
  101. deserialize({ read }) {
  102. this.dependencies = read();
  103. this.blocks = read();
  104. for (const block of this.blocks) {
  105. block.parent = this;
  106. }
  107. }
  108. }
  109. makeSerializable(DependenciesBlock, "webpack/lib/DependenciesBlock");
  110. module.exports = DependenciesBlock;