CssModule.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Alexander Akait @alexander-akait
  4. */
  5. "use strict";
  6. const NormalModule = require("./NormalModule");
  7. const makeSerializable = require("./util/makeSerializable");
  8. /** @typedef {import("./Module")} Module */
  9. /** @typedef {import("./NormalModule").NormalModuleCreateData} NormalModuleCreateData */
  10. /** @typedef {import("./RequestShortener")} RequestShortener */
  11. /** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
  12. /** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
  13. /** @typedef {import("../declarations/WebpackOptions").CssParserExportType} CssParserExportType */
  14. /** @typedef {string | undefined} CssLayer */
  15. /** @typedef {string | undefined} Supports */
  16. /** @typedef {string | undefined} Media */
  17. /** @typedef {[CssLayer, Supports, Media]} InheritanceItem */
  18. /** @typedef {InheritanceItem[]} Inheritance */
  19. /** @typedef {NormalModuleCreateData & { cssLayer: CssLayer, supports: Supports, media: Media, inheritance?: Inheritance, exportType?: CssParserExportType }} CSSModuleCreateData */
  20. class CssModule extends NormalModule {
  21. /**
  22. * Creates an instance of CssModule.
  23. * @param {CSSModuleCreateData} options options object
  24. */
  25. constructor(options) {
  26. super(options);
  27. // Avoid override `layer` for `Module` class, because it is a feature to run module in specific layer
  28. /** @type {CSSModuleCreateData['cssLayer']} */
  29. this.cssLayer = options.cssLayer;
  30. /** @type {CSSModuleCreateData['supports']} */
  31. this.supports = options.supports;
  32. /** @type {CSSModuleCreateData['media']} */
  33. this.media = options.media;
  34. /** @type {CSSModuleCreateData['inheritance']} */
  35. this.inheritance = options.inheritance;
  36. /** @type {CSSModuleCreateData['exportType']} */
  37. this.exportType = options.exportType;
  38. }
  39. /**
  40. * Returns the unique identifier used to reference this module.
  41. * @returns {string} a unique identifier of the module
  42. */
  43. identifier() {
  44. let identifier = super.identifier();
  45. if (this.cssLayer) {
  46. identifier += `|${this.cssLayer}`;
  47. }
  48. if (this.supports) {
  49. identifier += `|${this.supports}`;
  50. }
  51. if (this.media) {
  52. identifier += `|${this.media}`;
  53. }
  54. if (this.inheritance) {
  55. const inheritance = this.inheritance.map(
  56. (item, index) =>
  57. `inheritance_${index}|${item[0] || ""}|${item[1] || ""}|${
  58. item[2] || ""
  59. }`
  60. );
  61. identifier += `|${inheritance.join("|")}`;
  62. }
  63. if (this.exportType) {
  64. identifier += `|${this.exportType}`;
  65. }
  66. // We generate extra code for HMR, so we need to invalidate the module
  67. if (this.hot) {
  68. identifier += `|${this.hot}`;
  69. }
  70. return identifier;
  71. }
  72. /**
  73. * Returns a human-readable identifier for this module.
  74. * @param {RequestShortener} requestShortener the request shortener
  75. * @returns {string} a user readable identifier of the module
  76. */
  77. readableIdentifier(requestShortener) {
  78. const readableIdentifier = super.readableIdentifier(requestShortener);
  79. let identifier = `css ${readableIdentifier}`;
  80. if (this.cssLayer) {
  81. identifier += ` (layer: ${this.cssLayer})`;
  82. }
  83. if (this.supports) {
  84. identifier += ` (supports: ${this.supports})`;
  85. }
  86. if (this.media) {
  87. identifier += ` (media: ${this.media})`;
  88. }
  89. if (this.exportType) {
  90. identifier += ` (exportType: ${this.exportType})`;
  91. }
  92. return identifier;
  93. }
  94. /**
  95. * Assuming this module is in the cache. Update the (cached) module with
  96. * the fresh module from the factory. Usually updates internal references
  97. * and properties.
  98. * @param {Module} module fresh module
  99. * @returns {void}
  100. */
  101. updateCacheModule(module) {
  102. super.updateCacheModule(module);
  103. const m = /** @type {CssModule} */ (module);
  104. this.cssLayer = m.cssLayer;
  105. this.supports = m.supports;
  106. this.media = m.media;
  107. this.inheritance = m.inheritance;
  108. this.exportType = m.exportType;
  109. }
  110. /**
  111. * Serializes this instance into the provided serializer context.
  112. * @param {ObjectSerializerContext} context context
  113. */
  114. serialize(context) {
  115. const { write } = context;
  116. write(this.cssLayer);
  117. write(this.supports);
  118. write(this.media);
  119. write(this.inheritance);
  120. write(this.exportType);
  121. super.serialize(context);
  122. }
  123. /**
  124. * Restores this instance from the provided deserializer context.
  125. * @param {ObjectDeserializerContext} context context
  126. * @returns {CssModule} the deserialized object
  127. */
  128. static deserialize(context) {
  129. const obj = new CssModule({
  130. // will be deserialized by Module
  131. layer: /** @type {EXPECTED_ANY} */ (null),
  132. type: "",
  133. // will be filled by updateCacheModule
  134. resource: "",
  135. context: "",
  136. request: /** @type {EXPECTED_ANY} */ (null),
  137. userRequest: /** @type {EXPECTED_ANY} */ (null),
  138. rawRequest: /** @type {EXPECTED_ANY} */ (null),
  139. loaders: /** @type {EXPECTED_ANY} */ (null),
  140. matchResource: /** @type {EXPECTED_ANY} */ (null),
  141. parser: /** @type {EXPECTED_ANY} */ (null),
  142. parserOptions: /** @type {EXPECTED_ANY} */ (null),
  143. generator: /** @type {EXPECTED_ANY} */ (null),
  144. generatorOptions: /** @type {EXPECTED_ANY} */ (null),
  145. resolveOptions: /** @type {EXPECTED_ANY} */ (null),
  146. cssLayer: /** @type {EXPECTED_ANY} */ (null),
  147. supports: /** @type {EXPECTED_ANY} */ (null),
  148. media: /** @type {EXPECTED_ANY} */ (null),
  149. inheritance: /** @type {EXPECTED_ANY} */ (null),
  150. extractSourceMap: /** @type {EXPECTED_ANY} */ (null),
  151. exportType: /** @type {EXPECTED_ANY} */ (null)
  152. });
  153. obj.deserialize(context);
  154. return obj;
  155. }
  156. /**
  157. * Restores this instance from the provided deserializer context.
  158. * @param {ObjectDeserializerContext} context context
  159. */
  160. deserialize(context) {
  161. const { read } = context;
  162. this.cssLayer = read();
  163. this.supports = read();
  164. this.media = read();
  165. this.inheritance = read();
  166. this.exportType = read();
  167. super.deserialize(context);
  168. }
  169. }
  170. makeSerializable(CssModule, "webpack/lib/CssModule");
  171. module.exports = CssModule;