mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
turbopack-css: demote recoverable CSS parse warnings to Warning severity (#91524)
### What? Extends the CSS parse warning severity improvements in `turbopack/crates/turbopack-css/src/process.rs`. Canary (#90025, #91513) already: - Added a `severity` field to `ParsingIssue` and a `fn severity()` override - Demoted `UnsupportedPseudoClass` / `UnsupportedPseudoElement` selector errors from `Error` to `Warning` - Still **silently dropped** all other unrecognized parser warning kinds (`_ => { // Ignore }`) This PR completes the work: 1. **Surfaces all previously-ignored parser warnings as `IssueSeverity::Warning`** — the `_ => { // Ignore }` arm now emits a `ParsingIssue` at `Warning` severity instead of discarding it. 2. **Refactors the warning loop** — the nested severity match inside the existing `match err.kind` arm is replaced with a single top-level `let severity = match err.kind { … }` followed by an unconditional emit. This is cleaner and makes the severity logic easier to follow. Hard parse/transform errors (`Err(e)` from `parse_css_stylesheet`, minify errors, CSS module pure-selector errors) are unchanged — they remain `IssueSeverity::Error`. ### Why? Silently dropping parser warnings hides useful diagnostic information from developers. Surfacing them as `Warning` gives visibility without marking the build as broken. The restructure also avoids a redundant `UnsupportedPseudoClass`/`UnsupportedPseudoElement` check inside a nested match — the top-level arm order (specific pseudo variants before the catch-all `SelectorError(..)`) handles precedence correctly. ### How? - Removed the now-unused `error::SelectorError` short import (fully-qualified paths are used in the match). - Replaced the `match err.kind { <arms that emit> … _ => { // Ignore } }` pattern with: 1. `let severity = match err.kind { UnsupportedPseudo* => Warning, hard errors => Error, _ => Warning };` 2. Unconditional `IssueSource` construction and `ParsingIssue { severity, … }.emit()`. Co-authored-by: Tobias Koppers <[email protected]> Co-authored-by: Claude <[email protected]>
This commit is contained in:
co-authored by
Tobias Koppers
Claude
parent
0f089d5f9b
commit
046e0c4a00
@@ -3,7 +3,6 @@ use std::sync::{Arc, RwLock};
|
||||
use anyhow::{Result, bail};
|
||||
use lightningcss::{
|
||||
css_modules::{CssModuleExport, Pattern, Segment},
|
||||
error::SelectorError,
|
||||
stylesheet::{MinifyOptions, ParserOptions, PrinterOptions, StyleSheet, ToCssResult},
|
||||
targets::{BrowserslistConfig, Features, Targets},
|
||||
traits::ToCss,
|
||||
@@ -489,49 +488,44 @@ async fn process_content(
|
||||
) {
|
||||
Ok(mut ss) => {
|
||||
for err in warnings.read().unwrap().iter() {
|
||||
match err.kind {
|
||||
// Unsupported pseudo-classes/elements are common in real-world CSS
|
||||
// (vendor prefixes, custom frameworks) and do not prevent the
|
||||
// stylesheet from being used — treat them as recoverable warnings.
|
||||
// All other previously-ignored parser warnings are also surfaced.
|
||||
let severity = match err.kind {
|
||||
lightningcss::error::ParserError::SelectorError(
|
||||
lightningcss::error::SelectorError::UnsupportedPseudoClass(_)
|
||||
| lightningcss::error::SelectorError::UnsupportedPseudoElement(_),
|
||||
) => IssueSeverity::Warning,
|
||||
|
||||
lightningcss::error::ParserError::UnexpectedToken(_)
|
||||
| lightningcss::error::ParserError::UnexpectedImportRule
|
||||
| lightningcss::error::ParserError::SelectorError(..)
|
||||
| lightningcss::error::ParserError::EndOfInput => {
|
||||
let issue_source = match &err.loc {
|
||||
Some(loc) => IssueSource::from_single_line_col(
|
||||
source,
|
||||
SourcePos {
|
||||
// lightningcss::ErrorLocation is 1-based for column only
|
||||
line: loc.line,
|
||||
column: loc.column - 1,
|
||||
},
|
||||
),
|
||||
None => IssueSource::from_source_only(source),
|
||||
};
|
||||
| lightningcss::error::ParserError::EndOfInput => IssueSeverity::Error,
|
||||
|
||||
let severity = match &err.kind {
|
||||
lightningcss::error::ParserError::SelectorError(
|
||||
SelectorError::UnsupportedPseudoClass(_)
|
||||
| SelectorError::UnsupportedPseudoElement(_),
|
||||
) => {
|
||||
// In most cases, these are new selectors not yet
|
||||
// implemented in LightningCSS.
|
||||
IssueSeverity::Warning
|
||||
}
|
||||
_ => IssueSeverity::Error,
|
||||
};
|
||||
_ => IssueSeverity::Warning,
|
||||
};
|
||||
|
||||
ParsingIssue {
|
||||
msg: err.kind.to_string().into(),
|
||||
stage: IssueStage::Parse,
|
||||
source: issue_source,
|
||||
severity,
|
||||
}
|
||||
.resolved_cell()
|
||||
.emit();
|
||||
}
|
||||
let issue_source = match &err.loc {
|
||||
Some(loc) => IssueSource::from_single_line_col(
|
||||
source,
|
||||
SourcePos {
|
||||
// lightningcss::ErrorLocation is 1-based for column only
|
||||
line: loc.line,
|
||||
column: loc.column - 1,
|
||||
},
|
||||
),
|
||||
None => IssueSource::from_source_only(source),
|
||||
};
|
||||
|
||||
_ => {
|
||||
// Ignore
|
||||
}
|
||||
ParsingIssue {
|
||||
severity,
|
||||
msg: err.kind.to_string().into(),
|
||||
stage: IssueStage::Parse,
|
||||
source: issue_source,
|
||||
}
|
||||
.resolved_cell()
|
||||
.emit();
|
||||
}
|
||||
|
||||
let targets = *get_lightningcss_browser_targets(
|
||||
@@ -561,10 +555,10 @@ async fn process_content(
|
||||
None => IssueSource::from_source_only(source),
|
||||
};
|
||||
ParsingIssue {
|
||||
severity: IssueSeverity::Error,
|
||||
msg: e.kind.to_string().into(),
|
||||
stage: IssueStage::Transform,
|
||||
source: issue_source,
|
||||
severity: IssueSeverity::Error,
|
||||
}
|
||||
.resolved_cell()
|
||||
.emit();
|
||||
@@ -601,10 +595,10 @@ async fn process_content(
|
||||
None => IssueSource::from_source_only(source),
|
||||
};
|
||||
ParsingIssue {
|
||||
severity: IssueSeverity::Error,
|
||||
msg: e.kind.to_string().into(),
|
||||
stage: IssueStage::Parse,
|
||||
source: issue_source,
|
||||
severity: IssueSeverity::Error,
|
||||
}
|
||||
.resolved_cell()
|
||||
.emit();
|
||||
@@ -651,6 +645,7 @@ impl CssError {
|
||||
match self {
|
||||
CssError::CssSelectorInModuleNotPure { selector } => {
|
||||
ParsingIssue {
|
||||
severity: IssueSeverity::Error,
|
||||
msg: format!(
|
||||
"Selector \"{selector}\" is not pure. Pure selectors must contain at \
|
||||
least one local class or id."
|
||||
@@ -659,7 +654,6 @@ impl CssError {
|
||||
stage: IssueStage::Transform,
|
||||
// TODO: This should include the location of the selector in the file.
|
||||
source: IssueSource::from_source_only(source),
|
||||
severity: IssueSeverity::Error,
|
||||
}
|
||||
.resolved_cell()
|
||||
.emit();
|
||||
@@ -756,10 +750,10 @@ fn generate_css_source_map(source_map: &parcel_sourcemap::SourceMap) -> Result<R
|
||||
|
||||
#[turbo_tasks::value]
|
||||
struct ParsingIssue {
|
||||
severity: IssueSeverity,
|
||||
msg: RcStr,
|
||||
stage: IssueStage,
|
||||
source: IssueSource,
|
||||
severity: IssueSeverity,
|
||||
}
|
||||
|
||||
#[turbo_tasks::value_impl]
|
||||
|
||||
Reference in New Issue
Block a user