HtmlSourceDependency.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Alexander Akait @alexander-akait
  4. */
  5. "use strict";
  6. const { ASSET_URL_TYPE } = require("../ModuleSourceTypeConstants");
  7. const RawDataUrlModule = require("../asset/RawDataUrlModule");
  8. const makeSerializable = require("../util/makeSerializable");
  9. const memoize = require("../util/memoize");
  10. const ModuleDependency = require("./ModuleDependency");
  11. /** @import { ReplaceSource } from "webpack-sources" */
  12. /** @import CodeGenerationResults from "../CodeGenerationResults" */
  13. /** @import Dependency, { UpdateHashContext } from "../Dependency" */
  14. /**
  15. * @import {
  16. * CssDependencyTemplateContext as DependencyTemplateContext
  17. * } from "../DependencyTemplate"
  18. */
  19. /** @import Module, { BuildInfo } from "../Module" */
  20. /** @import { Range } from "../javascript/JavascriptParser" */
  21. /**
  22. * @import {
  23. * ObjectDeserializerContext,
  24. * ObjectSerializerContext
  25. * } from "../serialization/ObjectMiddleware"
  26. */
  27. /** @import Hash from "../util/Hash" */
  28. /** @import { RuntimeSpec } from "../util/runtime" */
  29. const getIgnoredRawDataUrlModule = memoize(
  30. () => new RawDataUrlModule("data:,", "ignored-asset", "(ignored asset)")
  31. );
  32. class HtmlSourceDependency extends ModuleDependency {
  33. /**
  34. * Creates an instance of HtmlSourceDependency.
  35. * @param {string} request request
  36. * @param {Range} range range of the argument
  37. */
  38. constructor(request, range) {
  39. super(request);
  40. this.range = range;
  41. /** @type {true | undefined} */
  42. this.prefetch = undefined;
  43. /** @type {true | undefined} */
  44. this.preload = undefined;
  45. /** @type {"low" | "high" | "auto" | undefined} */
  46. this.fetchPriority = undefined;
  47. /** @type {string | undefined} */
  48. this.asAttribute = undefined;
  49. /** @type {string | undefined} */
  50. this.typeAttribute = undefined;
  51. /** @type {string | undefined} */
  52. this.mediaAttribute = undefined;
  53. }
  54. get type() {
  55. return "html source()";
  56. }
  57. get category() {
  58. return "url";
  59. }
  60. get referencedSourceType() {
  61. return ASSET_URL_TYPE;
  62. }
  63. /**
  64. * Creates an ignored module.
  65. * @param {string} context context directory
  66. * @returns {Module} ignored module
  67. */
  68. createIgnoredModule(context) {
  69. return getIgnoredRawDataUrlModule();
  70. }
  71. /**
  72. * Updates the hash with the data contributed by this instance.
  73. * @param {Hash} hash hash to be updated
  74. * @param {UpdateHashContext} context context
  75. * @returns {void}
  76. */
  77. updateHash(hash, context) {
  78. // Fold in the asset's hash so the HTML invalidates when the embedded URL changes.
  79. const { chunkGraph } = context;
  80. const module = chunkGraph.moduleGraph.getModule(this);
  81. if (!module) return;
  82. const { hash: buildHash } = /** @type {BuildInfo} */ (module.buildInfo);
  83. if (buildHash) hash.update(buildHash);
  84. }
  85. /**
  86. * Serializes this instance into the provided serializer context.
  87. * @param {ObjectSerializerContext} context context
  88. */
  89. serialize(context) {
  90. const { write } = context;
  91. write(this.prefetch);
  92. write(this.preload);
  93. write(this.fetchPriority);
  94. write(this.asAttribute);
  95. write(this.typeAttribute);
  96. write(this.mediaAttribute);
  97. super.serialize(context);
  98. }
  99. /**
  100. * Restores this instance from the provided deserializer context.
  101. * @param {ObjectDeserializerContext} context context
  102. */
  103. deserialize(context) {
  104. const { read } = context;
  105. this.prefetch = read();
  106. this.preload = read();
  107. this.fetchPriority = read();
  108. this.asAttribute = read();
  109. this.typeAttribute = read();
  110. this.mediaAttribute = read();
  111. super.deserialize(context);
  112. }
  113. }
  114. HtmlSourceDependency.Template = class HtmlSourceDependencyTemplate extends (
  115. ModuleDependency.Template
  116. ) {
  117. /**
  118. * Applies the plugin by registering its hooks on the compiler.
  119. * @param {Dependency} dependency the dependency for which the template should be applied
  120. * @param {ReplaceSource} source the current replace source which can be modified
  121. * @param {DependencyTemplateContext} templateContext the context object
  122. * @returns {void}
  123. */
  124. apply(
  125. dependency,
  126. source,
  127. { moduleGraph, runtimeTemplate, codeGenerationResults }
  128. ) {
  129. const dep = /** @type {HtmlSourceDependency} */ (dependency);
  130. const module = /** @type {Module} */ (moduleGraph.getModule(dep));
  131. /** @type {string | undefined} */
  132. const newValue = this.assetUrl({
  133. module,
  134. codeGenerationResults
  135. });
  136. source.replace(dep.range[0], dep.range[1] - 1, newValue);
  137. }
  138. /**
  139. * Returns the url of the asset.
  140. * @param {object} options options object
  141. * @param {Module} options.module the module
  142. * @param {RuntimeSpec=} options.runtime runtime
  143. * @param {CodeGenerationResults} options.codeGenerationResults the code generation results
  144. * @returns {string} the url of the asset
  145. */
  146. assetUrl({ runtime, module, codeGenerationResults }) {
  147. if (!module) {
  148. return "data:,";
  149. }
  150. const codeGen = codeGenerationResults.get(module, runtime);
  151. const data = codeGen.data;
  152. if (!data) return "data:,";
  153. const url = data.get("url");
  154. if (!url || !url[ASSET_URL_TYPE]) return "data:,";
  155. return url[ASSET_URL_TYPE];
  156. }
  157. };
  158. makeSerializable(
  159. HtmlSourceDependency,
  160. "webpack/lib/dependencies/HtmlSourceDependency"
  161. );
  162. module.exports = HtmlSourceDependency;