CommonJsExportsDependency.js 3.9 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 InitFragment = require("../InitFragment");
  7. const makeSerializable = require("../util/makeSerializable");
  8. const propertyAccess = require("../util/propertyAccess");
  9. const { handleDependencyBase } = require("./CommonJsDependencyHelpers");
  10. const NullDependency = require("./NullDependency");
  11. /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
  12. /** @typedef {import("../Dependency")} Dependency */
  13. /** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
  14. /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
  15. /** @typedef {import("../ModuleGraph")} ModuleGraph */
  16. const EMPTY_OBJECT = {};
  17. class CommonJsExportsDependency extends NullDependency {
  18. constructor(range, valueRange, base, names) {
  19. super();
  20. this.range = range;
  21. this.valueRange = valueRange;
  22. this.base = base;
  23. this.names = names;
  24. }
  25. get type() {
  26. return "cjs exports";
  27. }
  28. /**
  29. * Returns the exported names
  30. * @param {ModuleGraph} moduleGraph module graph
  31. * @returns {ExportsSpec | undefined} export names
  32. */
  33. getExports(moduleGraph) {
  34. const name = this.names[0];
  35. return {
  36. exports: [
  37. {
  38. name,
  39. // we can't mangle names that are in an empty object
  40. // because one could access the prototype property
  41. // when export isn't set yet
  42. canMangle: !(name in EMPTY_OBJECT)
  43. }
  44. ],
  45. dependencies: undefined
  46. };
  47. }
  48. serialize(context) {
  49. const { write } = context;
  50. write(this.range);
  51. write(this.valueRange);
  52. write(this.base);
  53. write(this.names);
  54. super.serialize(context);
  55. }
  56. deserialize(context) {
  57. const { read } = context;
  58. this.range = read();
  59. this.valueRange = read();
  60. this.base = read();
  61. this.names = read();
  62. super.deserialize(context);
  63. }
  64. }
  65. makeSerializable(
  66. CommonJsExportsDependency,
  67. "webpack/lib/dependencies/CommonJsExportsDependency"
  68. );
  69. CommonJsExportsDependency.Template = class CommonJsExportsDependencyTemplate extends (
  70. NullDependency.Template
  71. ) {
  72. /**
  73. * @param {Dependency} dependency the dependency for which the template should be applied
  74. * @param {ReplaceSource} source the current replace source which can be modified
  75. * @param {DependencyTemplateContext} templateContext the context object
  76. * @returns {void}
  77. */
  78. apply(
  79. dependency,
  80. source,
  81. { module, moduleGraph, initFragments, runtimeRequirements, runtime }
  82. ) {
  83. const dep = /** @type {CommonJsExportsDependency} */ (dependency);
  84. const used = moduleGraph
  85. .getExportsInfo(module)
  86. .getUsedName(dep.names, runtime);
  87. const [type, base] = handleDependencyBase(
  88. dep.base,
  89. module,
  90. runtimeRequirements
  91. );
  92. switch (type) {
  93. case "expression":
  94. if (!used) {
  95. initFragments.push(
  96. new InitFragment(
  97. "var __webpack_unused_export__;\n",
  98. InitFragment.STAGE_CONSTANTS,
  99. 0,
  100. "__webpack_unused_export__"
  101. )
  102. );
  103. source.replace(
  104. dep.range[0],
  105. dep.range[1] - 1,
  106. "__webpack_unused_export__"
  107. );
  108. return;
  109. }
  110. source.replace(
  111. dep.range[0],
  112. dep.range[1] - 1,
  113. `${base}${propertyAccess(used)}`
  114. );
  115. return;
  116. case "Object.defineProperty":
  117. if (!used) {
  118. initFragments.push(
  119. new InitFragment(
  120. "var __webpack_unused_export__;\n",
  121. InitFragment.STAGE_CONSTANTS,
  122. 0,
  123. "__webpack_unused_export__"
  124. )
  125. );
  126. source.replace(
  127. dep.range[0],
  128. dep.valueRange[0] - 1,
  129. "__webpack_unused_export__ = ("
  130. );
  131. source.replace(dep.valueRange[1], dep.range[1] - 1, ")");
  132. return;
  133. }
  134. source.replace(
  135. dep.range[0],
  136. dep.valueRange[0] - 1,
  137. `Object.defineProperty(${base}${propertyAccess(
  138. used.slice(0, -1)
  139. )}, ${JSON.stringify(used[used.length - 1])}, (`
  140. );
  141. source.replace(dep.valueRange[1], dep.range[1] - 1, "))");
  142. return;
  143. }
  144. }
  145. };
  146. module.exports = CommonJsExportsDependency;