From fc4d5e36b2d72a8032cee6c46b57049ee1e2e165 Mon Sep 17 00:00:00 2001 From: pierreeurope Date: Fri, 13 Feb 2026 13:28:50 +0100 Subject: [PATCH] fix: include file names in CSS minification warnings When CSS minification (via esbuild or lightningcss) produces warnings or errors, they now show the actual filename instead of generic names like '' or 'style.css', making it much easier to debug which CSS file has the issue. This change: - Adds an optional 'filename' parameter to minifyCSS() function - Passes it to esbuild's 'sourcefile' option - Passes it to lightningcss's 'filename' option (replacing the TODO) - Updates finalizeCss() to accept and forward the filename parameter - Updates all call sites to pass the actual filename when available For single-file CSS (e.g., ?inline imports), the actual file path is used. For aggregated CSS chunks, the chunk name or CSS asset name is used to provide context. Fixes #15915 Signed-off-by: pierreeurope --- packages/vite/src/node/plugins/css.ts | 32 ++++++++++++++++++--------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index b504c1c697c8c5..eb1a97cd5f8978 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -618,7 +618,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { } else if (inlined) { let content = css if (config.build.cssMinify) { - content = await minifyCSS(content, config, true) + content = await minifyCSS(content, config, true, id) } code = `export default ${JSON.stringify(content)}` } else { @@ -812,7 +812,11 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { await urlEmitQueue.run(async () => Promise.all( urlEmitTasks.map(async (info) => { - info.content = await finalizeCss(info.content, config) + info.content = await finalizeCss( + info.content, + config, + info.originalFileName, + ) }), ), ) @@ -897,7 +901,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { // wait for previous tasks as well chunkCSS = await codeSplitEmitQueue.run(async () => { - return finalizeCss(chunkCSS!, config) + return finalizeCss(chunkCSS!, config, cssAssetName) }) // emit corresponding css file @@ -924,7 +928,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { // But because entry chunk can be imported by dynamic import, // we shouldn't remove the inlined CSS. (#10285) - chunkCSS = await finalizeCss(chunkCSS, config) + chunkCSS = await finalizeCss(chunkCSS, config, chunk.fileName) let cssString = JSON.stringify(chunkCSS) cssString = renderAssetUrlInJS( @@ -1032,7 +1036,11 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { // Finally, if there's any extracted CSS, we emit the asset if (extractedCss) { hasEmitted = true - extractedCss = await finalizeCss(extractedCss, config) + extractedCss = await finalizeCss( + extractedCss, + config, + getCssBundleName(), + ) this.emitFile({ name: getCssBundleName(), type: 'asset', @@ -1897,13 +1905,17 @@ function combineSourcemapsIfExists( const viteHashUpdateMarker = '/*$vite$:1*/' const viteHashUpdateMarkerRE = /\/\*\$vite\$:\d+\*\// -async function finalizeCss(css: string, config: ResolvedConfig) { +async function finalizeCss( + css: string, + config: ResolvedConfig, + filename?: string, +) { // hoist external @imports and @charset to the top of the CSS chunk per spec (#1845 and #6333) if (css.includes('@import') || css.includes('@charset')) { css = await hoistAtRules(css) } if (config.build.cssMinify) { - css = await minifyCSS(css, config, false) + css = await minifyCSS(css, config, false, filename) } // inject an additional string to generate a different hash for https://github.com/vitejs/vite/issues/18038 // @@ -2198,6 +2210,7 @@ async function minifyCSS( css: string, config: ResolvedConfig, inlined: boolean, + filename?: string, ) { // We want inlined CSS to not end with a linebreak, while ensuring that // regular CSS assets do end with a linebreak. @@ -2209,6 +2222,7 @@ async function minifyCSS( const { code, warnings } = await transform(css, { loader: 'css', target: config.build.cssTarget || undefined, + sourcefile: filename, ...resolveMinifyCssEsbuildOptions(config.esbuild || {}), }) if (warnings.length) { @@ -2235,9 +2249,7 @@ async function minifyCSS( ...config.css.lightningcss, targets: convertTargets(config.build.cssTarget), cssModules: undefined, - // TODO: Pass actual filename here, which can also be passed to esbuild's - // `sourcefile` option below to improve error messages - filename: defaultCssBundleName, + filename: filename || defaultCssBundleName, code: Buffer.from(css), minify: true, })