From efbc2ffe6a1ee5ec38a4396305561d6515d0943e Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Fri, 30 Aug 2024 17:21:18 +0800 Subject: node fixes, updates --- node_modules/webpack/lib/css/CssModulesPlugin.js | 888 +++++++++++++++++++++++ 1 file changed, 888 insertions(+) create mode 100644 node_modules/webpack/lib/css/CssModulesPlugin.js (limited to 'node_modules/webpack/lib/css/CssModulesPlugin.js') diff --git a/node_modules/webpack/lib/css/CssModulesPlugin.js b/node_modules/webpack/lib/css/CssModulesPlugin.js new file mode 100644 index 00000000..213c2178 --- /dev/null +++ b/node_modules/webpack/lib/css/CssModulesPlugin.js @@ -0,0 +1,888 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { SyncWaterfallHook, SyncHook } = require("tapable"); +const { + ConcatSource, + PrefixSource, + ReplaceSource, + CachedSource +} = require("webpack-sources"); +const Compilation = require("../Compilation"); +const CssModule = require("../CssModule"); +const { tryRunOrWebpackError } = require("../HookWebpackError"); +const HotUpdateChunk = require("../HotUpdateChunk"); +const { + CSS_MODULE_TYPE, + CSS_MODULE_TYPE_GLOBAL, + CSS_MODULE_TYPE_MODULE, + CSS_MODULE_TYPE_AUTO +} = require("../ModuleTypeConstants"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const SelfModuleFactory = require("../SelfModuleFactory"); +const WebpackError = require("../WebpackError"); +const CssExportDependency = require("../dependencies/CssExportDependency"); +const CssImportDependency = require("../dependencies/CssImportDependency"); +const CssLocalIdentifierDependency = require("../dependencies/CssLocalIdentifierDependency"); +const CssSelfLocalIdentifierDependency = require("../dependencies/CssSelfLocalIdentifierDependency"); +const CssUrlDependency = require("../dependencies/CssUrlDependency"); +const StaticExportsDependency = require("../dependencies/StaticExportsDependency"); +const { compareModulesByIdentifier } = require("../util/comparators"); +const createSchemaValidation = require("../util/create-schema-validation"); +const createHash = require("../util/createHash"); +const { getUndoPath } = require("../util/identifier"); +const memoize = require("../util/memoize"); +const nonNumericOnlyHash = require("../util/nonNumericOnlyHash"); +const CssExportsGenerator = require("./CssExportsGenerator"); +const CssGenerator = require("./CssGenerator"); +const CssParser = require("./CssParser"); + +/** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} OutputOptions */ +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */ +/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../CssModule").Inheritance} Inheritance */ +/** @typedef {import("../DependencyTemplate").CssExportsData} CssExportsData */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Template").RuntimeTemplate} RuntimeTemplate */ +/** @typedef {import("../TemplatedPathPlugin").TemplatePath} TemplatePath */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/memoize")} Memoize */ + +/** + * @typedef {object} ChunkRenderContext + * @property {RuntimeTemplate} runtimeTemplate runtime template + */ + +/** + * @typedef {object} CompilationHooks + * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModulePackage + * @property {SyncHook<[Chunk, Hash, ChunkHashContext]>} chunkHash + */ + +const getCssLoadingRuntimeModule = memoize(() => + require("./CssLoadingRuntimeModule") +); + +/** + * @param {string} name name + * @returns {{oneOf: [{$ref: string}], definitions: *}} schema + */ +const getSchema = name => { + const { definitions } = require("../../schemas/WebpackOptions.json"); + return { + definitions, + oneOf: [{ $ref: `#/definitions/${name}` }] + }; +}; + +const generatorValidationOptions = { + name: "Css Modules Plugin", + baseDataPath: "generator" +}; +const validateGeneratorOptions = { + css: createSchemaValidation( + require("../../schemas/plugins/css/CssGeneratorOptions.check.js"), + () => getSchema("CssGeneratorOptions"), + generatorValidationOptions + ), + "css/auto": createSchemaValidation( + require("../../schemas/plugins/css/CssAutoGeneratorOptions.check.js"), + () => getSchema("CssAutoGeneratorOptions"), + generatorValidationOptions + ), + "css/module": createSchemaValidation( + require("../../schemas/plugins/css/CssModuleGeneratorOptions.check.js"), + () => getSchema("CssModuleGeneratorOptions"), + generatorValidationOptions + ), + "css/global": createSchemaValidation( + require("../../schemas/plugins/css/CssGlobalGeneratorOptions.check.js"), + () => getSchema("CssGlobalGeneratorOptions"), + generatorValidationOptions + ) +}; + +const parserValidationOptions = { + name: "Css Modules Plugin", + baseDataPath: "parser" +}; +const validateParserOptions = { + css: createSchemaValidation( + require("../../schemas/plugins/css/CssParserOptions.check.js"), + () => getSchema("CssParserOptions"), + parserValidationOptions + ), + "css/auto": createSchemaValidation( + require("../../schemas/plugins/css/CssAutoParserOptions.check.js"), + () => getSchema("CssAutoParserOptions"), + parserValidationOptions + ), + "css/module": createSchemaValidation( + require("../../schemas/plugins/css/CssModuleParserOptions.check.js"), + () => getSchema("CssModuleParserOptions"), + parserValidationOptions + ), + "css/global": createSchemaValidation( + require("../../schemas/plugins/css/CssGlobalParserOptions.check.js"), + () => getSchema("CssGlobalParserOptions"), + parserValidationOptions + ) +}; + +/** @type {WeakMap} */ +const compilationHooksMap = new WeakMap(); + +/** + * @param {string} str string + * @param {boolean=} omitOptionalUnderscore if true, optional underscore is not added + * @returns {string} escaped string + */ +const escapeCss = (str, omitOptionalUnderscore) => { + const escaped = `${str}`.replace( + // cspell:word uffff + /[^a-zA-Z0-9_\u0081-\uFFFF-]/g, + s => `\\${s}` + ); + return !omitOptionalUnderscore && /^(?!--)[0-9_-]/.test(escaped) + ? `_${escaped}` + : escaped; +}; + +/** + * @param {string} str string + * @returns {string} encoded string + */ +const lzwEncode = str => { + /** @type {Map} */ + const map = new Map(); + let encoded = ""; + let phrase = str[0]; + let code = 256; + const maxCode = "\uFFFF".charCodeAt(0); + for (let i = 1; i < str.length; i++) { + const c = str[i]; + if (map.has(phrase + c)) { + phrase += c; + } else { + encoded += phrase.length > 1 ? map.get(phrase) : phrase; + map.set(phrase + c, String.fromCharCode(code)); + phrase = c; + if (++code > maxCode) { + code = 256; + map.clear(); + } + } + } + encoded += phrase.length > 1 ? map.get(phrase) : phrase; + return encoded; +}; + +const PLUGIN_NAME = "CssModulesPlugin"; + +class CssModulesPlugin { + /** + * @param {Compilation} compilation the compilation + * @returns {CompilationHooks} the attached hooks + */ + static getCompilationHooks(compilation) { + if (!(compilation instanceof Compilation)) { + throw new TypeError( + "The 'compilation' argument must be an instance of Compilation" + ); + } + let hooks = compilationHooksMap.get(compilation); + if (hooks === undefined) { + hooks = { + renderModulePackage: new SyncWaterfallHook([ + "source", + "module", + "renderContext" + ]), + chunkHash: new SyncHook(["chunk", "hash", "context"]) + }; + compilationHooksMap.set(compilation, hooks); + } + return hooks; + } + + constructor() { + /** @type {WeakMap} */ + this._moduleCache = new WeakMap(); + } + + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { normalModuleFactory }) => { + const hooks = CssModulesPlugin.getCompilationHooks(compilation); + const selfFactory = new SelfModuleFactory(compilation.moduleGraph); + compilation.dependencyFactories.set( + CssUrlDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + CssUrlDependency, + new CssUrlDependency.Template() + ); + compilation.dependencyTemplates.set( + CssLocalIdentifierDependency, + new CssLocalIdentifierDependency.Template() + ); + compilation.dependencyFactories.set( + CssSelfLocalIdentifierDependency, + selfFactory + ); + compilation.dependencyTemplates.set( + CssSelfLocalIdentifierDependency, + new CssSelfLocalIdentifierDependency.Template() + ); + compilation.dependencyTemplates.set( + CssExportDependency, + new CssExportDependency.Template() + ); + compilation.dependencyFactories.set( + CssImportDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + CssImportDependency, + new CssImportDependency.Template() + ); + compilation.dependencyTemplates.set( + StaticExportsDependency, + new StaticExportsDependency.Template() + ); + for (const type of [ + CSS_MODULE_TYPE, + CSS_MODULE_TYPE_GLOBAL, + CSS_MODULE_TYPE_MODULE, + CSS_MODULE_TYPE_AUTO + ]) { + normalModuleFactory.hooks.createParser + .for(type) + .tap(PLUGIN_NAME, parserOptions => { + validateParserOptions[type](parserOptions); + const { namedExports } = parserOptions; + + switch (type) { + case CSS_MODULE_TYPE_GLOBAL: + case CSS_MODULE_TYPE_AUTO: + return new CssParser({ + namedExports + }); + case CSS_MODULE_TYPE: + return new CssParser({ + allowModeSwitch: false, + namedExports + }); + case CSS_MODULE_TYPE_MODULE: + return new CssParser({ + defaultMode: "local", + namedExports + }); + } + }); + normalModuleFactory.hooks.createGenerator + .for(type) + .tap(PLUGIN_NAME, generatorOptions => { + validateGeneratorOptions[type](generatorOptions); + + return generatorOptions.exportsOnly + ? new CssExportsGenerator( + generatorOptions.exportsConvention, + generatorOptions.localIdentName, + generatorOptions.esModule + ) + : new CssGenerator( + generatorOptions.exportsConvention, + generatorOptions.localIdentName, + generatorOptions.esModule + ); + }); + normalModuleFactory.hooks.createModuleClass + .for(type) + .tap(PLUGIN_NAME, (createData, resolveData) => { + if (resolveData.dependencies.length > 0) { + // When CSS is imported from CSS there is only one dependency + const dependency = resolveData.dependencies[0]; + + if (dependency instanceof CssImportDependency) { + const parent = + /** @type {CssModule} */ + (compilation.moduleGraph.getParentModule(dependency)); + + if (parent instanceof CssModule) { + /** @type {import("../CssModule").Inheritance | undefined} */ + let inheritance; + + if ( + (parent.cssLayer !== null && + parent.cssLayer !== undefined) || + parent.supports || + parent.media + ) { + if (!inheritance) { + inheritance = []; + } + + inheritance.push([ + parent.cssLayer, + parent.supports, + parent.media + ]); + } + + if (parent.inheritance) { + if (!inheritance) { + inheritance = []; + } + + inheritance.push(...parent.inheritance); + } + + return new CssModule({ + ...createData, + cssLayer: dependency.layer, + supports: dependency.supports, + media: dependency.media, + inheritance + }); + } + + return new CssModule({ + ...createData, + cssLayer: dependency.layer, + supports: dependency.supports, + media: dependency.media + }); + } + } + + return new CssModule(createData); + }); + } + const orderedCssModulesPerChunk = new WeakMap(); + compilation.hooks.afterCodeGeneration.tap("CssModulesPlugin", () => { + const { chunkGraph } = compilation; + for (const chunk of compilation.chunks) { + if (CssModulesPlugin.chunkHasCss(chunk, chunkGraph)) { + orderedCssModulesPerChunk.set( + chunk, + this.getOrderedChunkCssModules(chunk, chunkGraph, compilation) + ); + } + } + }); + compilation.hooks.chunkHash.tap( + "CssModulesPlugin", + (chunk, hash, context) => { + hooks.chunkHash.call(chunk, hash, context); + } + ); + compilation.hooks.contentHash.tap("CssModulesPlugin", chunk => { + const { + chunkGraph, + codeGenerationResults, + moduleGraph, + runtimeTemplate, + outputOptions: { + hashSalt, + hashDigest, + hashDigestLength, + hashFunction + } + } = compilation; + const hash = createHash(hashFunction); + if (hashSalt) hash.update(hashSalt); + hooks.chunkHash.call(chunk, hash, { + chunkGraph, + codeGenerationResults, + moduleGraph, + runtimeTemplate + }); + const modules = orderedCssModulesPerChunk.get(chunk); + if (modules) { + for (const module of modules) { + hash.update(chunkGraph.getModuleHash(module, chunk.runtime)); + } + } + const digest = /** @type {string} */ (hash.digest(hashDigest)); + chunk.contentHash.css = nonNumericOnlyHash(digest, hashDigestLength); + }); + compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => { + const { chunkGraph } = compilation; + const { hash, chunk, codeGenerationResults, runtimeTemplate } = + options; + + if (chunk instanceof HotUpdateChunk) return result; + + /** @type {CssModule[] | undefined} */ + const modules = orderedCssModulesPerChunk.get(chunk); + if (modules !== undefined) { + const { path: filename, info } = compilation.getPathWithInfo( + CssModulesPlugin.getChunkFilenameTemplate( + chunk, + compilation.outputOptions + ), + { + hash, + runtime: chunk.runtime, + chunk, + contentHashType: "css" + } + ); + const undoPath = getUndoPath( + filename, + compilation.outputOptions.path, + false + ); + result.push({ + render: () => + this.renderChunk({ + chunk, + chunkGraph, + codeGenerationResults, + uniqueName: compilation.outputOptions.uniqueName, + cssHeadDataCompression: + compilation.outputOptions.cssHeadDataCompression, + undoPath, + modules, + runtimeTemplate, + hooks + }), + filename, + info, + identifier: `css${chunk.id}`, + hash: chunk.contentHash.css + }); + } + return result; + }); + const globalChunkLoading = compilation.outputOptions.chunkLoading; + /** + * @param {Chunk} chunk the chunk + * @returns {boolean} true, when enabled + */ + const isEnabledForChunk = chunk => { + const options = chunk.getEntryOptions(); + const chunkLoading = + options && options.chunkLoading !== undefined + ? options.chunkLoading + : globalChunkLoading; + return chunkLoading === "jsonp" || chunkLoading === "import"; + }; + const onceForChunkSet = new WeakSet(); + /** + * @param {Chunk} chunk chunk to check + * @param {Set} set runtime requirements + */ + const handler = (chunk, set) => { + if (onceForChunkSet.has(chunk)) return; + onceForChunkSet.add(chunk); + if (!isEnabledForChunk(chunk)) return; + + set.add(RuntimeGlobals.publicPath); + set.add(RuntimeGlobals.getChunkCssFilename); + set.add(RuntimeGlobals.hasOwnProperty); + set.add(RuntimeGlobals.moduleFactoriesAddOnly); + set.add(RuntimeGlobals.makeNamespaceObject); + + const CssLoadingRuntimeModule = getCssLoadingRuntimeModule(); + compilation.addRuntimeModule(chunk, new CssLoadingRuntimeModule(set)); + }; + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.hasCssModules) + .tap(PLUGIN_NAME, handler); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.ensureChunkHandlers) + .tap(PLUGIN_NAME, handler); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.hmrDownloadUpdateHandlers) + .tap(PLUGIN_NAME, handler); + } + ); + } + + /** + * @param {Chunk} chunk chunk + * @param {Iterable} modules unordered modules + * @param {Compilation} compilation compilation + * @returns {Module[]} ordered modules + */ + getModulesInOrder(chunk, modules, compilation) { + if (!modules) return []; + + /** @type {Module[]} */ + const modulesList = [...modules]; + + // Get ordered list of modules per chunk group + // Lists are in reverse order to allow to use Array.pop() + const modulesByChunkGroup = Array.from(chunk.groupsIterable, chunkGroup => { + const sortedModules = modulesList + .map(module => ({ + module, + index: chunkGroup.getModulePostOrderIndex(module) + })) + .filter(item => item.index !== undefined) + .sort( + (a, b) => + /** @type {number} */ (b.index) - /** @type {number} */ (a.index) + ) + .map(item => item.module); + + return { list: sortedModules, set: new Set(sortedModules) }; + }); + + if (modulesByChunkGroup.length === 1) + return modulesByChunkGroup[0].list.reverse(); + + const compareModuleLists = ({ list: a }, { list: b }) => { + if (a.length === 0) { + return b.length === 0 ? 0 : 1; + } + if (b.length === 0) return -1; + return compareModulesByIdentifier(a[a.length - 1], b[b.length - 1]); + }; + + modulesByChunkGroup.sort(compareModuleLists); + + /** @type {Module[]} */ + const finalModules = []; + + for (;;) { + const failedModules = new Set(); + const list = modulesByChunkGroup[0].list; + if (list.length === 0) { + // done, everything empty + break; + } + /** @type {Module} */ + let selectedModule = list[list.length - 1]; + let hasFailed; + outer: for (;;) { + for (const { list, set } of modulesByChunkGroup) { + if (list.length === 0) continue; + const lastModule = list[list.length - 1]; + if (lastModule === selectedModule) continue; + if (!set.has(selectedModule)) continue; + failedModules.add(selectedModule); + if (failedModules.has(lastModule)) { + // There is a conflict, try other alternatives + hasFailed = lastModule; + continue; + } + selectedModule = lastModule; + hasFailed = false; + continue outer; // restart + } + break; + } + if (hasFailed) { + // There is a not resolve-able conflict with the selectedModule + // TODO print better warning + compilation.warnings.push( + new WebpackError( + `chunk ${chunk.name || chunk.id}\nConflicting order between ${ + /** @type {Module} */ + (hasFailed).readableIdentifier(compilation.requestShortener) + } and ${selectedModule.readableIdentifier( + compilation.requestShortener + )}` + ) + ); + selectedModule = /** @type {Module} */ (hasFailed); + } + // Insert the selected module into the final modules list + finalModules.push(selectedModule); + // Remove the selected module from all lists + for (const { list, set } of modulesByChunkGroup) { + const lastModule = list[list.length - 1]; + if (lastModule === selectedModule) list.pop(); + else if (hasFailed && set.has(selectedModule)) { + const idx = list.indexOf(selectedModule); + if (idx >= 0) list.splice(idx, 1); + } + } + modulesByChunkGroup.sort(compareModuleLists); + } + return finalModules; + } + + /** + * @param {Chunk} chunk chunk + * @param {ChunkGraph} chunkGraph chunk graph + * @param {Compilation} compilation compilation + * @returns {Module[]} ordered css modules + */ + getOrderedChunkCssModules(chunk, chunkGraph, compilation) { + return [ + ...this.getModulesInOrder( + chunk, + /** @type {Iterable} */ + ( + chunkGraph.getOrderedChunkModulesIterableBySourceType( + chunk, + "css-import", + compareModulesByIdentifier + ) + ), + compilation + ), + ...this.getModulesInOrder( + chunk, + /** @type {Iterable} */ + ( + chunkGraph.getOrderedChunkModulesIterableBySourceType( + chunk, + "css", + compareModulesByIdentifier + ) + ), + compilation + ) + ]; + } + + /** + * @param {object} options options + * @param {string[]} options.metaData meta data + * @param {string} options.undoPath undo path for public path auto + * @param {Chunk} options.chunk chunk + * @param {ChunkGraph} options.chunkGraph chunk graph + * @param {CodeGenerationResults} options.codeGenerationResults code generation results + * @param {CssModule} options.module css module + * @param {RuntimeTemplate} options.runtimeTemplate runtime template + * @param {CompilationHooks} options.hooks hooks + * @returns {Source} css module source + */ + renderModule({ + metaData, + undoPath, + chunk, + chunkGraph, + codeGenerationResults, + module, + hooks, + runtimeTemplate + }) { + const codeGenResult = codeGenerationResults.get(module, chunk.runtime); + const moduleSourceContent = + /** @type {Source} */ + ( + codeGenResult.sources.get("css") || + codeGenResult.sources.get("css-import") + ); + + const cacheEntry = this._moduleCache.get(moduleSourceContent); + + /** @type {Inheritance} */ + const inheritance = [[module.cssLayer, module.supports, module.media]]; + if (module.inheritance) { + inheritance.push(...module.inheritance); + } + + let source; + if ( + cacheEntry && + cacheEntry.undoPath === undoPath && + cacheEntry.inheritance.every(([layer, supports, media], i) => { + const item = inheritance[i]; + if (Array.isArray(item)) { + return layer === item[0] && supports === item[1] && media === item[2]; + } + return false; + }) + ) { + source = cacheEntry.source; + } else { + const moduleSourceCode = /** @type {string} */ ( + moduleSourceContent.source() + ); + const publicPathAutoRegex = new RegExp( + CssUrlDependency.PUBLIC_PATH_AUTO, + "g" + ); + /** @type {Source} */ + let moduleSource = new ReplaceSource(moduleSourceContent); + let match; + while ((match = publicPathAutoRegex.exec(moduleSourceCode))) { + /** @type {ReplaceSource} */ (moduleSource).replace( + match.index, + (match.index += match[0].length - 1), + undoPath + ); + } + + for (let i = 0; i < inheritance.length; i++) { + const layer = inheritance[i][0]; + const supports = inheritance[i][1]; + const media = inheritance[i][2]; + + if (media) { + moduleSource = new ConcatSource( + `@media ${media} {\n`, + new PrefixSource("\t", moduleSource), + "}\n" + ); + } + + if (supports) { + moduleSource = new ConcatSource( + `@supports (${supports}) {\n`, + new PrefixSource("\t", moduleSource), + "}\n" + ); + } + + // Layer can be anonymous + if (layer !== undefined && layer !== null) { + moduleSource = new ConcatSource( + `@layer${layer ? ` ${layer}` : ""} {\n`, + new PrefixSource("\t", moduleSource), + "}\n" + ); + } + } + + if (moduleSource) { + moduleSource = new ConcatSource(moduleSource, "\n"); + } + + source = new CachedSource(moduleSource); + this._moduleCache.set(moduleSourceContent, { + inheritance, + undoPath, + source + }); + } + /** @type {CssExportsData | undefined} */ + const cssExportsData = + codeGenResult.data && codeGenResult.data.get("css-exports"); + const exports = cssExportsData && cssExportsData.exports; + const esModule = cssExportsData && cssExportsData.esModule; + let moduleId = String(chunkGraph.getModuleId(module)); + + // When `optimization.moduleIds` is `named` the module id is a path, so we need to normalize it between platforms + if (typeof moduleId === "string") { + moduleId = moduleId.replace(/\\/g, "/"); + } + + metaData.push( + `${ + exports + ? Array.from( + exports, + ([n, v]) => `${escapeCss(n)}:${escapeCss(v)}/` + ).join("") + : "" + }${esModule ? "&" : ""}${escapeCss(moduleId)}` + ); + return tryRunOrWebpackError( + () => + hooks.renderModulePackage.call(source, module, { + runtimeTemplate + }), + "CssModulesPlugin.getCompilationHooks().renderModulePackage" + ); + } + + /** + * @param {object} options options + * @param {string | undefined} options.uniqueName unique name + * @param {boolean | undefined} options.cssHeadDataCompression compress css head data + * @param {string} options.undoPath undo path for public path auto + * @param {Chunk} options.chunk chunk + * @param {ChunkGraph} options.chunkGraph chunk graph + * @param {CodeGenerationResults} options.codeGenerationResults code generation results + * @param {CssModule[]} options.modules ordered css modules + * @param {RuntimeTemplate} options.runtimeTemplate runtime template + * @param {CompilationHooks} options.hooks hooks + * @returns {Source} generated source + */ + renderChunk({ + uniqueName, + cssHeadDataCompression, + undoPath, + chunk, + chunkGraph, + codeGenerationResults, + modules, + runtimeTemplate, + hooks + }) { + const source = new ConcatSource(); + /** @type {string[]} */ + const metaData = []; + for (const module of modules) { + try { + const moduleSource = this.renderModule({ + metaData, + undoPath, + chunk, + chunkGraph, + codeGenerationResults, + module, + runtimeTemplate, + hooks + }); + source.add(moduleSource); + } catch (err) { + /** @type {Error} */ + (err).message += `\nduring rendering of css ${module.identifier()}`; + throw err; + } + } + const metaDataStr = metaData.join(","); + source.add( + `head{--webpack-${escapeCss( + (uniqueName ? `${uniqueName}-` : "") + chunk.id, + true + )}:${cssHeadDataCompression ? lzwEncode(metaDataStr) : metaDataStr};}` + ); + chunk.rendered = true; + return source; + } + + /** + * @param {Chunk} chunk chunk + * @param {OutputOptions} outputOptions output options + * @returns {TemplatePath} used filename template + */ + static getChunkFilenameTemplate(chunk, outputOptions) { + if (chunk.cssFilenameTemplate) { + return chunk.cssFilenameTemplate; + } else if (chunk.canBeInitial()) { + return /** @type {TemplatePath} */ (outputOptions.cssFilename); + } + return /** @type {TemplatePath} */ (outputOptions.cssChunkFilename); + } + + /** + * @param {Chunk} chunk chunk + * @param {ChunkGraph} chunkGraph chunk graph + * @returns {boolean} true, when the chunk has css + */ + static chunkHasCss(chunk, chunkGraph) { + return ( + Boolean(chunkGraph.getChunkModulesIterableBySourceType(chunk, "css")) || + Boolean( + chunkGraph.getChunkModulesIterableBySourceType(chunk, "css-import") + ) + ); + } +} + +module.exports = CssModulesPlugin; -- cgit v1.2.3