/* MIT License http://www.opensource.org/licenses/mit-license.php Author Sergey Melyukov @smelukov */ "use strict"; const { ConcatSource, RawSource, ReplaceSource, SourceMapSource } = require("webpack-sources"); const { UsageState } = require("../ExportsInfo"); const Generator = require("../Generator"); const InitFragment = require("../InitFragment"); const { CSS_TYPE, CSS_TYPES, JAVASCRIPT_AND_CSS_TYPES, JAVASCRIPT_TYPE, JAVASCRIPT_TYPES } = require("../ModuleSourceTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const CssImportDependency = require("../dependencies/CssImportDependency"); const HarmonyImportSideEffectDependency = require("../dependencies/HarmonyImportSideEffectDependency"); const memoize = require("../util/memoize"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../../declarations/WebpackOptions").CssModuleGeneratorOptions} CssModuleGeneratorOptions */ /** @typedef {import("../Compilation").DependencyConstructor} DependencyConstructor */ /** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").CssData} CssData */ /** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../Generator").GenerateContext} GenerateContext */ /** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */ /** @typedef {import("../Module").BuildInfo} BuildInfo */ /** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */ /** @typedef {import("../Module").SourceType} SourceType */ /** @typedef {import("../Module").SourceTypes} SourceTypes */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../NormalModule")} NormalModule */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("./CssModulesPlugin").ModuleFactoryCacheEntry} ModuleFactoryCacheEntry */ /** @typedef {import("../CssModule")} CssModule */ /** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */ /** @typedef {import("../../declarations/WebpackOptions").CssParserExportType} CssParserExportType */ const getPropertyName = memoize(() => require("../util/property")); const getCssModulesPlugin = memoize(() => require("./CssModulesPlugin")); class CssGenerator extends Generator { /** * Creates an instance of CssGenerator. * @param {CssModuleGeneratorOptions} options options * @param {ModuleGraph} moduleGraph the module graph */ constructor(options, moduleGraph) { super(); this.options = options; this._exportsOnly = options.exportsOnly; this._esModule = options.esModule; this._moduleGraph = moduleGraph; /** @type {WeakMap} */ this._moduleFactoryCache = new WeakMap(); } /** * Returns the reason this module cannot be concatenated, when one exists. * @param {NormalModule} module module for which the bailout reason should be determined * @param {ConcatenationBailoutReasonContext} context context * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated */ getConcatenationBailoutReason(module, context) { if (!this._esModule) { return "Module is not an ECMAScript module"; } return undefined; } /** * Generate JavaScript code that requires and concatenates all CSS imports * @param {NormalModule} module the module to generate CSS text for * @param {GenerateContext} generateContext the generate context * @param {boolean} getDefaultExport whether to get the default export * @returns {{ expr: string, type: CssParserExportType }[]} JavaScript code that concatenates all imported CSS */ _generateImportCode(module, generateContext, getDefaultExport = true) { const moduleGraph = generateContext.moduleGraph; /** @type {{ expr: string, type: CssParserExportType }[]} */ const parts = []; // Iterate through module.dependencies to maintain source order for (const dep of module.dependencies) { if (dep instanceof CssImportDependency) { const depModule = /** @type {CssModule} */ (moduleGraph.getModule(dep)); const importVar = generateContext.runtimeTemplate.moduleExports({ module: depModule, chunkGraph: generateContext.chunkGraph, request: depModule.userRequest, weak: false, runtimeRequirements: generateContext.runtimeRequirements }); if (getDefaultExport) { generateContext.runtimeRequirements.add( RuntimeGlobals.compatGetDefaultExport ); parts.push({ expr: `(${RuntimeGlobals.compatGetDefaultExport}(${importVar})() || "")`, type: /** @type {CssParserExportType} */ (depModule.exportType) }); } else { parts.push({ expr: importVar, type: /** @type {CssParserExportType} */ (depModule.exportType) }); } } } return parts; } /** * Generate CSS source for the current module * @param {NormalModule} module the module to generate CSS source for * @param {GenerateContext} generateContext the generate context * @returns {Source | null} the CSS source */ _generateContentSource(module, generateContext) { const moduleSourceContent = /** @type {Source} */ ( this.generate(module, { ...generateContext, type: CSS_TYPE }) ); if (!moduleSourceContent) { return null; } const compilation = generateContext.runtimeTemplate.compilation; // For non-link exportTypes (style, text, css-style-sheet), url() in the CSS // is resolved relative to the document URL (for