PureExpressionDependency.js 4.0 KB

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