PureExpressionDependency.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { UsageState } = require("../ExportsInfo");
  7. const makeSerializable = require("../util/makeSerializable");
  8. const { filterRuntime, runtimeToString } = require("../util/runtime");
  9. const NullDependency = require("./NullDependency");
  10. /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
  11. /** @typedef {import("../Dependency")} Dependency */
  12. /** @typedef {import("../Dependency").RuntimeSpec} RuntimeSpec */
  13. /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
  14. /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
  15. /** @typedef {import("../Module")} Module */
  16. /** @typedef {import("../ModuleGraph")} ModuleGraph */
  17. /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
  18. /** @typedef {import("../javascript/JavascriptParser").Range} Range */
  19. /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
  20. /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
  21. /** @typedef {import("../util/Hash")} Hash */
  22. class PureExpressionDependency extends NullDependency {
  23. /**
  24. * Creates an instance of PureExpressionDependency.
  25. * @param {Range} range the source range
  26. */
  27. constructor(range) {
  28. super();
  29. this.range = range;
  30. /** @type {Set<string> | false} */
  31. this.usedByExports = false;
  32. }
  33. /**
  34. * Get runtime condition.
  35. * @param {ModuleGraph} moduleGraph module graph
  36. * @param {RuntimeSpec} runtime current runtimes
  37. * @returns {boolean | RuntimeSpec} runtime condition
  38. */
  39. _getRuntimeCondition(moduleGraph, runtime) {
  40. const usedByExports = this.usedByExports;
  41. if (usedByExports !== false) {
  42. const selfModule =
  43. /** @type {Module} */
  44. (moduleGraph.getParentModule(this));
  45. const exportsInfo = moduleGraph.getExportsInfo(selfModule);
  46. const runtimeCondition = filterRuntime(runtime, (runtime) => {
  47. for (const exportName of usedByExports) {
  48. if (exportsInfo.getUsed(exportName, runtime) !== UsageState.Unused) {
  49. return true;
  50. }
  51. }
  52. return false;
  53. });
  54. return runtimeCondition;
  55. }
  56. return false;
  57. }
  58. /**
  59. * Updates the hash with the data contributed by this instance.
  60. * @param {Hash} hash hash to be updated
  61. * @param {UpdateHashContext} context context
  62. * @returns {void}
  63. */
  64. updateHash(hash, context) {
  65. const runtimeCondition = this._getRuntimeCondition(
  66. context.chunkGraph.moduleGraph,
  67. context.runtime
  68. );
  69. if (runtimeCondition === true) {
  70. return;
  71. } else if (runtimeCondition === false) {
  72. hash.update("null");
  73. } else {
  74. hash.update(
  75. `${runtimeToString(runtimeCondition)}|${runtimeToString(
  76. context.runtime
  77. )}`
  78. );
  79. }
  80. hash.update(String(this.range));
  81. }
  82. /**
  83. * Gets module evaluation side effects state.
  84. * @param {ModuleGraph} moduleGraph the module graph
  85. * @returns {ConnectionState} how this dependency connects the module to referencing modules
  86. */
  87. getModuleEvaluationSideEffectsState(moduleGraph) {
  88. return false;
  89. }
  90. /**
  91. * Serializes this instance into the provided serializer context.
  92. * @param {ObjectSerializerContext} context context
  93. */
  94. serialize(context) {
  95. const { write } = context;
  96. write(this.range);
  97. write(this.usedByExports);
  98. super.serialize(context);
  99. }
  100. /**
  101. * Restores this instance from the provided deserializer context.
  102. * @param {ObjectDeserializerContext} context context
  103. */
  104. deserialize(context) {
  105. const { read } = context;
  106. this.range = read();
  107. this.usedByExports = read();
  108. super.deserialize(context);
  109. }
  110. }
  111. makeSerializable(
  112. PureExpressionDependency,
  113. "webpack/lib/dependencies/PureExpressionDependency"
  114. );
  115. PureExpressionDependency.Template = class PureExpressionDependencyTemplate extends (
  116. NullDependency.Template
  117. ) {
  118. /**
  119. * Applies the plugin by registering its hooks on the compiler.
  120. * @param {Dependency} dependency the dependency for which the template should be applied
  121. * @param {ReplaceSource} source the current replace source which can be modified
  122. * @param {DependencyTemplateContext} templateContext the context object
  123. * @returns {void}
  124. */
  125. apply(
  126. dependency,
  127. source,
  128. { chunkGraph, moduleGraph, runtime, runtimeTemplate, runtimeRequirements }
  129. ) {
  130. const dep = /** @type {PureExpressionDependency} */ (dependency);
  131. const runtimeCondition = dep._getRuntimeCondition(moduleGraph, runtime);
  132. if (runtimeCondition === true) {
  133. // Do nothing
  134. } else if (runtimeCondition === false) {
  135. source.insert(
  136. dep.range[0],
  137. "(/* unused pure expression or super */ null && ("
  138. );
  139. source.insert(dep.range[1], "))");
  140. } else {
  141. const condition = runtimeTemplate.runtimeConditionExpression({
  142. chunkGraph,
  143. runtime,
  144. runtimeCondition,
  145. runtimeRequirements
  146. });
  147. source.insert(
  148. dep.range[0],
  149. `(/* runtime-dependent pure expression or super */ ${condition} ? (`
  150. );
  151. source.insert(dep.range[1], ") : null)");
  152. }
  153. }
  154. };
  155. module.exports = PureExpressionDependency;