| | |
| | | |
| | | "use strict"; |
| | | |
| | | const { ConcatSource, RawSource, ReplaceSource } = require("webpack-sources"); |
| | | 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, |
| | | JS_AND_CSS_TYPES, |
| | | JS_TYPE, |
| | | JS_TYPES |
| | | } = require("../ModuleSourceTypesConstants"); |
| | | JAVASCRIPT_AND_CSS_TYPES, |
| | | JAVASCRIPT_TYPE, |
| | | JAVASCRIPT_TYPES |
| | | } = require("../ModuleSourceTypeConstants"); |
| | | const RuntimeGlobals = require("../RuntimeGlobals"); |
| | | const Template = require("../Template"); |
| | | const CssImportDependency = require("../dependencies/CssImportDependency"); |
| | | const { getUndoPath } = require("../util/identifier"); |
| | | const HarmonyImportSideEffectDependency = require("../dependencies/HarmonyImportSideEffectDependency"); |
| | | |
| | | const memoize = require("../util/memoize"); |
| | | |
| | | /** @typedef {import("webpack-sources").Source} Source */ |
| | | /** @typedef {import("../../declarations/WebpackOptions").CssAutoGeneratorOptions} CssAutoGeneratorOptions */ |
| | | /** @typedef {import("../../declarations/WebpackOptions").CssGlobalGeneratorOptions} CssGlobalGeneratorOptions */ |
| | | /** @typedef {import("../../declarations/WebpackOptions").CssModuleGeneratorOptions} CssModuleGeneratorOptions */ |
| | | /** @typedef {import("../Compilation").DependencyConstructor} DependencyConstructor */ |
| | | /** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */ |
| | |
| | | /** @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("../Module").RuntimeRequirements} RuntimeRequirements */ |
| | | /** @typedef {import("../../declarations/WebpackOptions").CssParserExportType} CssParserExportType */ |
| | | |
| | | const getPropertyName = memoize(() => require("../util/propertyName")); |
| | | const getPropertyName = memoize(() => require("../util/property")); |
| | | const getCssModulesPlugin = memoize(() => require("./CssModulesPlugin")); |
| | | |
| | | class CssGenerator extends Generator { |
| | | /** |
| | | * @param {CssAutoGeneratorOptions | CssGlobalGeneratorOptions | CssModuleGeneratorOptions} options options |
| | | * Creates an instance of CssGenerator. |
| | | * @param {CssModuleGeneratorOptions} options options |
| | | * @param {ModuleGraph} moduleGraph the module graph |
| | | */ |
| | | constructor(options, moduleGraph) { |
| | | super(); |
| | | this.convention = options.exportsConvention; |
| | | this.localIdentName = options.localIdentName; |
| | | this.options = options; |
| | | this._exportsOnly = options.exportsOnly; |
| | | this._esModule = options.esModule; |
| | | this._moduleGraph = moduleGraph; |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | * 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) { |
| | | _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) { |
| | | /** @type {CssModule} */ |
| | | const depModule = /** @type {CssModule} */ (moduleGraph.getModule(dep)); |
| | | const importVar = generateContext.runtimeTemplate.moduleExports({ |
| | | module: depModule, |
| | | chunkGraph: generateContext.chunkGraph, |
| | | request: /** @type {CssModule} */ (depModule).userRequest, |
| | | request: depModule.userRequest, |
| | | weak: false, |
| | | runtimeRequirements: generateContext.runtimeRequirements |
| | | }); |
| | | |
| | | if (getDefaultExport) { |
| | | generateContext.runtimeRequirements.add( |
| | | RuntimeGlobals.compatGetDefaultExport |
| | | ); |
| | | parts.push({ |
| | | expr: `(${RuntimeGlobals.compatGetDefaultExport}(${importVar})() || "")`, |
| | | type: /** @type {CssParserExportType} */ ( |
| | | /** @type {BuildMeta} */ (depModule.buildMeta).exportType |
| | | ) |
| | | type: /** @type {CssParserExportType} */ (depModule.exportType) |
| | | }); |
| | | } else { |
| | | parts.push({ |
| | | expr: importVar, |
| | | type: /** @type {CssParserExportType} */ (depModule.exportType) |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Generate CSS code for the current module |
| | | * @param {NormalModule} module the module to generate CSS code for |
| | | * Generate CSS source for the current module |
| | | * @param {NormalModule} module the module to generate CSS source for |
| | | * @param {GenerateContext} generateContext the generate context |
| | | * @returns {string} the CSS code as string |
| | | * @returns {Source | null} the CSS source |
| | | */ |
| | | _generateModuleCode(module, generateContext) { |
| | | _generateContentSource(module, generateContext) { |
| | | const moduleSourceContent = /** @type {Source} */ ( |
| | | this.generate(module, { |
| | | ...generateContext, |
| | | type: "css" |
| | | type: CSS_TYPE |
| | | }) |
| | | ); |
| | | |
| | | if (!moduleSourceContent) { |
| | | return ""; |
| | | return null; |
| | | } |
| | | |
| | | const compilation = generateContext.runtimeTemplate.compilation; |
| | | const { path: filename } = compilation.getPathWithInfo( |
| | | compilation.outputOptions.cssChunkFilename, |
| | | { |
| | | runtime: generateContext.runtime, |
| | | contentHashType: "css" |
| | | } |
| | | ); |
| | | const undoPath = getUndoPath( |
| | | filename, |
| | | compilation.outputOptions.path, |
| | | false |
| | | ); |
| | | // For non-link exportTypes (style, text, css-style-sheet), url() in the CSS |
| | | // is resolved relative to the document URL (for <style> tags and CSSStyleSheet), |
| | | // not relative to any output file. Use empty undoPath so urls are relative to |
| | | // the output root. |
| | | const undoPath = ""; |
| | | |
| | | const CssModulesPlugin = getCssModulesPlugin(); |
| | | const hooks = CssModulesPlugin.getCompilationHooks(compilation); |
| | | const renderedSource = CssModulesPlugin.renderModule( |
| | | return CssModulesPlugin.renderModule( |
| | | /** @type {CssModule} */ (module), |
| | | { |
| | | undoPath, |
| | |
| | | }, |
| | | hooks |
| | | ); |
| | | |
| | | if (!renderedSource) { |
| | | return ""; |
| | | } |
| | | |
| | | const content = renderedSource.source(); |
| | | return typeof content === "string" ? content : content.toString("utf8"); |
| | | } |
| | | |
| | | /** |
| | | * Convert a CSS Source to a JS string literal Source, preserving source map. |
| | | * Wraps the CSS content with JSON.stringify so it can be embedded in JS code. |
| | | * @param {Source} cssSource the CSS source |
| | | * @param {NormalModule} module the module |
| | | * @returns {Source} a Source representing a JS string literal |
| | | */ |
| | | _cssSourceToJsStringLiteral(cssSource, module) { |
| | | const { source, map } = cssSource.sourceAndMap(); |
| | | const content = /** @type {string} */ (source); |
| | | const escaped = JSON.stringify(content); |
| | | if (map) { |
| | | return new SourceMapSource(escaped, module.identifier(), map, content); |
| | | } |
| | | return new RawSource(escaped); |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided module. |
| | | * @param {NormalModule} module the current module |
| | | * @param {Dependency} dependency the dependency to generate |
| | | * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments |
| | |
| | | } |
| | | |
| | | /** |
| | | * Processes the provided module. |
| | | * @param {NormalModule} module the module to generate |
| | | * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments |
| | | * @param {ReplaceSource} source the current replace source which can be modified |
| | |
| | | } |
| | | |
| | | /** |
| | | * Generates generated code for this runtime module. |
| | | * @param {NormalModule} module module for which the code should be generated |
| | | * @param {GenerateContext} generateContext context for generate |
| | | * @returns {Source | null} generated code |
| | | */ |
| | | generate(module, generateContext) { |
| | | const exportType = /** @type {BuildMeta} */ (module.buildMeta).exportType; |
| | | const exportType = /** @type {CssModule} */ (module).exportType || "link"; |
| | | const source = |
| | | generateContext.type === "javascript" |
| | | ? exportType === "link" |
| | | generateContext.type === JAVASCRIPT_TYPE && exportType === "link" |
| | | ? new ReplaceSource(new RawSource("")) |
| | | : new ReplaceSource(/** @type {Source} */ (module.originalSource())) |
| | | : new ReplaceSource(/** @type {Source} */ (module.originalSource())); |
| | | /** @type {InitFragment<GenerateContext>[]} */ |
| | | const initFragments = []; |
| | |
| | | cssData |
| | | }); |
| | | |
| | | switch (generateContext.type) { |
| | | case JAVASCRIPT_TYPE: { |
| | | const generateContentCode = () => { |
| | | switch (exportType) { |
| | | case "style": { |
| | | const cssSource = this._generateContentSource( |
| | | module, |
| | | generateContext |
| | | ); |
| | | if (!cssSource) return ""; |
| | | const moduleId = generateContext.chunkGraph.getModuleId(module); |
| | | |
| | | generateContext.runtimeRequirements.add( |
| | | RuntimeGlobals.cssInjectStyle |
| | | ); |
| | | |
| | | return new ConcatSource( |
| | | `${RuntimeGlobals.cssInjectStyle}(${JSON.stringify(moduleId || "")}, `, |
| | | this._cssSourceToJsStringLiteral(cssSource, module), |
| | | ");" |
| | | ); |
| | | } |
| | | |
| | | default: |
| | | return ""; |
| | | } |
| | | }; |
| | | const generateImportCode = () => { |
| | | switch (exportType) { |
| | | case "style": { |
| | | return this._generateImportCode(module, generateContext, false) |
| | | .map((part) => `${part.expr};`) |
| | | .join("\n"); |
| | | } |
| | | default: |
| | | return ""; |
| | | } |
| | | }; |
| | | const generateExportCode = () => { |
| | | /** @returns {Source} generated CSS text as JS expression */ |
| | | const generateCssText = () => { |
| | | const importCode = this._generateImportCode(module, generateContext); |
| | | const moduleCode = this._generateModuleCode(module, generateContext); |
| | | const importCode = this._generateImportCode( |
| | | module, |
| | | generateContext |
| | | ); |
| | | const cssSource = this._generateContentSource( |
| | | module, |
| | | generateContext |
| | | ); |
| | | |
| | | let jsLiteral = cssSource |
| | | ? this._cssSourceToJsStringLiteral(cssSource, module) |
| | | : new RawSource('""'); |
| | | |
| | | if (importCode.length > 0) { |
| | | if ( |
| | |
| | | RuntimeGlobals.cssMergeStyleSheets |
| | | ); |
| | | |
| | | return `${RuntimeGlobals.cssMergeStyleSheets}([${[...importCode.map((part) => part.expr), JSON.stringify(moduleCode)].join(", ")}])`; |
| | | } |
| | | return generateContext.runtimeTemplate.concatenation( |
| | | ...importCode, |
| | | moduleCode |
| | | const args = importCode.map((part) => part.expr); |
| | | |
| | | jsLiteral = new ConcatSource( |
| | | `${RuntimeGlobals.cssMergeStyleSheets}([${args.join(", ")}, `, |
| | | jsLiteral, |
| | | "])" |
| | | ); |
| | | } else { |
| | | jsLiteral = new ConcatSource( |
| | | `${generateContext.runtimeTemplate.concatenation( |
| | | ...importCode |
| | | )} + `, |
| | | jsLiteral |
| | | ); |
| | | } |
| | | return JSON.stringify(moduleCode); |
| | | }; |
| | | } |
| | | |
| | | if ( |
| | | exportType === "css-style-sheet" && |
| | | typeof (/** @type {BuildInfo} */ (module.buildInfo).charset) !== |
| | | "undefined" |
| | | ) { |
| | | jsLiteral = new ConcatSource( |
| | | `'@charset "${/** @type {BuildInfo} */ (module.buildInfo).charset}";\\n' + `, |
| | | jsLiteral |
| | | ); |
| | | } |
| | | |
| | | return jsLiteral; |
| | | }; |
| | | /** |
| | | * @returns {string | null} the default export |
| | | * Generates js default export. |
| | | * @returns {Source | null} the default export |
| | | */ |
| | | const generateJSDefaultExport = () => { |
| | | switch (exportType) { |
| | |
| | | return generateCssText(); |
| | | } |
| | | case "css-style-sheet": { |
| | | const constOrVar = generateContext.runtimeTemplate.renderConst(); |
| | | return `(${generateContext.runtimeTemplate.basicFunction("", [ |
| | | `${constOrVar} cssText = ${generateCssText()};`, |
| | | `${constOrVar} sheet = new CSSStyleSheet();`, |
| | | "sheet.replaceSync(cssText);", |
| | | "return sheet;" |
| | | ])})()`; |
| | | const constOrVar = |
| | | generateContext.runtimeTemplate.renderConst(); |
| | | const cssText = generateCssText(); |
| | | const fnPrefix = |
| | | generateContext.runtimeTemplate.supportsArrowFunction() |
| | | ? "() => {\n" |
| | | : "function() {\n"; |
| | | const body = |
| | | `${constOrVar} sheet = new CSSStyleSheet();\n` + |
| | | "sheet.replaceSync(cssText);\n" + |
| | | "return sheet;\n"; |
| | | return new ConcatSource( |
| | | `(${fnPrefix}${constOrVar} cssText = `, |
| | | cssText, |
| | | `;\n${body}})()` |
| | | ); |
| | | } |
| | | default: |
| | | return null; |
| | | } |
| | | }; |
| | | |
| | | switch (generateContext.type) { |
| | | case "javascript": { |
| | | const isCSSModule = /** @type {BuildMeta} */ (module.buildMeta) |
| | | .isCSSModule; |
| | | /** @type {Source | null} */ |
| | | const defaultExport = generateJSDefaultExport(); |
| | | /** |
| | | * @param {string} name the export name |
| | | * @param {string} value the export value |
| | | * @returns {string} the value to be used in the export |
| | | */ |
| | | const stringifyExportValue = (name, value) => { |
| | | if (defaultExport) { |
| | | return name === "default" ? value : JSON.stringify(value); |
| | | } |
| | | return JSON.stringify(value); |
| | | }; |
| | | |
| | | /** @type {BuildInfo} */ |
| | | (module.buildInfo).cssData = cssData; |
| | |
| | | generateContext.runtimeRequirements.add(RuntimeGlobals.module); |
| | | } |
| | | |
| | | if (defaultExport) { |
| | | cssData.exports.set("default", /** @type {string} */ (defaultExport)); |
| | | } |
| | | |
| | | if (cssData.exports.size === 0 && !isCSSModule) { |
| | | if (!defaultExport && cssData.exports.size === 0 && !isCSSModule) { |
| | | return new RawSource(""); |
| | | } |
| | | |
| | | if (generateContext.concatenationScope) { |
| | | const source = new ConcatSource(); |
| | | /** @type {Set<string>} */ |
| | | const usedIdentifiers = new Set(); |
| | | const { RESERVED_IDENTIFIER } = getPropertyName(); |
| | | |
| | | if (defaultExport) { |
| | | const usedName = generateContext.moduleGraph |
| | | .getExportInfo(module, "default") |
| | | .getUsedName("default", generateContext.runtime); |
| | | if (usedName) { |
| | | let identifier = Template.toIdentifier(usedName); |
| | | if (RESERVED_IDENTIFIER.has(identifier)) { |
| | | identifier = `_${identifier}`; |
| | | } |
| | | usedIdentifiers.add(identifier); |
| | | generateContext.concatenationScope.registerExport( |
| | | "default", |
| | | identifier |
| | | ); |
| | | source.add( |
| | | `${generateContext.runtimeTemplate.renderConst()} ${identifier} = ` |
| | | ); |
| | | source.add(defaultExport); |
| | | source.add(";\n"); |
| | | } |
| | | } |
| | | |
| | | for (const [name, v] of cssData.exports) { |
| | | const usedName = generateContext.moduleGraph |
| | |
| | | if (!usedName) { |
| | | continue; |
| | | } |
| | | let identifier = Template.toIdentifier(usedName); |
| | | |
| | | let identifier = Template.toIdentifier(usedName); |
| | | if (RESERVED_IDENTIFIER.has(identifier)) { |
| | | identifier = `_${identifier}`; |
| | | } |
| | | const i = 0; |
| | | let i = 0; |
| | | while (usedIdentifiers.has(identifier)) { |
| | | identifier = Template.toIdentifier(name + i); |
| | | i += 1; |
| | | } |
| | | usedIdentifiers.add(identifier); |
| | | generateContext.concatenationScope.registerExport(name, identifier); |
| | | generateContext.concatenationScope.registerExport( |
| | | name, |
| | | identifier |
| | | ); |
| | | source.add( |
| | | `${generateContext.runtimeTemplate.renderConst()} ${identifier} = ${stringifyExportValue(name, v)};\n` |
| | | `${generateContext.runtimeTemplate.renderConst()} ${identifier} = ${JSON.stringify(v)};\n` |
| | | ); |
| | | } |
| | | return source; |
| | |
| | | generateContext.runtimeRequirements.add(RuntimeGlobals.module); |
| | | |
| | | if (!isCSSModule && !needNsObj) { |
| | | return new RawSource( |
| | | `${module.moduleArgument}.exports = ${defaultExport}` |
| | | return new ConcatSource( |
| | | `${module.moduleArgument}.exports = `, |
| | | /** @type {Source} */ (defaultExport) |
| | | ); |
| | | } |
| | | |
| | | const exports = []; |
| | | |
| | | for (const [name, v] of cssData.exports) { |
| | | exports.push( |
| | | `\t${JSON.stringify(name)}: ${stringifyExportValue(name, v)}` |
| | | ); |
| | | } |
| | | |
| | | return new RawSource( |
| | | const result = new ConcatSource(); |
| | | result.add( |
| | | `${needNsObj ? `${RuntimeGlobals.makeNamespaceObject}(` : ""}${ |
| | | module.moduleArgument |
| | | }.exports = {\n${exports.join(",\n")}\n}${needNsObj ? ")" : ""};` |
| | | }.exports = {\n` |
| | | ); |
| | | |
| | | if (defaultExport) { |
| | | result.add('\t"default": '); |
| | | result.add(defaultExport); |
| | | if (cssData.exports.size > 0) { |
| | | result.add(",\n"); |
| | | } |
| | | } |
| | | |
| | | /** @type {string[]} */ |
| | | const exportEntries = []; |
| | | for (const [name, v] of cssData.exports) { |
| | | exportEntries.push( |
| | | `\t${JSON.stringify(name)}: ${JSON.stringify(v)}` |
| | | ); |
| | | } |
| | | case "css": { |
| | | if (!this._generatesJsOnly(module)) { |
| | | if (exportEntries.length > 0) { |
| | | result.add(exportEntries.join(",\n")); |
| | | } |
| | | |
| | | result.add(`\n}${needNsObj ? ")" : ""};`); |
| | | return result; |
| | | }; |
| | | |
| | | const codeParts = this._exportsOnly |
| | | ? [generateExportCode()] |
| | | : [generateImportCode(), generateContentCode(), generateExportCode()]; |
| | | |
| | | const source = new ConcatSource(); |
| | | for (const part of codeParts) { |
| | | if (part) { |
| | | source.add(part); |
| | | source.add("\n"); |
| | | } |
| | | } |
| | | return source; |
| | | } |
| | | case CSS_TYPE: { |
| | | if ( |
| | | !( |
| | | this._exportsOnly || |
| | | /** @type {boolean} */ (exportType && exportType !== "link") |
| | | ) |
| | | ) { |
| | | generateContext.runtimeRequirements.add(RuntimeGlobals.hasCssModules); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Generates fallback output for the provided error condition. |
| | | * @param {Error} error the error |
| | | * @param {NormalModule} module module for which the code should be generated |
| | | * @param {GenerateContext} generateContext context for generate |
| | |
| | | */ |
| | | generateError(error, module, generateContext) { |
| | | switch (generateContext.type) { |
| | | case "javascript": { |
| | | case JAVASCRIPT_TYPE: { |
| | | return new RawSource( |
| | | `throw new Error(${JSON.stringify(error.message)});` |
| | | ); |
| | | } |
| | | case "css": { |
| | | case CSS_TYPE: { |
| | | return new RawSource(`/**\n ${error.message} \n**/`); |
| | | } |
| | | default: |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns the source types available for this module. |
| | | * @param {NormalModule} module fresh module |
| | | * @returns {SourceTypes} available types (do not mutate) |
| | | */ |
| | | getTypes(module) { |
| | | if (this._generatesJsOnly(module)) { |
| | | return JS_TYPES; |
| | | const exportType = /** @type {CssModule} */ (module).exportType || "link"; |
| | | if (exportType === "style") { |
| | | return JAVASCRIPT_TYPES; |
| | | } |
| | | |
| | | const sourceTypes = new Set(); |
| | | const connections = this._moduleGraph.getIncomingConnections(module); |
| | | |
| | | for (const connection of connections) { |
| | | if ( |
| | | exportType === "link" && |
| | | connection.dependency instanceof CssImportDependency |
| | | ) { |
| | | continue; |
| | | } |
| | | |
| | | // when no hmr required, css module js output contains no sideEffects at all |
| | | // js sideeffect connection doesn't require js type output |
| | | if (connection.dependency instanceof HarmonyImportSideEffectDependency) { |
| | | continue; |
| | | } |
| | | |
| | | if (!connection.originModule) { |
| | | continue; |
| | | } |
| | | |
| | | if (connection.originModule.type.split("/")[0] !== CSS_TYPE) { |
| | | sourceTypes.add(JS_TYPE); |
| | | sourceTypes.add(JAVASCRIPT_TYPE); |
| | | } else { |
| | | const originModule = /** @type {CssModule} */ connection.originModule; |
| | | const originExportType = /** @type {CssModule} */ (originModule) |
| | | .exportType; |
| | | if ( |
| | | /** @type {boolean} */ ( |
| | | originExportType && originExportType !== "link" |
| | | ) |
| | | ) { |
| | | sourceTypes.add(JAVASCRIPT_TYPE); |
| | | } |
| | | } |
| | | if (sourceTypes.has(JS_TYPE)) { |
| | | return JS_AND_CSS_TYPES; |
| | | } |
| | | if ( |
| | | this._exportsOnly || |
| | | /** @type {boolean} */ (exportType && exportType !== "link") |
| | | ) { |
| | | if (sourceTypes.has(JAVASCRIPT_TYPE)) { |
| | | return JAVASCRIPT_TYPES; |
| | | } |
| | | return new Set(); |
| | | } |
| | | if (sourceTypes.has(JAVASCRIPT_TYPE)) { |
| | | return JAVASCRIPT_AND_CSS_TYPES; |
| | | } |
| | | return CSS_TYPES; |
| | | } |
| | | |
| | | /** |
| | | * Returns the estimated size for the requested source type. |
| | | * @param {NormalModule} module the module |
| | | * @param {string=} type source type |
| | | * @param {SourceType=} type source type |
| | | * @returns {number} estimate size of the module |
| | | */ |
| | | getSize(module, type) { |
| | | switch (type) { |
| | | case "javascript": { |
| | | case JAVASCRIPT_TYPE: { |
| | | const cssData = /** @type {BuildInfo} */ (module.buildInfo).cssData; |
| | | if (!cssData) { |
| | | return 42; |
| | |
| | | return 0; |
| | | } |
| | | const exports = cssData.exports; |
| | | const stringifiedExports = JSON.stringify( |
| | | [...exports].reduce((obj, [key, value]) => { |
| | | obj[key] = value; |
| | | return obj; |
| | | }, /** @type {Record<string, string>} */ ({})) |
| | | ); |
| | | /** @type {Record<string, string>} */ |
| | | const exportsObj = {}; |
| | | for (const [key, value] of exports) { |
| | | exportsObj[key] = value; |
| | | } |
| | | const stringifiedExports = JSON.stringify(exportsObj); |
| | | |
| | | return stringifiedExports.length + 42; |
| | | } |
| | | case "css": { |
| | | case CSS_TYPE: { |
| | | const originalSource = module.originalSource(); |
| | | |
| | | if (!originalSource) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Updates the hash with the data contributed by this instance. |
| | | * @param {Hash} hash hash that will be modified |
| | | * @param {UpdateHashContext} updateHashContext context for updating hash |
| | | */ |
| | | updateHash(hash, { module }) { |
| | | hash.update(/** @type {boolean} */ (this._esModule).toString()); |
| | | } |
| | | |
| | | /** |
| | | * @param {NormalModule} module module |
| | | * @returns {boolean} true if the module only outputs JavaScript |
| | | */ |
| | | _generatesJsOnly(module) { |
| | | const exportType = /** @type {BuildMeta} */ (module.buildMeta).exportType; |
| | | return ( |
| | | this._exportsOnly || |
| | | /** @type {boolean} */ (exportType && exportType !== "link") |
| | | ); |
| | | hash.update(/** @type {boolean} */ (this._exportsOnly).toString()); |
| | | } |
| | | } |
| | | |