CommonJsFullRequireDependency.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const Template = require("../Template");
  7. const { equals } = require("../util/ArrayHelpers");
  8. const makeSerializable = require("../util/makeSerializable");
  9. const propertyAccess = require("../util/propertyAccess");
  10. const ModuleDependency = require("./ModuleDependency");
  11. /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
  12. /** @typedef {import("../Dependency")} Dependency */
  13. /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */
  14. /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
  15. /** @typedef {import("../ModuleGraph")} ModuleGraph */
  16. /** @typedef {import("../javascript/JavascriptParser").Range} Range */
  17. /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
  18. /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
  19. /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
  20. class CommonJsFullRequireDependency extends ModuleDependency {
  21. /**
  22. * @param {string} request the request string
  23. * @param {Range} range location in source code
  24. * @param {string[]} names accessed properties on module
  25. */
  26. constructor(request, range, names) {
  27. super(request);
  28. this.range = range;
  29. this.names = names;
  30. this.call = false;
  31. this.asiSafe = undefined;
  32. }
  33. /**
  34. * Returns list of exports referenced by this dependency
  35. * @param {ModuleGraph} moduleGraph module graph
  36. * @param {RuntimeSpec} runtime the runtime for which the module is analysed
  37. * @returns {(string[] | ReferencedExport)[]} referenced exports
  38. */
  39. getReferencedExports(moduleGraph, runtime) {
  40. if (this.call) {
  41. const importedModule = moduleGraph.getModule(this);
  42. if (
  43. !importedModule ||
  44. importedModule.getExportsType(moduleGraph, false) !== "namespace"
  45. ) {
  46. return [this.names.slice(0, -1)];
  47. }
  48. }
  49. return [this.names];
  50. }
  51. /**
  52. * @param {ObjectSerializerContext} context context
  53. */
  54. serialize(context) {
  55. const { write } = context;
  56. write(this.names);
  57. write(this.call);
  58. write(this.asiSafe);
  59. super.serialize(context);
  60. }
  61. /**
  62. * @param {ObjectDeserializerContext} context context
  63. */
  64. deserialize(context) {
  65. const { read } = context;
  66. this.names = read();
  67. this.call = read();
  68. this.asiSafe = read();
  69. super.deserialize(context);
  70. }
  71. get type() {
  72. return "cjs full require";
  73. }
  74. get category() {
  75. return "commonjs";
  76. }
  77. }
  78. CommonJsFullRequireDependency.Template = class CommonJsFullRequireDependencyTemplate extends (
  79. ModuleDependency.Template
  80. ) {
  81. /**
  82. * @param {Dependency} dependency the dependency for which the template should be applied
  83. * @param {ReplaceSource} source the current replace source which can be modified
  84. * @param {DependencyTemplateContext} templateContext the context object
  85. * @returns {void}
  86. */
  87. apply(
  88. dependency,
  89. source,
  90. {
  91. module,
  92. runtimeTemplate,
  93. moduleGraph,
  94. chunkGraph,
  95. runtimeRequirements,
  96. runtime,
  97. initFragments
  98. }
  99. ) {
  100. const dep = /** @type {CommonJsFullRequireDependency} */ (dependency);
  101. if (!dep.range) return;
  102. const importedModule = moduleGraph.getModule(dep);
  103. let requireExpr = runtimeTemplate.moduleExports({
  104. module: importedModule,
  105. chunkGraph,
  106. request: dep.request,
  107. weak: dep.weak,
  108. runtimeRequirements
  109. });
  110. if (importedModule) {
  111. const ids = dep.names;
  112. const usedImported = moduleGraph
  113. .getExportsInfo(importedModule)
  114. .getUsedName(ids, runtime);
  115. if (usedImported) {
  116. const comment = equals(usedImported, ids)
  117. ? ""
  118. : Template.toNormalComment(propertyAccess(ids)) + " ";
  119. const access = `${comment}${propertyAccess(usedImported)}`;
  120. requireExpr =
  121. dep.asiSafe === true
  122. ? `(${requireExpr}${access})`
  123. : `${requireExpr}${access}`;
  124. }
  125. }
  126. source.replace(dep.range[0], dep.range[1] - 1, requireExpr);
  127. }
  128. };
  129. makeSerializable(
  130. CommonJsFullRequireDependency,
  131. "webpack/lib/dependencies/CommonJsFullRequireDependency"
  132. );
  133. module.exports = CommonJsFullRequireDependency;