ImportDependency.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const Dependency = require("../Dependency");
  7. const makeSerializable = require("../util/makeSerializable");
  8. const ModuleDependency = require("./ModuleDependency");
  9. /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
  10. /** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */
  11. /** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
  12. /** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
  13. /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
  14. /** @typedef {import("../Module")} Module */
  15. /** @typedef {import("../Module").BuildMeta} BuildMeta */
  16. /** @typedef {import("../ModuleGraph")} ModuleGraph */
  17. /** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
  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/runtime").RuntimeSpec} RuntimeSpec */
  22. /** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
  23. class ImportDependency extends ModuleDependency {
  24. /**
  25. * @param {string} request the request
  26. * @param {Range} range expression range
  27. * @param {RawReferencedExports | null} referencedExports list of referenced exports
  28. * @param {ImportPhaseType} phase import phase
  29. * @param {ImportAttributes=} attributes import attributes
  30. */
  31. constructor(request, range, referencedExports, phase, attributes) {
  32. super(request);
  33. this.range = range;
  34. this.referencedExports = referencedExports;
  35. this.phase = phase;
  36. this.attributes = attributes;
  37. }
  38. get type() {
  39. return "import()";
  40. }
  41. get category() {
  42. return "esm";
  43. }
  44. /**
  45. * @returns {string | null} an identifier to merge equal requests
  46. */
  47. getResourceIdentifier() {
  48. let str = super.getResourceIdentifier();
  49. if (this.attributes) {
  50. str += `|importAttributes${JSON.stringify(this.attributes)}`;
  51. }
  52. return str;
  53. }
  54. /**
  55. * Returns list of exports referenced by this dependency
  56. * @param {ModuleGraph} moduleGraph module graph
  57. * @param {RuntimeSpec} runtime the runtime for which the module is analysed
  58. * @returns {ReferencedExports} referenced exports
  59. */
  60. getReferencedExports(moduleGraph, runtime) {
  61. if (!this.referencedExports) return Dependency.EXPORTS_OBJECT_REFERENCED;
  62. /** @type {ReferencedExports} */
  63. const refs = [];
  64. for (const referencedExport of this.referencedExports) {
  65. if (referencedExport[0] === "default") {
  66. const selfModule =
  67. /** @type {Module} */
  68. (moduleGraph.getParentModule(this));
  69. const importedModule =
  70. /** @type {Module} */
  71. (moduleGraph.getModule(this));
  72. const exportsType = importedModule.getExportsType(
  73. moduleGraph,
  74. /** @type {BuildMeta} */
  75. (selfModule.buildMeta).strictHarmonyModule
  76. );
  77. if (
  78. exportsType === "default-only" ||
  79. exportsType === "default-with-named"
  80. ) {
  81. return Dependency.EXPORTS_OBJECT_REFERENCED;
  82. }
  83. }
  84. refs.push({
  85. name: referencedExport,
  86. canMangle: false
  87. });
  88. }
  89. return refs;
  90. }
  91. /**
  92. * @param {ObjectSerializerContext} context context
  93. */
  94. serialize(context) {
  95. context.write(this.range);
  96. context.write(this.referencedExports);
  97. context.write(this.phase);
  98. context.write(this.attributes);
  99. super.serialize(context);
  100. }
  101. /**
  102. * @param {ObjectDeserializerContext} context context
  103. */
  104. deserialize(context) {
  105. this.range = context.read();
  106. this.referencedExports = context.read();
  107. this.phase = context.read();
  108. this.attributes = context.read();
  109. super.deserialize(context);
  110. }
  111. }
  112. makeSerializable(ImportDependency, "webpack/lib/dependencies/ImportDependency");
  113. ImportDependency.Template = class ImportDependencyTemplate extends (
  114. ModuleDependency.Template
  115. ) {
  116. /**
  117. * @param {Dependency} dependency the dependency for which the template should be applied
  118. * @param {ReplaceSource} source the current replace source which can be modified
  119. * @param {DependencyTemplateContext} templateContext the context object
  120. * @returns {void}
  121. */
  122. apply(
  123. dependency,
  124. source,
  125. { runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements }
  126. ) {
  127. const dep = /** @type {ImportDependency} */ (dependency);
  128. const block = /** @type {AsyncDependenciesBlock} */ (
  129. moduleGraph.getParentBlock(dep)
  130. );
  131. const content = runtimeTemplate.moduleNamespacePromise({
  132. chunkGraph,
  133. block,
  134. module: /** @type {Module} */ (moduleGraph.getModule(dep)),
  135. request: dep.request,
  136. strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule,
  137. dependency: dep,
  138. message: "import()",
  139. runtimeRequirements
  140. });
  141. source.replace(dep.range[0], dep.range[1] - 1, content);
  142. }
  143. };
  144. module.exports = ImportDependency;