ContextDependency.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const Dependency = require("../Dependency");
  7. const DependencyTemplate = require("../DependencyTemplate");
  8. const makeSerializable = require("../util/makeSerializable");
  9. const memoize = require("../util/memoize");
  10. /** @typedef {import("../ContextModule").ContextOptions} ContextOptions */
  11. /** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */
  12. /** @typedef {import("../ModuleGraph")} ModuleGraph */
  13. /** @typedef {import("../WebpackError")} WebpackError */
  14. const getCriticalDependencyWarning = memoize(() =>
  15. require("./CriticalDependencyWarning")
  16. );
  17. /** @typedef {ContextOptions & { request: string }} ContextDependencyOptions */
  18. const regExpToString = r => (r ? r + "" : "");
  19. class ContextDependency extends Dependency {
  20. /**
  21. * @param {ContextDependencyOptions} options options for the context module
  22. * @param {string=} context request context
  23. */
  24. constructor(options, context) {
  25. super();
  26. this.options = options;
  27. this.userRequest = this.options && this.options.request;
  28. /** @type {false | string} */
  29. this.critical = false;
  30. this.hadGlobalOrStickyRegExp = false;
  31. if (
  32. this.options &&
  33. (this.options.regExp.global || this.options.regExp.sticky)
  34. ) {
  35. this.options = { ...this.options, regExp: null };
  36. this.hadGlobalOrStickyRegExp = true;
  37. }
  38. this.request = undefined;
  39. this.range = undefined;
  40. this.valueRange = undefined;
  41. this.inShorthand = undefined;
  42. // TODO refactor this
  43. this.replaces = undefined;
  44. this._requestContext = context;
  45. }
  46. /**
  47. * @returns {string | undefined} a request context
  48. */
  49. getContext() {
  50. return this._requestContext;
  51. }
  52. get category() {
  53. return "commonjs";
  54. }
  55. /**
  56. * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module
  57. */
  58. couldAffectReferencingModule() {
  59. return true;
  60. }
  61. /**
  62. * @returns {string | null} an identifier to merge equal requests
  63. */
  64. getResourceIdentifier() {
  65. return (
  66. `context${this._requestContext || ""}|ctx request${
  67. this.options.request
  68. } ${this.options.recursive} ` +
  69. `${regExpToString(this.options.regExp)} ${regExpToString(
  70. this.options.include
  71. )} ${regExpToString(this.options.exclude)} ` +
  72. `${this.options.mode} ${this.options.chunkName} ` +
  73. `${JSON.stringify(this.options.groupOptions)}`
  74. );
  75. }
  76. /**
  77. * Returns warnings
  78. * @param {ModuleGraph} moduleGraph module graph
  79. * @returns {WebpackError[]} warnings
  80. */
  81. getWarnings(moduleGraph) {
  82. let warnings = super.getWarnings(moduleGraph);
  83. if (this.critical) {
  84. if (!warnings) warnings = [];
  85. const CriticalDependencyWarning = getCriticalDependencyWarning();
  86. warnings.push(new CriticalDependencyWarning(this.critical));
  87. }
  88. if (this.hadGlobalOrStickyRegExp) {
  89. if (!warnings) warnings = [];
  90. const CriticalDependencyWarning = getCriticalDependencyWarning();
  91. warnings.push(
  92. new CriticalDependencyWarning(
  93. "Contexts can't use RegExps with the 'g' or 'y' flags."
  94. )
  95. );
  96. }
  97. return warnings;
  98. }
  99. serialize(context) {
  100. const { write } = context;
  101. write(this.options);
  102. write(this.userRequest);
  103. write(this.critical);
  104. write(this.hadGlobalOrStickyRegExp);
  105. write(this.request);
  106. write(this._requestContext);
  107. write(this.range);
  108. write(this.valueRange);
  109. write(this.prepend);
  110. write(this.replaces);
  111. super.serialize(context);
  112. }
  113. deserialize(context) {
  114. const { read } = context;
  115. this.options = read();
  116. this.userRequest = read();
  117. this.critical = read();
  118. this.hadGlobalOrStickyRegExp = read();
  119. this.request = read();
  120. this._requestContext = read();
  121. this.range = read();
  122. this.valueRange = read();
  123. this.prepend = read();
  124. this.replaces = read();
  125. super.deserialize(context);
  126. }
  127. }
  128. makeSerializable(
  129. ContextDependency,
  130. "webpack/lib/dependencies/ContextDependency"
  131. );
  132. ContextDependency.Template = DependencyTemplate;
  133. module.exports = ContextDependency;