PureExpressionDependency.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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, deepMergeRuntime } = require("../util/runtime");
  9. const NullDependency = require("./NullDependency");
  10. /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
  11. /** @typedef {import("../ChunkGraph")} ChunkGraph */
  12. /** @typedef {import("../Dependency")} Dependency */
  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. * @param {Range} range the source range
  25. */
  26. constructor(range) {
  27. super();
  28. this.range = range;
  29. /** @type {Set<string> | false} */
  30. this.usedByExports = false;
  31. this._hashUpdate = undefined;
  32. }
  33. /**
  34. * Update the hash
  35. * @param {Hash} hash hash to be updated
  36. * @param {UpdateHashContext} context context
  37. * @returns {void}
  38. */
  39. updateHash(hash, context) {
  40. if (this._hashUpdate === undefined) {
  41. this._hashUpdate = this.range + "";
  42. }
  43. hash.update(this._hashUpdate);
  44. }
  45. /**
  46. * @param {ModuleGraph} moduleGraph the module graph
  47. * @returns {ConnectionState} how this dependency connects the module to referencing modules
  48. */
  49. getModuleEvaluationSideEffectsState(moduleGraph) {
  50. return false;
  51. }
  52. /**
  53. * @param {ObjectSerializerContext} context context
  54. */
  55. serialize(context) {
  56. const { write } = context;
  57. write(this.range);
  58. write(this.usedByExports);
  59. super.serialize(context);
  60. }
  61. /**
  62. * @param {ObjectDeserializerContext} context context
  63. */
  64. deserialize(context) {
  65. const { read } = context;
  66. this.range = read();
  67. this.usedByExports = read();
  68. super.deserialize(context);
  69. }
  70. }
  71. makeSerializable(
  72. PureExpressionDependency,
  73. "webpack/lib/dependencies/PureExpressionDependency"
  74. );
  75. PureExpressionDependency.Template = class PureExpressionDependencyTemplate extends (
  76. NullDependency.Template
  77. ) {
  78. /**
  79. * @param {Dependency} dependency the dependency for which the template should be applied
  80. * @param {ReplaceSource} source the current replace source which can be modified
  81. * @param {DependencyTemplateContext} templateContext the context object
  82. * @returns {void}
  83. */
  84. apply(
  85. dependency,
  86. source,
  87. {
  88. chunkGraph,
  89. moduleGraph,
  90. runtime,
  91. runtimes,
  92. runtimeTemplate,
  93. runtimeRequirements
  94. }
  95. ) {
  96. const dep = /** @type {PureExpressionDependency} */ (dependency);
  97. const usedByExports = dep.usedByExports;
  98. if (usedByExports !== false) {
  99. const selfModule =
  100. /** @type {Module} */
  101. (moduleGraph.getParentModule(dep));
  102. const exportsInfo = moduleGraph.getExportsInfo(selfModule);
  103. const merged = deepMergeRuntime(runtimes, runtime);
  104. const runtimeCondition = filterRuntime(merged, runtime => {
  105. for (const exportName of usedByExports) {
  106. if (exportsInfo.getUsed(exportName, runtime) !== UsageState.Unused) {
  107. return true;
  108. }
  109. }
  110. return false;
  111. });
  112. if (runtimeCondition === true) return;
  113. if (runtimeCondition !== false) {
  114. const condition = runtimeTemplate.runtimeConditionExpression({
  115. chunkGraph,
  116. runtime: merged,
  117. runtimeCondition,
  118. runtimeRequirements
  119. });
  120. source.insert(
  121. dep.range[0],
  122. `(/* runtime-dependent pure expression or super */ ${condition} ? (`
  123. );
  124. source.insert(dep.range[1], ") : null)");
  125. return;
  126. }
  127. }
  128. source.insert(
  129. dep.range[0],
  130. `(/* unused pure expression or super */ null && (`
  131. );
  132. source.insert(dep.range[1], "))");
  133. }
  134. };
  135. module.exports = PureExpressionDependency;