From 9bce51f651aad297ef9eb6df832bfdaf1de05d84 Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期三, 22 四月 2026 14:27:54 +0800
Subject: [PATCH] 青岛推送

---
 node_modules/webpack/lib/css/CssModulesPlugin.js |  477 +++++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 300 insertions(+), 177 deletions(-)

diff --git a/node_modules/webpack/lib/css/CssModulesPlugin.js b/node_modules/webpack/lib/css/CssModulesPlugin.js
index 01d3128..007466b 100644
--- a/node_modules/webpack/lib/css/CssModulesPlugin.js
+++ b/node_modules/webpack/lib/css/CssModulesPlugin.js
@@ -17,6 +17,7 @@
 const CssModule = require("../CssModule");
 const { tryRunOrWebpackError } = require("../HookWebpackError");
 const HotUpdateChunk = require("../HotUpdateChunk");
+const { CSS_IMPORT_TYPE, CSS_TYPE } = require("../ModuleSourceTypeConstants");
 const {
 	CSS_MODULE_TYPE,
 	CSS_MODULE_TYPE_AUTO,
@@ -25,30 +26,25 @@
 } = require("../ModuleTypeConstants");
 const NormalModule = require("../NormalModule");
 const RuntimeGlobals = require("../RuntimeGlobals");
-const SelfModuleFactory = require("../SelfModuleFactory");
 const Template = require("../Template");
 const WebpackError = require("../WebpackError");
 const CssIcssExportDependency = require("../dependencies/CssIcssExportDependency");
-const CssIcssFromIdentifierDependency = require("../dependencies/CssIcssFromIdentifierDependency");
-const CssIcssGlobalIdentifierDependency = require("../dependencies/CssIcssGlobalIdentifierDependency");
 const CssIcssImportDependency = require("../dependencies/CssIcssImportDependency");
-const CssIcssLocalIdentifierDependency = require("../dependencies/CssIcssLocalIdentifierDependency");
-const CssIcssSelfLocalIdentifierDependency = require("../dependencies/CssIcssSelfLocalIdentifierDependency");
 const CssIcssSymbolDependency = require("../dependencies/CssIcssSymbolDependency");
 const CssImportDependency = require("../dependencies/CssImportDependency");
 const CssUrlDependency = require("../dependencies/CssUrlDependency");
 const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
 const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
-const { compareModulesByIdOrIdentifier } = require("../util/comparators");
-const createSchemaValidation = require("../util/create-schema-validation");
+const { compareModulesByFullName } = require("../util/comparators");
 const createHash = require("../util/createHash");
 const { getUndoPath } = require("../util/identifier");
 const memoize = require("../util/memoize");
 const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
 const removeBOM = require("../util/removeBOM");
 const CssGenerator = require("./CssGenerator");
-const CssMergeStyleSheetsRuntimeModule = require("./CssMergeStyleSheetsRuntimeModule");
 const CssParser = require("./CssParser");
+
+const publicPathAutoRegex = new RegExp(CssUrlDependency.PUBLIC_PATH_AUTO, "g");
 
 /** @typedef {import("webpack-sources").Source} Source */
 /** @typedef {import("../config/defaults").OutputNormalizedWithDefaults} OutputOptions */
@@ -68,6 +64,7 @@
 /** @typedef {import("../Module").BuildMeta} BuildMeta */
 
 /**
+ * Defines the render context type used by this module.
  * @typedef {object} RenderContext
  * @property {Chunk} chunk the chunk
  * @property {ChunkGraph} chunkGraph the chunk graph
@@ -79,6 +76,7 @@
  */
 
 /**
+ * Defines the chunk render context type used by this module.
  * @typedef {object} ChunkRenderContext
  * @property {Chunk=} chunk the chunk
  * @property {ChunkGraph=} chunkGraph the chunk graph
@@ -90,12 +88,14 @@
  */
 
 /**
+ * Defines the compilation hooks type used by this module.
  * @typedef {object} CompilationHooks
  * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModulePackage
  * @property {SyncHook<[Chunk, Hash, ChunkHashContext]>} chunkHash
  */
 
 /**
+ * Defines the module factory cache entry type used by this module.
  * @typedef {object} ModuleFactoryCacheEntry
  * @property {string} undoPath - The undo path to the CSS file
  * @property {Inheritance} inheritance - The inheritance chain
@@ -105,8 +105,15 @@
 const getCssLoadingRuntimeModule = memoize(() =>
 	require("./CssLoadingRuntimeModule")
 );
+const getCssMergeStyleSheetsRuntimeModule = memoize(() =>
+	require("./CssMergeStyleSheetsRuntimeModule")
+);
+const getCssInjectStyleRuntimeModule = memoize(() =>
+	require("./CssInjectStyleRuntimeModule")
+);
 
 /**
+ * Returns ], definitions: import("../../schemas/WebpackOptions.json")["definitions"] }} schema.
  * @param {string} name name
  * @returns {{ oneOf: [{ $ref: string }], definitions: import("../../schemas/WebpackOptions.json")["definitions"] }} schema
  */
@@ -119,58 +126,14 @@
 	};
 };
 
-const generatorValidationOptions = {
-	name: "Css Modules Plugin",
-	baseDataPath: "generator"
-};
-const validateGeneratorOptions = {
-	css: createSchemaValidation(
-		require("../../schemas/plugins/css/CssGeneratorOptions.check"),
-		() => getSchema("CssGeneratorOptions"),
-		generatorValidationOptions
-	),
-	"css/auto": createSchemaValidation(
-		require("../../schemas/plugins/css/CssAutoGeneratorOptions.check"),
-		() => getSchema("CssAutoGeneratorOptions"),
-		generatorValidationOptions
-	),
-	"css/module": createSchemaValidation(
-		require("../../schemas/plugins/css/CssModuleGeneratorOptions.check"),
-		() => getSchema("CssModuleGeneratorOptions"),
-		generatorValidationOptions
-	),
-	"css/global": createSchemaValidation(
-		require("../../schemas/plugins/css/CssGlobalGeneratorOptions.check"),
-		() => getSchema("CssGlobalGeneratorOptions"),
-		generatorValidationOptions
-	)
-};
-
 const parserValidationOptions = {
 	name: "Css Modules Plugin",
 	baseDataPath: "parser"
 };
-const validateParserOptions = {
-	css: createSchemaValidation(
-		require("../../schemas/plugins/css/CssParserOptions.check"),
-		() => getSchema("CssParserOptions"),
-		parserValidationOptions
-	),
-	"css/auto": createSchemaValidation(
-		require("../../schemas/plugins/css/CssAutoParserOptions.check"),
-		() => getSchema("CssAutoParserOptions"),
-		parserValidationOptions
-	),
-	"css/module": createSchemaValidation(
-		require("../../schemas/plugins/css/CssModuleParserOptions.check"),
-		() => getSchema("CssModuleParserOptions"),
-		parserValidationOptions
-	),
-	"css/global": createSchemaValidation(
-		require("../../schemas/plugins/css/CssGlobalParserOptions.check"),
-		() => getSchema("CssGlobalParserOptions"),
-		parserValidationOptions
-	)
+
+const generatorValidationOptions = {
+	name: "Css Modules Plugin",
+	baseDataPath: "generator"
 };
 
 /** @type {WeakMap<Compilation, CompilationHooks>} */
@@ -180,6 +143,7 @@
 
 class CssModulesPlugin {
 	/**
+	 * Returns the attached hooks.
 	 * @param {Compilation} compilation the compilation
 	 * @returns {CompilationHooks} the attached hooks
 	 */
@@ -210,7 +174,7 @@
 	}
 
 	/**
-	 * Apply the plugin
+	 * Applies the plugin by registering its hooks on the compiler.
 	 * @param {Compiler} compiler the compiler instance
 	 * @returns {void}
 	 */
@@ -219,7 +183,6 @@
 			PLUGIN_NAME,
 			(compilation, { normalModuleFactory }) => {
 				const hooks = CssModulesPlugin.getCompilationHooks(compilation);
-				const selfFactory = new SelfModuleFactory(compilation.moduleGraph);
 				compilation.dependencyFactories.set(
 					CssImportDependency,
 					normalModuleFactory
@@ -236,18 +199,6 @@
 					CssUrlDependency,
 					new CssUrlDependency.Template()
 				);
-				compilation.dependencyTemplates.set(
-					CssIcssLocalIdentifierDependency,
-					new CssIcssLocalIdentifierDependency.Template()
-				);
-				compilation.dependencyFactories.set(
-					CssIcssSelfLocalIdentifierDependency,
-					selfFactory
-				);
-				compilation.dependencyTemplates.set(
-					CssIcssSelfLocalIdentifierDependency,
-					new CssIcssSelfLocalIdentifierDependency.Template()
-				);
 				compilation.dependencyFactories.set(
 					CssIcssImportDependency,
 					normalModuleFactory
@@ -255,22 +206,6 @@
 				compilation.dependencyTemplates.set(
 					CssIcssImportDependency,
 					new CssIcssImportDependency.Template()
-				);
-				compilation.dependencyFactories.set(
-					CssIcssFromIdentifierDependency,
-					normalModuleFactory
-				);
-				compilation.dependencyTemplates.set(
-					CssIcssFromIdentifierDependency,
-					new CssIcssFromIdentifierDependency.Template()
-				);
-				compilation.dependencyFactories.set(
-					CssIcssGlobalIdentifierDependency,
-					normalModuleFactory
-				);
-				compilation.dependencyTemplates.set(
-					CssIcssGlobalIdentifierDependency,
-					new CssIcssGlobalIdentifierDependency.Template()
 				);
 				compilation.dependencyTemplates.set(
 					CssIcssExportDependency,
@@ -293,52 +228,126 @@
 					normalModuleFactory.hooks.createParser
 						.for(type)
 						.tap(PLUGIN_NAME, (parserOptions) => {
-							validateParserOptions[type](parserOptions);
-							const {
-								url,
-								import: importOption,
-								namedExports,
-								exportType
-							} = parserOptions;
+							/** @type {undefined | "global" | "local" | "auto"} */
+							let defaultMode;
 
 							switch (type) {
-								case CSS_MODULE_TYPE:
-									return new CssParser({
-										importOption,
-										url,
-										namedExports,
-										exportType
-									});
-								case CSS_MODULE_TYPE_GLOBAL:
-									return new CssParser({
-										defaultMode: "global",
-										importOption,
-										url,
-										namedExports,
-										exportType
-									});
-								case CSS_MODULE_TYPE_MODULE:
-									return new CssParser({
-										defaultMode: "local",
-										importOption,
-										url,
-										namedExports,
-										exportType
-									});
-								case CSS_MODULE_TYPE_AUTO:
-									return new CssParser({
-										defaultMode: "auto",
-										importOption,
-										url,
-										namedExports,
-										exportType
-									});
+								case CSS_MODULE_TYPE: {
+									compiler.validate(
+										() => getSchema("CssParserOptions"),
+										parserOptions,
+										parserValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssParserOptions.check")(
+												options
+											)
+									);
+
+									break;
+								}
+								case CSS_MODULE_TYPE_GLOBAL: {
+									defaultMode = "global";
+									compiler.validate(
+										() => getSchema("CssModuleParserOptions"),
+										parserOptions,
+										parserValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssModuleParserOptions.check")(
+												options
+											)
+									);
+									break;
+								}
+								case CSS_MODULE_TYPE_MODULE: {
+									defaultMode = "local";
+									compiler.validate(
+										() => getSchema("CssModuleParserOptions"),
+										parserOptions,
+										parserValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssModuleParserOptions.check")(
+												options
+											)
+									);
+									break;
+								}
+								case CSS_MODULE_TYPE_AUTO: {
+									defaultMode = "auto";
+									compiler.validate(
+										() => getSchema("CssModuleParserOptions"),
+										parserOptions,
+										parserValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssModuleParserOptions.check")(
+												options
+											)
+									);
+									break;
+								}
 							}
+
+							return new CssParser({
+								defaultMode,
+								...parserOptions
+							});
 						});
 					normalModuleFactory.hooks.createGenerator
 						.for(type)
 						.tap(PLUGIN_NAME, (generatorOptions) => {
-							validateGeneratorOptions[type](generatorOptions);
+							switch (type) {
+								case CSS_MODULE_TYPE: {
+									compiler.validate(
+										() => getSchema("CssGeneratorOptions"),
+										generatorOptions,
+										generatorValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssGeneratorOptions.check")(
+												options
+											)
+									);
+
+									break;
+								}
+								case CSS_MODULE_TYPE_GLOBAL: {
+									compiler.validate(
+										() => getSchema("CssModuleGeneratorOptions"),
+										generatorOptions,
+										generatorValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssModuleGeneratorOptions.check")(
+												options
+											)
+									);
+
+									break;
+								}
+								case CSS_MODULE_TYPE_MODULE: {
+									compiler.validate(
+										() => getSchema("CssModuleGeneratorOptions"),
+										generatorOptions,
+										generatorValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssModuleGeneratorOptions.check")(
+												options
+											)
+									);
+
+									break;
+								}
+								case CSS_MODULE_TYPE_AUTO: {
+									compiler.validate(
+										() => getSchema("CssModuleGeneratorOptions"),
+										generatorOptions,
+										generatorValidationOptions,
+										(options) =>
+											require("../../schemas/plugins/css/CssModuleGeneratorOptions.check")(
+												options
+											)
+									);
+
+									break;
+								}
+							}
 
 							return new CssGenerator(
 								generatorOptions,
@@ -348,6 +357,9 @@
 					normalModuleFactory.hooks.createModuleClass
 						.for(type)
 						.tap(PLUGIN_NAME, (createData, resolveData) => {
+							const exportType =
+								/** @type {CssParser} */
+								(createData.parser).options.exportType;
 							if (resolveData.dependencies.length > 0) {
 								// When CSS is imported from CSS there is only one dependency
 								const dependency = resolveData.dependencies[0];
@@ -358,7 +370,7 @@
 										(compilation.moduleGraph.getParentModule(dependency));
 
 									if (parent instanceof CssModule) {
-										/** @type {import("../CssModule").Inheritance | undefined} */
+										/** @type {Inheritance | undefined} */
 										let inheritance;
 
 										if (
@@ -392,7 +404,8 @@
 												cssLayer: dependency.layer,
 												supports: dependency.supports,
 												media: dependency.media,
-												inheritance
+												inheritance,
+												exportType: parent.exportType || exportType
 											})
 										);
 									}
@@ -403,7 +416,8 @@
 											...createData,
 											cssLayer: dependency.layer,
 											supports: dependency.supports,
-											media: dependency.media
+											media: dependency.media,
+											exportType
 										})
 									);
 								}
@@ -411,7 +425,12 @@
 
 							return new CssModule(
 								/** @type {CSSModuleCreateData} */
-								(createData)
+								(
+									/** @type {unknown} */ ({
+										...createData,
+										exportType
+									})
+								)
 							);
 						});
 
@@ -433,18 +452,24 @@
 					compilation
 				).renderModuleContent.tap(PLUGIN_NAME, (source, module) => {
 					if (module instanceof CssModule && module.hot) {
+						const exportType = module.exportType;
+						// When exportType !== "link", modules behave like JavaScript modules
+						if (exportType && !["link", "style"].includes(exportType)) {
+							return source;
+						}
+						// For exportType === "link", we can optimize with self-acceptance
 						const cssData = /** @type {BuildInfo} */ (module.buildInfo).cssData;
 						if (!cssData) {
 							return source;
 						}
 						const exports = cssData.exports;
+						/** @type {Record<string, string>} */
+						const exportsObj = {};
+						for (const [key, value] of exports) {
+							exportsObj[key] = value;
+						}
 						const stringifiedExports = JSON.stringify(
-							JSON.stringify(
-								[...exports].reduce((obj, [key, value]) => {
-									obj[key] = value;
-									return obj;
-								}, /** @type {Record<string, string>} */ ({}))
-							)
+							JSON.stringify(exportsObj)
 						);
 
 						const hmrCode = Template.asString([
@@ -456,7 +481,11 @@
 							"} else {",
 							Template.indent("module.hot.accept();"),
 							"}",
-							"module.hot.dispose(function(data) { data.__webpack_css_exports__ = __webpack_css_exports__; });"
+							"module.hot.dispose(function(data) {",
+							Template.indent([
+								"data.__webpack_css_exports__ = __webpack_css_exports__;"
+							]),
+							"});"
 						]);
 
 						return new ConcatSource(source, "\n", new RawSource(hmrCode));
@@ -464,6 +493,7 @@
 
 					return source;
 				});
+				/** @type {WeakMap<Chunk, CssModule[]>} */
 				const orderedCssModulesPerChunk = new WeakMap();
 				compilation.hooks.afterCodeGeneration.tap(PLUGIN_NAME, () => {
 					const { chunkGraph } = compilation;
@@ -562,6 +592,7 @@
 				});
 				const globalChunkLoading = compilation.outputOptions.chunkLoading;
 				/**
+				 * Checks whether this css modules plugin is enabled for chunk.
 				 * @param {Chunk} chunk the chunk
 				 * @returns {boolean} true, when enabled
 				 */
@@ -573,8 +604,10 @@
 							: globalChunkLoading;
 					return chunkLoading === "jsonp" || chunkLoading === "import";
 				};
+				/** @type {WeakSet<Chunk>} */
 				const onceForChunkSet = new WeakSet();
 				/**
+				 * Handles the hook callback for this code path.
 				 * @param {Chunk} chunk chunk to check
 				 * @param {RuntimeRequirements} set runtime requirements
 				 */
@@ -633,9 +666,22 @@
 				compilation.hooks.runtimeRequirementInTree
 					.for(RuntimeGlobals.cssMergeStyleSheets)
 					.tap(PLUGIN_NAME, (chunk) => {
+						const CssMergeStyleSheetsRuntimeModule =
+							getCssMergeStyleSheetsRuntimeModule();
 						compilation.addRuntimeModule(
 							chunk,
 							new CssMergeStyleSheetsRuntimeModule()
+						);
+					});
+
+				compilation.hooks.runtimeRequirementInTree
+					.for(RuntimeGlobals.cssInjectStyle)
+					.tap(PLUGIN_NAME, (chunk, set) => {
+						const CssInjectStyleRuntimeModule =
+							getCssInjectStyleRuntimeModule();
+						compilation.addRuntimeModule(
+							chunk,
+							new CssInjectStyleRuntimeModule(set)
 						);
 					});
 			}
@@ -643,8 +689,9 @@
 	}
 
 	/**
+	 * Gets modules in order.
 	 * @param {Chunk} chunk chunk
-	 * @param {Iterable<Module>} modules unordered modules
+	 * @param {Iterable<Module> | undefined} modules unordered modules
 	 * @param {Compilation} compilation compilation
 	 * @returns {Module[]} ordered modules
 	 */
@@ -679,11 +726,12 @@
 			return modulesByChunkGroup[0].list.reverse();
 		}
 
-		const boundCompareModulesByIdOrIdentifier = compareModulesByIdOrIdentifier(
-			compilation.chunkGraph
+		const boundCompareModulesByFullName = compareModulesByFullName(
+			compilation.compiler
 		);
 
 		/**
+		 * Compares module lists.
 		 * @param {{ list: Module[] }} a a
 		 * @param {{ list: Module[] }} b b
 		 * @returns {-1 | 0 | 1} result
@@ -693,10 +741,7 @@
 				return b.length === 0 ? 0 : 1;
 			}
 			if (b.length === 0) return -1;
-			return boundCompareModulesByIdOrIdentifier(
-				a[a.length - 1],
-				b[b.length - 1]
-			);
+			return boundCompareModulesByFullName(a[a.length - 1], b[b.length - 1]);
 		};
 
 		modulesByChunkGroup.sort(compareModuleLists);
@@ -705,6 +750,7 @@
 		const finalModules = [];
 
 		for (;;) {
+			/** @type {Set<Module>} */
 			const failedModules = new Set();
 			const list = modulesByChunkGroup[0].list;
 			if (list.length === 0) {
@@ -713,6 +759,7 @@
 			}
 			/** @type {Module} */
 			let selectedModule = list[list.length - 1];
+			/** @type {undefined | false | Module} */
 			let hasFailed;
 			outer: for (;;) {
 				for (const { list, set } of modulesByChunkGroup) {
@@ -733,19 +780,43 @@
 				break;
 			}
 			if (hasFailed) {
+				const fallbackModule = /** @type {Module} */ (hasFailed);
+
+				const fallbackIssuers = [
+					...compilation.moduleGraph
+						.getIncomingConnectionsByOriginModule(fallbackModule)
+						.keys()
+				].filter(Boolean);
+
+				const selectedIssuers = [
+					...compilation.moduleGraph
+						.getIncomingConnectionsByOriginModule(selectedModule)
+						.keys()
+				].filter(Boolean);
+
+				const allIssuers = [
+					...new Set([...fallbackIssuers, ...selectedIssuers])
+				]
+					.map((m) =>
+						/** @type {Module} */ (m).readableIdentifier(
+							compilation.requestShortener
+						)
+					)
+					.sort();
+
 				// 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(
+						`chunk ${
+							chunk.name || chunk.id
+						}\nConflicting order between ${fallbackModule.readableIdentifier(
 							compilation.requestShortener
-						)}`
+						)} and ${selectedModule.readableIdentifier(
+							compilation.requestShortener
+						)}\nCSS modules are imported in:\n  - ${allIssuers.join("\n  - ")}`
 					)
 				);
-				selectedModule = /** @type {Module} */ (hasFailed);
+				selectedModule = fallbackModule;
 			}
 			// Insert the selected module into the final modules list
 			finalModules.push(selectedModule);
@@ -765,41 +836,70 @@
 	}
 
 	/**
+	 * Gets ordered chunk css modules.
 	 * @param {Chunk} chunk chunk
 	 * @param {ChunkGraph} chunkGraph chunk graph
 	 * @param {Compilation} compilation compilation
-	 * @returns {Module[]} ordered css modules
+	 * @returns {CssModule[]} ordered css modules
 	 */
 	getOrderedChunkCssModules(chunk, chunkGraph, compilation) {
-		return [
+		/** @type {string | undefined} */
+		let charset;
+
+		return /** @type {CssModule[]} */ ([
 			...this.getModulesInOrder(
 				chunk,
-				/** @type {Iterable<Module>} */
-				(
-					chunkGraph.getOrderedChunkModulesIterableBySourceType(
-						chunk,
-						"css-import",
-						compareModulesByIdOrIdentifier(chunkGraph)
-					)
+				chunkGraph.getOrderedChunkModulesIterableBySourceType(
+					chunk,
+					CSS_IMPORT_TYPE,
+					compareModulesByFullName(compilation.compiler)
 				),
 				compilation
 			),
 			...this.getModulesInOrder(
 				chunk,
-				/** @type {Iterable<Module>} */
-				(
-					chunkGraph.getOrderedChunkModulesIterableBySourceType(
-						chunk,
-						"css",
-						compareModulesByIdOrIdentifier(chunkGraph)
-					)
+				chunkGraph.getOrderedChunkModulesIterableBySourceType(
+					chunk,
+					CSS_TYPE,
+					compareModulesByFullName(compilation.compiler)
 				),
 				compilation
-			)
-		];
+			).map((module) => {
+				if (
+					typeof (/** @type {BuildInfo} */ (module.buildInfo).charset) !==
+					"undefined"
+				) {
+					if (
+						typeof charset !== "undefined" &&
+						charset !== /** @type {BuildInfo} */ (module.buildInfo).charset
+					) {
+						const err = new WebpackError(
+							`Conflicting @charset at-rules detected: the module ${module.readableIdentifier(
+								compilation.requestShortener
+							)} (in chunk ${chunk.name || chunk.id}) specifies "${
+								/** @type {BuildInfo} */ (module.buildInfo).charset
+							}", but "${charset}" was expected, all modules must use the same character set`
+						);
+
+						err.chunk = chunk;
+						err.module = module;
+						err.hideStack = true;
+
+						compilation.warnings.push(err);
+					}
+
+					if (typeof charset === "undefined") {
+						charset = /** @type {BuildInfo} */ (module.buildInfo).charset;
+					}
+				}
+
+				return module;
+			})
+		]);
 	}
 
 	/**
+	 * Renders css module source.
 	 * @param {CssModule} module css module
 	 * @param {ChunkRenderContext} renderContext options object
 	 * @param {CompilationHooks} hooks hooks
@@ -815,10 +915,12 @@
 			inheritance.push(...module.inheritance);
 		}
 
+		/** @type {CachedSource} */
 		let source;
 		if (
 			cacheEntry &&
 			cacheEntry.undoPath === undoPath &&
+			cacheEntry.inheritance.length === inheritance.length &&
 			cacheEntry.inheritance.every(([layer, supports, media], i) => {
 				const item = inheritance[i];
 				if (Array.isArray(item)) {
@@ -833,17 +935,15 @@
 			const moduleSourceCode =
 				/** @type {string} */
 				(moduleSourceContent.source());
-			const publicPathAutoRegex = new RegExp(
-				CssUrlDependency.PUBLIC_PATH_AUTO,
-				"g"
-			);
+			publicPathAutoRegex.lastIndex = 0;
 			/** @type {Source} */
 			let moduleSource = new ReplaceSource(moduleSourceContent);
+			/** @type {null | RegExpExecArray} */
 			let match;
 			while ((match = publicPathAutoRegex.exec(moduleSourceCode))) {
 				/** @type {ReplaceSource} */ (moduleSource).replace(
 					match.index,
-					(match.index += match[0].length - 1),
+					match.index + match[0].length - 1,
 					undoPath
 				);
 			}
@@ -898,6 +998,7 @@
 	}
 
 	/**
+	 * Renders generated source.
 	 * @param {RenderContext} renderContext the render context
 	 * @param {CompilationHooks} hooks hooks
 	 * @returns {Source} generated source
@@ -914,14 +1015,26 @@
 		hooks
 	) {
 		const source = new ConcatSource();
+
+		/** @type {string | undefined} */
+		let charset;
+
 		for (const module of modules) {
+			if (
+				typeof (/** @type {BuildInfo} */ (module.buildInfo).charset) !==
+					"undefined" &&
+				typeof charset === "undefined"
+			) {
+				charset = /** @type {BuildInfo} */ (module.buildInfo).charset;
+			}
+
 			try {
 				const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
 				const moduleSourceContent =
 					/** @type {Source} */
 					(
-						codeGenResult.sources.get("css") ||
-							codeGenResult.sources.get("css-import")
+						codeGenResult.sources.get(CSS_TYPE) ||
+							codeGenResult.sources.get(CSS_IMPORT_TYPE)
 					);
 				const moduleSource = CssModulesPlugin.renderModule(
 					module,
@@ -945,11 +1058,18 @@
 				throw err;
 			}
 		}
+
 		chunk.rendered = true;
+
+		if (charset) {
+			return new ConcatSource(`@charset "${charset}";\n`, source);
+		}
+
 		return source;
 	}
 
 	/**
+	 * Gets chunk filename template.
 	 * @param {Chunk} chunk chunk
 	 * @param {OutputOptions} outputOptions output options
 	 * @returns {TemplatePath} used filename template
@@ -964,15 +1084,18 @@
 	}
 
 	/**
+	 * Returns true, when the chunk has css.
 	 * @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")
+				chunkGraph.getChunkModulesIterableBySourceType(chunk, CSS_TYPE)
+			) ||
+			Boolean(
+				chunkGraph.getChunkModulesIterableBySourceType(chunk, CSS_IMPORT_TYPE)
 			)
 		);
 	}

--
Gitblit v1.9.3