ContextDependency.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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("../javascript/JavascriptParser").Range} Range */
  11. /** @typedef {import("../ContextModule").ContextOptions} ContextOptions */
  12. /** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */
  13. /** @typedef {import("../ModuleGraph")} ModuleGraph */
  14. /** @typedef {import("../WebpackError")} WebpackError */
  15. /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
  16. /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
  17. const getCriticalDependencyWarning = memoize(() =>
  18. require("./CriticalDependencyWarning")
  19. );
  20. /** @typedef {ContextOptions & { request: string }} ContextDependencyOptions */
  21. /** @typedef {{ value: string, range: Range }[]} Replaces */
  22. /**
  23. * Returns stringified regexp.
  24. * @param {RegExp | false | null | undefined} r regexp
  25. * @returns {string} stringified regexp
  26. */
  27. const regExpToString = (r) => (r ? String(r) : "");
  28. class ContextDependency extends Dependency {
  29. /**
  30. * Creates an instance of ContextDependency.
  31. * @param {ContextDependencyOptions} options options for the context module
  32. * @param {string=} context request context
  33. */
  34. constructor(options, context) {
  35. super();
  36. this.options = options;
  37. this.userRequest = this.options && this.options.request;
  38. /** @type {false | undefined | string} */
  39. this.critical = false;
  40. this.hadGlobalOrStickyRegExp = false;
  41. if (
  42. this.options &&
  43. this.options.regExp &&
  44. (this.options.regExp.global || this.options.regExp.sticky)
  45. ) {
  46. this.options = { ...this.options, regExp: null };
  47. this.hadGlobalOrStickyRegExp = true;
  48. }
  49. /** @type {string | undefined} */
  50. this.request = undefined;
  51. /** @type {Range | undefined} */
  52. this.range = undefined;
  53. /** @type {Range | undefined} */
  54. this.valueRange = undefined;
  55. /** @type {boolean | string | undefined} */
  56. this.inShorthand = undefined;
  57. /** @type {Replaces | undefined} */
  58. this.replaces = undefined;
  59. this._requestContext = context;
  60. }
  61. /**
  62. * Returns a request context.
  63. * @returns {string | undefined} a request context
  64. */
  65. getContext() {
  66. return this._requestContext;
  67. }
  68. get category() {
  69. return "commonjs";
  70. }
  71. /**
  72. * Could affect referencing module.
  73. * @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
  74. */
  75. couldAffectReferencingModule() {
  76. return true;
  77. }
  78. /**
  79. * Returns an identifier to merge equal requests.
  80. * @returns {string | null} an identifier to merge equal requests
  81. */
  82. getResourceIdentifier() {
  83. return (
  84. `context${this._requestContext || ""}|ctx request${
  85. this.options.request
  86. } ${this.options.recursive} ` +
  87. `${regExpToString(this.options.regExp)} ${regExpToString(
  88. this.options.include
  89. )} ${regExpToString(this.options.exclude)} ` +
  90. `${this.options.mode} ${this.options.chunkName} ` +
  91. `${JSON.stringify(this.options.groupOptions)}` +
  92. `${
  93. this.options.referencedExports
  94. ? ` ${JSON.stringify(this.options.referencedExports)}`
  95. : ""
  96. }`
  97. );
  98. }
  99. /**
  100. * Returns warnings.
  101. * @param {ModuleGraph} moduleGraph module graph
  102. * @returns {WebpackError[] | null | undefined} warnings
  103. */
  104. getWarnings(moduleGraph) {
  105. let warnings = super.getWarnings(moduleGraph);
  106. if (this.critical) {
  107. if (!warnings) warnings = [];
  108. const CriticalDependencyWarning = getCriticalDependencyWarning();
  109. warnings.push(new CriticalDependencyWarning(this.critical));
  110. }
  111. if (this.hadGlobalOrStickyRegExp) {
  112. if (!warnings) warnings = [];
  113. const CriticalDependencyWarning = getCriticalDependencyWarning();
  114. warnings.push(
  115. new CriticalDependencyWarning(
  116. "Contexts can't use RegExps with the 'g' or 'y' flags."
  117. )
  118. );
  119. }
  120. return warnings;
  121. }
  122. /**
  123. * Serializes this instance into the provided serializer context.
  124. * @param {ObjectSerializerContext} context context
  125. */
  126. serialize(context) {
  127. const { write } = context;
  128. write(this.options);
  129. write(this.userRequest);
  130. write(this.critical);
  131. write(this.hadGlobalOrStickyRegExp);
  132. write(this.request);
  133. write(this._requestContext);
  134. write(this.range);
  135. write(this.valueRange);
  136. write(this.replaces);
  137. super.serialize(context);
  138. }
  139. /**
  140. * Restores this instance from the provided deserializer context.
  141. * @param {ObjectDeserializerContext} context context
  142. */
  143. deserialize(context) {
  144. const { read } = context;
  145. this.options = read();
  146. this.userRequest = read();
  147. this.critical = read();
  148. this.hadGlobalOrStickyRegExp = read();
  149. this.request = read();
  150. this._requestContext = read();
  151. this.range = read();
  152. this.valueRange = read();
  153. this.replaces = read();
  154. super.deserialize(context);
  155. }
  156. }
  157. makeSerializable(
  158. ContextDependency,
  159. "webpack/lib/dependencies/ContextDependency"
  160. );
  161. ContextDependency.Template = DependencyTemplate;
  162. module.exports = ContextDependency;