ImportDependency.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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").ReferencedExport} ReferencedExport */
  12. /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
  13. /** @typedef {import("../Module")} Module */
  14. /** @typedef {import("../Module").BuildMeta} BuildMeta */
  15. /** @typedef {import("../ModuleGraph")} ModuleGraph */
  16. /** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
  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/runtime").RuntimeSpec} RuntimeSpec */
  21. class ImportDependency extends ModuleDependency {
  22. /**
  23. * @param {string} request the request
  24. * @param {Range} range expression range
  25. * @param {(string[][] | null)=} referencedExports list of referenced exports
  26. * @param {ImportAttributes=} attributes import attributes
  27. */
  28. constructor(request, range, referencedExports, attributes) {
  29. super(request);
  30. this.range = range;
  31. this.referencedExports = referencedExports;
  32. this.assertions = attributes;
  33. }
  34. get type() {
  35. return "import()";
  36. }
  37. get category() {
  38. return "esm";
  39. }
  40. /**
  41. * Returns list of exports referenced by this dependency
  42. * @param {ModuleGraph} moduleGraph module graph
  43. * @param {RuntimeSpec} runtime the runtime for which the module is analysed
  44. * @returns {(string[] | ReferencedExport)[]} referenced exports
  45. */
  46. getReferencedExports(moduleGraph, runtime) {
  47. if (!this.referencedExports) return Dependency.EXPORTS_OBJECT_REFERENCED;
  48. const refs = [];
  49. for (const referencedExport of this.referencedExports) {
  50. if (referencedExport[0] === "default") {
  51. const selfModule =
  52. /** @type {Module} */
  53. (moduleGraph.getParentModule(this));
  54. const importedModule =
  55. /** @type {Module} */
  56. (moduleGraph.getModule(this));
  57. const exportsType = importedModule.getExportsType(
  58. moduleGraph,
  59. /** @type {BuildMeta} */
  60. (selfModule.buildMeta).strictHarmonyModule
  61. );
  62. if (
  63. exportsType === "default-only" ||
  64. exportsType === "default-with-named"
  65. ) {
  66. return Dependency.EXPORTS_OBJECT_REFERENCED;
  67. }
  68. }
  69. refs.push({
  70. name: referencedExport,
  71. canMangle: false
  72. });
  73. }
  74. return refs;
  75. }
  76. /**
  77. * @param {ObjectSerializerContext} context context
  78. */
  79. serialize(context) {
  80. context.write(this.range);
  81. context.write(this.referencedExports);
  82. context.write(this.assertions);
  83. super.serialize(context);
  84. }
  85. /**
  86. * @param {ObjectDeserializerContext} context context
  87. */
  88. deserialize(context) {
  89. this.range = context.read();
  90. this.referencedExports = context.read();
  91. this.assertions = context.read();
  92. super.deserialize(context);
  93. }
  94. }
  95. makeSerializable(ImportDependency, "webpack/lib/dependencies/ImportDependency");
  96. ImportDependency.Template = class ImportDependencyTemplate extends (
  97. ModuleDependency.Template
  98. ) {
  99. /**
  100. * @param {Dependency} dependency the dependency for which the template should be applied
  101. * @param {ReplaceSource} source the current replace source which can be modified
  102. * @param {DependencyTemplateContext} templateContext the context object
  103. * @returns {void}
  104. */
  105. apply(
  106. dependency,
  107. source,
  108. { runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements }
  109. ) {
  110. const dep = /** @type {ImportDependency} */ (dependency);
  111. const block = /** @type {AsyncDependenciesBlock} */ (
  112. moduleGraph.getParentBlock(dep)
  113. );
  114. const content = runtimeTemplate.moduleNamespacePromise({
  115. chunkGraph,
  116. block: block,
  117. module: /** @type {Module} */ (moduleGraph.getModule(dep)),
  118. request: dep.request,
  119. strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule,
  120. message: "import()",
  121. runtimeRequirements
  122. });
  123. source.replace(dep.range[0], dep.range[1] - 1, content);
  124. }
  125. };
  126. module.exports = ImportDependency;