mirror of
https://github.com/swc-project/swc.git
synced 2024-12-24 14:16:12 +03:00
fix(css/modules): Allow out-of-order class names for composes
(#8218)
**Related issue:** - Closes #7910
This commit is contained in:
parent
cb29fdd1f4
commit
aeb9cafd11
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -3250,9 +3250,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.188"
|
||||
version = "1.0.190"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
|
||||
checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@ -3280,9 +3280,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.188"
|
||||
version = "1.0.190"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
||||
checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -5451,6 +5451,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"pretty_assertions",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"swc_common",
|
||||
"swc_error_reporters",
|
||||
|
@ -307,13 +307,23 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
for class_name in n.value.iter() {
|
||||
for class_name in n.value.iter_mut() {
|
||||
if let ComponentValue::Ident(box Ident { span, value, .. }) = class_name {
|
||||
if let Some(value) = self.data.orig_to_renamed.get(value) {
|
||||
let orig = value.clone();
|
||||
rename(
|
||||
*span,
|
||||
&mut self.config,
|
||||
&mut self.result,
|
||||
&mut self.data.orig_to_renamed,
|
||||
&mut self.data.renamed_to_orig,
|
||||
value,
|
||||
);
|
||||
|
||||
if let Some(new_name) = self.data.orig_to_renamed.get(&orig) {
|
||||
composes_for_current.push(CssClassName::Local {
|
||||
name: Ident {
|
||||
span: *span,
|
||||
value: value.clone(),
|
||||
value: new_name.clone(),
|
||||
raw: None,
|
||||
},
|
||||
});
|
||||
|
@ -32,13 +32,13 @@ fn imports(input: PathBuf) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let s = serde_json::to_string_pretty(&result).unwrap();
|
||||
NormalizedOutput::from(s)
|
||||
.compare_to_file(input.with_file_name(format!(
|
||||
NormalizedOutput::compare_json_to_file(
|
||||
&result,
|
||||
&input.with_file_name(format!(
|
||||
"{}.imports.json",
|
||||
input.file_stem().unwrap().to_string_lossy()
|
||||
)))
|
||||
.unwrap();
|
||||
)),
|
||||
);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
@ -89,41 +89,39 @@ fn compile(input: PathBuf) {
|
||||
.unwrap();
|
||||
|
||||
if !transform_result.renamed.is_empty() {
|
||||
let transformed_classes = serde_json::to_string_pretty(
|
||||
&transform_result
|
||||
.renamed
|
||||
.into_iter()
|
||||
.map(|(k, v)| {
|
||||
(
|
||||
k,
|
||||
v.into_iter()
|
||||
.map(|v| match v {
|
||||
CssClassName::Global { name } => {
|
||||
CssClassNameForTest::Global { name: name.value }
|
||||
let transformed_classes = &transform_result
|
||||
.renamed
|
||||
.into_iter()
|
||||
.map(|(k, v)| {
|
||||
(
|
||||
k,
|
||||
v.into_iter()
|
||||
.map(|v| match v {
|
||||
CssClassName::Global { name } => {
|
||||
CssClassNameForTest::Global { name: name.value }
|
||||
}
|
||||
CssClassName::Local { name } => {
|
||||
CssClassNameForTest::Local { name: name.value }
|
||||
}
|
||||
CssClassName::Import { name, from } => {
|
||||
CssClassNameForTest::Import {
|
||||
name: name.value,
|
||||
from,
|
||||
}
|
||||
CssClassName::Local { name } => {
|
||||
CssClassNameForTest::Local { name: name.value }
|
||||
}
|
||||
CssClassName::Import { name, from } => {
|
||||
CssClassNameForTest::Import {
|
||||
name: name.value,
|
||||
from,
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.collect::<FxHashMap<_, _>>(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.collect::<FxHashMap<_, _>>();
|
||||
|
||||
NormalizedOutput::from(transformed_classes)
|
||||
.compare_to_file(input.with_file_name(format!(
|
||||
NormalizedOutput::compare_json_to_file(
|
||||
&transformed_classes,
|
||||
&input.with_file_name(format!(
|
||||
"{}.transform.json",
|
||||
input.file_stem().unwrap().to_string_lossy()
|
||||
)))
|
||||
.unwrap();
|
||||
)),
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
|
@ -0,0 +1,7 @@
|
||||
.__local__child-class1 {
|
||||
color: red;
|
||||
}
|
||||
.__local__root-class {}
|
||||
.__local__child-class2 {
|
||||
color: green;
|
||||
}
|
10
crates/swc_css_modules/tests/fixture/issue-7910.css
Normal file
10
crates/swc_css_modules/tests/fixture/issue-7910.css
Normal file
@ -0,0 +1,10 @@
|
||||
.child-class1 {
|
||||
color: red;
|
||||
}
|
||||
.root-class {
|
||||
composes: child-class1;
|
||||
composes: child-class2;
|
||||
}
|
||||
.child-class2 {
|
||||
color: green;
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
{
|
||||
"child-class1": [
|
||||
{
|
||||
"type": "local",
|
||||
"name": "__local__child-class1"
|
||||
}
|
||||
],
|
||||
"root-class": [
|
||||
{
|
||||
"type": "local",
|
||||
"name": "__local__root-class"
|
||||
},
|
||||
{
|
||||
"type": "local",
|
||||
"name": "__local__child-class1"
|
||||
},
|
||||
{
|
||||
"type": "local",
|
||||
"name": "__local__child-class2"
|
||||
}
|
||||
],
|
||||
"child-class2": [
|
||||
{
|
||||
"type": "local",
|
||||
"name": "__local__child-class2"
|
||||
}
|
||||
]
|
||||
}
|
@ -18,7 +18,8 @@ difference = "2"
|
||||
once_cell = "1.18.0"
|
||||
pretty_assertions = "1.3"
|
||||
regex = "1"
|
||||
serde_json = "1.0.71"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
tracing = "0.1.37"
|
||||
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
use std::{
|
||||
env, fmt,
|
||||
fs::{create_dir_all, File},
|
||||
fs::{self, create_dir_all, File},
|
||||
io::Read,
|
||||
ops::Deref,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use serde::Serialize;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::paths;
|
||||
@ -102,6 +103,28 @@ impl NormalizedOutput {
|
||||
NormalizedOutput(normalize_input(s, true))
|
||||
}
|
||||
|
||||
pub fn compare_json_to_file<T>(actual: &T, path: &Path)
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
let actual_value =
|
||||
serde_json::to_value(actual).expect("failed to serialize the actual value to json");
|
||||
|
||||
if let Ok(expected) = fs::read_to_string(path) {
|
||||
let expected_value = serde_json::from_str::<serde_json::Value>(&expected)
|
||||
.expect("failed to deserialize the expected value from json");
|
||||
|
||||
if expected_value == actual_value {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let actual_json_string = serde_json::to_string_pretty(&actual_value)
|
||||
.expect("failed to serialize the actual value to json");
|
||||
|
||||
let _ = NormalizedOutput::from(actual_json_string).compare_to_file(path);
|
||||
}
|
||||
|
||||
/// If output differs, prints actual stdout/stderr to
|
||||
/// `CARGO_MANIFEST_DIR/target/swc-test-results/ui/$rel_path` where
|
||||
/// `$rel_path`: `path.strip_prefix(CARGO_MANIFEST_DIR)`
|
||||
|
Loading…
Reference in New Issue
Block a user