ContextElementDependency.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. /** @import ContextModule from "../ContextModule" */
  10. /** @import { RawReferencedExports, ReferencedExports } from "../Dependency" */
  11. /** @import Module from "../Module" */
  12. /** @import ModuleGraph from "../ModuleGraph" */
  13. /** @import { ImportAttributes } from "../javascript/JavascriptParser" */
  14. /** @import { RuntimeSpec } from "../util/runtime" */
  15. /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext<[string | undefined, string, RawReferencedExports | null | undefined, ImportAttributes | undefined, string | undefined]>} ObjectDeserializerContext */
  16. /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext<[string | undefined, string, RawReferencedExports | null | undefined, ImportAttributes | undefined, string | undefined]>} ObjectSerializerContext */
  17. class ContextElementDependency extends ModuleDependency {
  18. /**
  19. * Creates an instance of ContextElementDependency.
  20. * @param {string} request request
  21. * @param {string | undefined} userRequest user request
  22. * @param {string | undefined} typePrefix type prefix
  23. * @param {string} category category
  24. * @param {RawReferencedExports | null=} referencedExports referenced exports
  25. * @param {string=} context context
  26. * @param {ImportAttributes=} attributes import assertions
  27. * @param {string=} contextRequest the request of the context as written by the user, without query and fragment
  28. */
  29. constructor(
  30. request,
  31. userRequest,
  32. typePrefix,
  33. category,
  34. referencedExports,
  35. context,
  36. attributes,
  37. contextRequest
  38. ) {
  39. super(request);
  40. if (userRequest) {
  41. /** @type {string} */
  42. this.userRequest = userRequest;
  43. }
  44. /** @type {string | undefined} */
  45. this._typePrefix = typePrefix;
  46. /** @type {string} */
  47. this._category = category;
  48. /** @type {RawReferencedExports | null | undefined} */
  49. this.referencedExports = referencedExports;
  50. /** @type {string | undefined} */
  51. this._context = context || undefined;
  52. /** @type {ImportAttributes | undefined} */
  53. this.attributes = attributes;
  54. /** @type {string | undefined} */
  55. this._contextRequest = contextRequest || undefined;
  56. }
  57. /**
  58. * The request as the user wrote it, e.g. `#configs/file.mjs` where `request`
  59. * is the `./file.mjs` relative to the resolved `#configs` directory.
  60. * @returns {string} the original request
  61. */
  62. get originalRequest() {
  63. const request = this.request;
  64. if (this._contextRequest === undefined || !request.startsWith("./")) {
  65. return request;
  66. }
  67. return this._contextRequest + request.slice(1);
  68. }
  69. get type() {
  70. if (this._typePrefix) {
  71. return `${this._typePrefix} context element`;
  72. }
  73. return "context element";
  74. }
  75. get category() {
  76. return this._category;
  77. }
  78. /**
  79. * Returns an identifier to merge equal requests.
  80. * @returns {string | null} an identifier to merge equal requests
  81. */
  82. getResourceIdentifier() {
  83. let str = super.getResourceIdentifier();
  84. if (this.attributes) {
  85. str += `|attributes${JSON.stringify(this.attributes)}`;
  86. }
  87. return str;
  88. }
  89. /**
  90. * Returns list of exports referenced by this dependency
  91. * @param {ModuleGraph} moduleGraph module graph
  92. * @param {RuntimeSpec} runtime the runtime for which the module is analysed
  93. * @returns {ReferencedExports} referenced exports
  94. */
  95. getReferencedExports(moduleGraph, runtime) {
  96. if (!this.referencedExports) return Dependency.EXPORTS_OBJECT_REFERENCED;
  97. /** @type {ReferencedExports} */
  98. const refs = [];
  99. for (const referencedExport of this.referencedExports) {
  100. if (
  101. this._typePrefix === "import()" &&
  102. referencedExport[0] === "default"
  103. ) {
  104. const selfModule =
  105. /** @type {ContextModule} */
  106. (moduleGraph.getParentModule(this));
  107. const importedModule =
  108. /** @type {Module} */
  109. (moduleGraph.getModule(this));
  110. const exportsType = importedModule.getExportsType(
  111. moduleGraph,
  112. selfModule.options.namespaceObject === "strict"
  113. );
  114. if (
  115. exportsType === "default-only" ||
  116. exportsType === "default-with-named"
  117. ) {
  118. return Dependency.EXPORTS_OBJECT_REFERENCED;
  119. }
  120. }
  121. refs.push({
  122. name: referencedExport,
  123. canMangle: false,
  124. canInline: false
  125. });
  126. }
  127. return refs;
  128. }
  129. /**
  130. * Serializes this instance into the provided serializer context.
  131. * @param {ObjectSerializerContext} context context
  132. */
  133. serialize(context) {
  134. context
  135. .write(this._typePrefix)
  136. .write(this._category)
  137. .write(this.referencedExports)
  138. .write(this.attributes)
  139. .write(this._contextRequest);
  140. super.serialize(context);
  141. }
  142. /**
  143. * Restores this instance from the provided deserializer context.
  144. * @param {ObjectDeserializerContext} context context
  145. */
  146. deserialize(context) {
  147. this._typePrefix = context.read();
  148. const c1 = context.rest;
  149. this._category = c1.read();
  150. const c2 = c1.rest;
  151. this.referencedExports = c2.read();
  152. const c3 = c2.rest;
  153. this.attributes = c3.read();
  154. const c4 = c3.rest;
  155. this._contextRequest = c4.read();
  156. super.deserialize(c4.rest);
  157. }
  158. }
  159. makeSerializable(
  160. ContextElementDependency,
  161. "webpack/lib/dependencies/ContextElementDependency"
  162. );
  163. module.exports = ContextElementDependency;