Show Lightning CSS warnings when optimizing/minifying in production (#18918)
This PR improves the DX by showing all the Lightning CSS warnings when using a "production" build (or using `--optimize` or `--minify` flags when using the CLI). Right now Tailwind CSS itself doesn't care about the exact syntax you are using in the CSS as long as it looks valid. We do this because otherwise we would have to parse a lot more CSS syntax and validate it even though it would be valid CSS in 99.99% of the cases. Even worse, if you want to use newer CSS syntax that Tailwind CSS doesn't validate yet, then you would get warnings for valid CSS. Another reason why we don't do this is because the browser already does a great job at ignoring invalid CSS. So the linked issue #15872 would still silently fail in development mode. In this case, everything would work, except the shadow with the invalid syntax. But in production mode, you would now get a proper warning from Lightning CSS, because they try to optimize the CSS and remove invalid CSS. One potential issue here is that we run Lightning CSS on the generated CSS, not on the input CSS. So the current output shows the warnings in the output CSS not the input CSS. Any thoughts if we would just skip the line numbers? ## Test plan 1. Everything works as before 2. In production mode, you would get warnings printed to the terminal. This is done in `@tailwindcss/node` so the CLI/Vite/PostCSS plugins would all get the same behavior. Screenshots: If you have a single issue: <img width="977" height="441" alt="image" src="https://github.com/user-attachments/assets/7b061ee9-b74f-4b40-aa05-cff67a21dfcc" /> If you have multiple issues: <img width="2170" height="711" alt="image" src="https://github.com/user-attachments/assets/a5bc9b0a-964b-465f-80f3-d30dd467e69c" /> Fixes: #15872
This commit is contained in:
parent
65bad11380
commit
d0a1bd655b
3 changed files with 63 additions and 0 deletions
|
|
@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Do not generate `grid-row` utilities when configuring `grid-row-start` or `grid-row-end` ([#18907](https://github.com/tailwindlabs/tailwindcss/pull/18907))
|
||||
- Prevent duplicate CSS when overwriting a static utility with a theme key ([#18056](https://github.com/tailwindlabs/tailwindcss/pull/18056))
|
||||
- Do not migrate `variant = 'outline'` during upgrades ([#18922](https://github.com/tailwindlabs/tailwindcss/pull/18922))
|
||||
- Show Lightning CSS warnings (if any) when optimizing/minifying ([#18918](https://github.com/tailwindlabs/tailwindcss/pull/18918))
|
||||
|
||||
## [4.1.13] - 2025-09-03
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,48 @@ export function optimize(
|
|||
let result = optimize(Buffer.from(input), map)
|
||||
map = result.map?.toString()
|
||||
|
||||
// Because of `errorRecovery: true`, there could be warnings, so let's let the
|
||||
// user know about them.
|
||||
if (process.env.NODE_ENV !== 'test' && result.warnings.length > 0) {
|
||||
let lines = input.split('\n')
|
||||
|
||||
let output = [
|
||||
`Found ${result.warnings.length} ${result.warnings.length === 1 ? 'warning' : 'warnings'} while optimizing generated CSS:`,
|
||||
]
|
||||
|
||||
for (let [idx, warning] of result.warnings.entries()) {
|
||||
output.push('')
|
||||
if (result.warnings.length > 1) {
|
||||
output.push(`Issue #${idx + 1}:`)
|
||||
}
|
||||
|
||||
let context = 2
|
||||
|
||||
let start = Math.max(0, warning.loc.line - context - 1)
|
||||
let end = Math.min(lines.length, warning.loc.line + context)
|
||||
|
||||
let snippet = lines.slice(start, end).map((line, idx) => {
|
||||
if (start + idx + 1 === warning.loc.line) {
|
||||
return `${dim(`\u2502`)} ${line}`
|
||||
} else {
|
||||
return dim(`\u2502 ${line}`)
|
||||
}
|
||||
})
|
||||
|
||||
snippet.splice(
|
||||
warning.loc.line - start,
|
||||
0,
|
||||
`${dim('\u2506')}${' '.repeat(warning.loc.column - 1)} ${yellow(`${dim('^--')} ${warning.message}`)}`,
|
||||
`${dim('\u2506')}`,
|
||||
)
|
||||
|
||||
output.push(...snippet)
|
||||
}
|
||||
output.push('')
|
||||
|
||||
console.warn(output.join('\n'))
|
||||
}
|
||||
|
||||
result = optimize(result.code, map)
|
||||
map = result.map?.toString()
|
||||
|
||||
|
|
@ -88,3 +130,11 @@ export function optimize(
|
|||
map,
|
||||
}
|
||||
}
|
||||
|
||||
function dim(str: string) {
|
||||
return `\x1B[2m${str}\x1B[22m`
|
||||
}
|
||||
|
||||
function yellow(str: string) {
|
||||
return `\x1B[33m${str}\x1B[39m`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,23 +6,35 @@ export default defineConfig([
|
|||
minify: true,
|
||||
dts: true,
|
||||
entry: ['src/index.cts'],
|
||||
define: {
|
||||
'process.env.NODE_ENV': '"production"',
|
||||
},
|
||||
},
|
||||
{
|
||||
format: ['esm'],
|
||||
minify: true,
|
||||
dts: true,
|
||||
entry: ['src/index.ts'],
|
||||
define: {
|
||||
'process.env.NODE_ENV': '"production"',
|
||||
},
|
||||
},
|
||||
{
|
||||
format: ['esm'],
|
||||
minify: true,
|
||||
dts: true,
|
||||
entry: ['src/esm-cache.loader.mts'],
|
||||
define: {
|
||||
'process.env.NODE_ENV': '"production"',
|
||||
},
|
||||
},
|
||||
{
|
||||
format: ['cjs'],
|
||||
minify: true,
|
||||
dts: true,
|
||||
entry: ['src/require-cache.cts'],
|
||||
define: {
|
||||
'process.env.NODE_ENV': '"production"',
|
||||
},
|
||||
},
|
||||
])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue