Skip to content

Commit

Permalink
feat(css/modules): Preserve spans of CSS class names (#7185)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdy1 authored Apr 1, 2023
1 parent b7366fd commit df7b4e7
Show file tree
Hide file tree
Showing 12 changed files with 138 additions and 75 deletions.
2 changes: 1 addition & 1 deletion crates/swc_css_ast/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span};
use crate::Function;

#[ast_node("Ident")]
#[derive(Eq, Hash)]
#[derive(Eq, PartialOrd, Ord, Hash)]
pub struct Ident {
pub span: Span,
#[cfg_attr(feature = "rkyv", with(swc_atoms::EncodeJsWord))]
Expand Down
56 changes: 36 additions & 20 deletions crates/swc_css_modules/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#![feature(box_patterns)]

use rustc_hash::FxHashMap;
use serde::Serialize;
use swc_atoms::{js_word, JsWord};
use swc_common::util::take::Take;
use swc_common::{util::take::Take, Span};
use swc_css_ast::{
ComplexSelector, ComplexSelectorChildren, ComponentValue, Declaration, DeclarationName,
Delimiter, DelimiterValue, FunctionName, Ident, KeyframesName, PseudoClassSelectorChildren,
Expand All @@ -28,19 +27,18 @@ pub trait TransformConfig {
// ComponentValue;
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
#[serde(tag = "type", rename_all = "camelCase")]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum CssClassName {
Local {
/// Tranformed css class name
name: JsWord,
name: Ident,
},
Global {
name: JsWord,
name: Ident,
},
Import {
/// The exported class name. This is the value specified by the user.
name: JsWord,
name: Ident,
/// The module specifier.
from: JsWord,
},
Expand Down Expand Up @@ -100,6 +98,7 @@ where
n.raw = None;

rename(
n.span,
&mut self.config,
&mut self.result,
&mut self.data.orig_to_renamed,
Expand All @@ -111,6 +110,7 @@ where
n.raw = None;

rename(
n.span,
&mut self.config,
&mut self.result,
&mut self.data.orig_to_renamed,
Expand Down Expand Up @@ -265,11 +265,9 @@ where
ComponentValue::Str(import_source),
) => {
for class_name in n.value.iter().take(n.value.len() - 2) {
if let ComponentValue::Ident(box Ident { value, .. }) =
class_name
{
if let ComponentValue::Ident(value) = class_name {
composes_for_current.push(CssClassName::Import {
name: value.clone(),
name: *value.clone(),
from: import_source.value.clone(),
});
}
Expand All @@ -288,11 +286,9 @@ where
}),
) => {
for class_name in n.value.iter().take(n.value.len() - 2) {
if let ComponentValue::Ident(box Ident { value, .. }) =
class_name
{
if let ComponentValue::Ident(value) = class_name {
composes_for_current.push(CssClassName::Global {
name: value.clone(),
name: *value.clone(),
});
}
}
Expand All @@ -303,10 +299,14 @@ where
}

for class_name in n.value.iter() {
if let ComponentValue::Ident(box Ident { value, .. }) = class_name {
if let ComponentValue::Ident(box Ident { span, value, .. }) = class_name {
if let Some(value) = self.data.orig_to_renamed.get(value) {
composes_for_current.push(CssClassName::Local {
name: value.clone(),
name: Ident {
span: *span,
value: value.clone(),
raw: None,
},
});
}
}
Expand All @@ -328,7 +328,9 @@ where

for v in &mut n.value {
match v {
ComponentValue::Ident(box Ident { value, raw, .. }) => {
ComponentValue::Ident(box Ident {
span, value, raw, ..
}) => {
if !can_change {
continue;
}
Expand Down Expand Up @@ -388,6 +390,7 @@ where
*raw = None;

rename(
*span,
&mut self.config,
&mut self.result,
&mut self.data.orig_to_renamed,
Expand Down Expand Up @@ -438,10 +441,14 @@ where
}
js_word!("animation-name") => {
for v in &mut n.value {
if let ComponentValue::Ident(box Ident { value, raw, .. }) = v {
if let ComponentValue::Ident(box Ident {
span, value, raw, ..
}) = v
{
*raw = None;

rename(
*span,
&mut self.config,
&mut self.result,
&mut self.data.orig_to_renamed,
Expand Down Expand Up @@ -565,6 +572,7 @@ where
}

fn rename<C>(
span: Span,
config: &mut C,
result: &mut TransformResult,
orig_to_renamed: &mut FxHashMap<JsWord, JsWord>,
Expand All @@ -586,7 +594,13 @@ fn rename<C>(
{
let e = result.renamed.entry(name.clone()).or_default();

let v = CssClassName::Local { name: new.clone() };
let v = CssClassName::Local {
name: Ident {
span,
value: new.clone(),
raw: None,
},
};
if !e.contains(&v) {
e.push(v);
}
Expand All @@ -609,6 +623,7 @@ fn process_local<C>(
sel.text.raw = None;

rename(
sel.span,
config,
result,
orig_to_renamed,
Expand All @@ -620,6 +635,7 @@ fn process_local<C>(
sel.text.raw = None;

rename(
sel.span,
config,
result,
orig_to_renamed,
Expand Down
51 changes: 49 additions & 2 deletions crates/swc_css_modules/tests/fixture.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use std::path::PathBuf;

use rustc_hash::FxHashMap;
use serde::Serialize;
use swc_atoms::JsWord;
use swc_css_codegen::{
writer::basic::{BasicCssWriter, BasicCssWriterConfig, IndentType},
CodeGenerator, Emit,
};
use swc_css_modules::CssClassName;
use swc_css_parser::parser::ParserConfig;
use testing::NormalizedOutput;

Expand Down Expand Up @@ -84,8 +87,34 @@ fn compile(input: PathBuf) {
.unwrap();

if !transform_result.renamed.is_empty() {
let transformed_classes =
serde_json::to_string_pretty(&transform_result.renamed).unwrap();
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 }
}
CssClassName::Local { name } => {
CssClassNameForTest::Local { name: name.value }
}
CssClassName::Import { name, from } => {
CssClassNameForTest::Import {
name: name.value,
from,
}
}
})
.collect::<Vec<_>>(),
)
})
.collect::<FxHashMap<_, _>>(),
)
.unwrap();

NormalizedOutput::from(transformed_classes)
.compare_to_file(input.with_file_name(format!(
Expand All @@ -99,6 +128,24 @@ fn compile(input: PathBuf) {
.unwrap();
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
#[serde(tag = "type", rename_all = "camelCase")]
enum CssClassNameForTest {
Local {
/// Tranformed css class name
name: JsWord,
},
Global {
name: JsWord,
},
Import {
/// The exported class name. This is the value specified by the user.
name: JsWord,
/// The module specifier.
from: JsWord,
},
}

struct TestConfig {}

impl swc_css_modules::TransformConfig for TestConfig {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"bulb": [
"1a2b3c": [
{
"type": "local",
"name": "__local__bulb"
"name": "__local__1a2b3c"
}
],
"class": [
Expand Down Expand Up @@ -125,10 +125,10 @@
"name": "__local__test"
}
],
"1a2b3c": [
"bulb": [
{
"type": "local",
"name": "__local__1a2b3c"
"name": "__local__bulb"
}
]
}
8 changes: 4 additions & 4 deletions crates/swc_css_modules/tests/fixture/basic.transform.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"bulb": [
"1a2b3c": [
{
"type": "local",
"name": "__local__bulb"
"name": "__local__1a2b3c"
}
],
"class": [
Expand Down Expand Up @@ -125,10 +125,10 @@
"name": "__local__test"
}
],
"1a2b3c": [
"bulb": [
{
"type": "local",
"name": "__local__1a2b3c"
"name": "__local__bulb"
}
]
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"body": [
"header-baz": [
{
"type": "local",
"name": "__local__body"
"name": "__local__header-baz"
}
],
"footer": [
Expand All @@ -11,10 +11,10 @@
"name": "__local__footer"
}
],
"header-baz": [
"body": [
{
"type": "local",
"name": "__local__header-baz"
"name": "__local__body"
}
]
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
{
"bar": [
{
"type": "local",
"name": "__local__bar"
}
],
"two": [
{
"type": "local",
Expand All @@ -16,11 +22,5 @@
"type": "local",
"name": "__local__one"
}
],
"bar": [
{
"type": "local",
"name": "__local__bar"
}
]
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"⌘⌥": [
"1a2b3c": [
{
"type": "local",
"name": "__local__⌘⌥"
"name": "__local__1a2b3c"
}
],
"1a2b3c": [
"☺☃": [
{
"type": "local",
"name": "__local__1a2b3c"
"name": "__local__☺☃"
}
],
"f+o+o": [
Expand Down Expand Up @@ -281,10 +281,10 @@
"name": "__local__😍"
}
],
"☺☃": [
"⌘⌥": [
{
"type": "local",
"name": "__local__☺☃"
"name": "__local__⌘⌥"
}
]
}
Loading

1 comment on commit df7b4e7

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: df7b4e7 Previous: 98f1493 Ratio
es/full/bugs-1 308518 ns/iter (± 5262) 319640 ns/iter (± 7150) 0.97
es/full/minify/libraries/antd 1618657672 ns/iter (± 40418617) 1726344554 ns/iter (± 10561559) 0.94
es/full/minify/libraries/d3 298840073 ns/iter (± 7936825) 323931996 ns/iter (± 4661319) 0.92
es/full/minify/libraries/echarts 1226898101 ns/iter (± 17894600) 1325201138 ns/iter (± 8392097) 0.93
es/full/minify/libraries/jquery 90277760 ns/iter (± 521093) 100419271 ns/iter (± 2201704) 0.90
es/full/minify/libraries/lodash 104815922 ns/iter (± 912919) 114339196 ns/iter (± 2217249) 0.92
es/full/minify/libraries/moment 52346299 ns/iter (± 423367) 57279717 ns/iter (± 1159558) 0.91
es/full/minify/libraries/react 19138856 ns/iter (± 227146) 20530480 ns/iter (± 388203) 0.93
es/full/minify/libraries/terser 248247521 ns/iter (± 3636671) 281659173 ns/iter (± 3220533) 0.88
es/full/minify/libraries/three 434551669 ns/iter (± 3377169) 514723601 ns/iter (± 8546985) 0.84
es/full/minify/libraries/typescript 3085532926 ns/iter (± 60312318) 3214993155 ns/iter (± 39668692) 0.96
es/full/minify/libraries/victory 704530067 ns/iter (± 11596938) 744374271 ns/iter (± 12072637) 0.95
es/full/minify/libraries/vue 132311610 ns/iter (± 1241176) 146259233 ns/iter (± 1401424) 0.90
es/full/codegen/es3 28789 ns/iter (± 57) 28788 ns/iter (± 94) 1.00
es/full/codegen/es5 28937 ns/iter (± 39) 28822 ns/iter (± 55) 1.00
es/full/codegen/es2015 28896 ns/iter (± 47) 28817 ns/iter (± 61) 1.00
es/full/codegen/es2016 28905 ns/iter (± 38) 28841 ns/iter (± 63) 1.00
es/full/codegen/es2017 28790 ns/iter (± 69) 28863 ns/iter (± 48) 1.00
es/full/codegen/es2018 28925 ns/iter (± 62) 28796 ns/iter (± 55) 1.00
es/full/codegen/es2019 28842 ns/iter (± 80) 28863 ns/iter (± 51) 1.00
es/full/codegen/es2020 28844 ns/iter (± 49) 28838 ns/iter (± 49) 1.00
es/full/all/es3 180580662 ns/iter (± 2351385) 181173783 ns/iter (± 4573435) 1.00
es/full/all/es5 170547068 ns/iter (± 2784161) 173563835 ns/iter (± 3461751) 0.98
es/full/all/es2015 134320395 ns/iter (± 2096706) 133250644 ns/iter (± 2618505) 1.01
es/full/all/es2016 130730819 ns/iter (± 5604847) 134658935 ns/iter (± 3663162) 0.97
es/full/all/es2017 132278857 ns/iter (± 1663664) 131076265 ns/iter (± 2336010) 1.01
es/full/all/es2018 125214455 ns/iter (± 1847700) 126530134 ns/iter (± 1018461) 0.99
es/full/all/es2019 124151561 ns/iter (± 2126899) 125942342 ns/iter (± 982743) 0.99
es/full/all/es2020 116930865 ns/iter (± 675254) 118520078 ns/iter (± 1078796) 0.99
es/full/parser 517571 ns/iter (± 8678) 518430 ns/iter (± 9278) 1.00
es/full/base/fixer 22634 ns/iter (± 54) 22659 ns/iter (± 31) 1.00
es/full/base/resolver_and_hygiene 83764 ns/iter (± 171) 85357 ns/iter (± 84) 0.98
serialization of serde 126 ns/iter (± 0) 126 ns/iter (± 0) 1
css/minify/libraries/bootstrap 27472937 ns/iter (± 118756) 28550237 ns/iter (± 206194) 0.96
css/visitor/compare/clone 2149341 ns/iter (± 7396) 2135819 ns/iter (± 17211) 1.01
css/visitor/compare/visit_mut_span 2313866 ns/iter (± 6592) 2363945 ns/iter (± 10295) 0.98
css/visitor/compare/visit_mut_span_panic 2377476 ns/iter (± 48690) 2381459 ns/iter (± 4263) 1.00
css/visitor/compare/fold_span 3088903 ns/iter (± 12000) 3097252 ns/iter (± 24038) 1.00
css/visitor/compare/fold_span_panic 3286742 ns/iter (± 15002) 3288468 ns/iter (± 14268) 1.00
css/lexer/bootstrap_5_1_3 5139974 ns/iter (± 28215) 5127739 ns/iter (± 17179) 1.00
css/lexer/foundation_6_7_4 4329641 ns/iter (± 2664) 4315051 ns/iter (± 2953) 1.00
css/lexer/tailwind_3_1_1 822982 ns/iter (± 1023) 820416 ns/iter (± 467) 1.00
css/parser/bootstrap_5_1_3 20912642 ns/iter (± 55083) 21912567 ns/iter (± 106670) 0.95
css/parser/foundation_6_7_4 16804827 ns/iter (± 208160) 17243412 ns/iter (± 78088) 0.97
css/parser/tailwind_3_1_1 3221675 ns/iter (± 3038) 3208342 ns/iter (± 5229) 1.00
es/codegen/colors 318092 ns/iter (± 180851) 319195 ns/iter (± 179658) 1.00
es/codegen/large 1278025 ns/iter (± 638888) 1108834 ns/iter (± 553706) 1.15
es/codegen/with-parser/colors 46839 ns/iter (± 336) 47391 ns/iter (± 104) 0.99
es/codegen/with-parser/large 508458 ns/iter (± 1469) 510664 ns/iter (± 1650) 1.00
es/minify/libraries/antd 1428047242 ns/iter (± 48440549) 1554411977 ns/iter (± 21720740) 0.92
es/minify/libraries/d3 253226985 ns/iter (± 4129214) 283503715 ns/iter (± 3056566) 0.89
es/minify/libraries/echarts 1076650813 ns/iter (± 15075787) 1147105523 ns/iter (± 7195882) 0.94
es/minify/libraries/jquery 78774305 ns/iter (± 510272) 85285603 ns/iter (± 887372) 0.92
es/minify/libraries/lodash 94091429 ns/iter (± 515591) 101769111 ns/iter (± 1910453) 0.92
es/minify/libraries/moment 45428124 ns/iter (± 420796) 47037527 ns/iter (± 496431) 0.97
es/minify/libraries/react 17039051 ns/iter (± 189833) 17721400 ns/iter (± 217209) 0.96
es/minify/libraries/terser 208628727 ns/iter (± 2663152) 227810590 ns/iter (± 2176494) 0.92
es/minify/libraries/three 359759426 ns/iter (± 3565709) 409644998 ns/iter (± 6446489) 0.88
es/minify/libraries/typescript 2616041810 ns/iter (± 15188129) 2710772256 ns/iter (± 16365195) 0.97
es/minify/libraries/victory 570016089 ns/iter (± 11792975) 643034972 ns/iter (± 7629931) 0.89
es/minify/libraries/vue 115094218 ns/iter (± 657153) 120150639 ns/iter (± 1564301) 0.96
es/visitor/compare/clone 2320256 ns/iter (± 7677) 2361211 ns/iter (± 16070) 0.98
es/visitor/compare/visit_mut_span 2704710 ns/iter (± 5796) 2723003 ns/iter (± 8174) 0.99
es/visitor/compare/visit_mut_span_panic 2728456 ns/iter (± 2172) 2782484 ns/iter (± 12330) 0.98
es/visitor/compare/fold_span 3788494 ns/iter (± 13854) 3850667 ns/iter (± 21907) 0.98
es/visitor/compare/fold_span_panic 3931931 ns/iter (± 6808) 4016819 ns/iter (± 58524) 0.98
es/lexer/colors 13115 ns/iter (± 13) 13100 ns/iter (± 15) 1.00
es/lexer/angular 6398592 ns/iter (± 7314) 6407649 ns/iter (± 3214) 1.00
es/lexer/backbone 766827 ns/iter (± 652) 767754 ns/iter (± 600) 1.00
es/lexer/jquery 4311618 ns/iter (± 1820) 4326775 ns/iter (± 6123) 1.00
es/lexer/jquery mobile 6749973 ns/iter (± 7837) 6768438 ns/iter (± 5453) 1.00
es/lexer/mootools 3415719 ns/iter (± 2022) 3411408 ns/iter (± 24834) 1.00
es/lexer/underscore 634231 ns/iter (± 231) 633554 ns/iter (± 383) 1.00
es/lexer/three 20524357 ns/iter (± 19427) 20588356 ns/iter (± 12252) 1.00
es/lexer/yui 3837992 ns/iter (± 1346) 3835597 ns/iter (± 5982) 1.00
es/parser/colors 28529 ns/iter (± 99) 28620 ns/iter (± 148) 1.00
es/parser/angular 14986657 ns/iter (± 176217) 15831337 ns/iter (± 292628) 0.95
es/parser/backbone 2164748 ns/iter (± 20346) 2154059 ns/iter (± 10522) 1.00
es/parser/jquery 11686919 ns/iter (± 133893) 11994324 ns/iter (± 384937) 0.97
es/parser/jquery mobile 18270061 ns/iter (± 220408) 19689832 ns/iter (± 208056) 0.93
es/parser/mootools 8857632 ns/iter (± 20665) 8950141 ns/iter (± 64218) 0.99
es/parser/underscore 1814800 ns/iter (± 14864) 1810161 ns/iter (± 8761) 1.00
es/parser/three 53443028 ns/iter (± 845450) 56262059 ns/iter (± 688752) 0.95
es/parser/yui 8974021 ns/iter (± 59228) 9119986 ns/iter (± 68342) 0.98
es/preset-env/usage/builtin_type 144111 ns/iter (± 34326) 143545 ns/iter (± 33774) 1.00
es/preset-env/usage/property 21214 ns/iter (± 65) 20390 ns/iter (± 90) 1.04
es/resolver/typescript 119434908 ns/iter (± 2414700) 127056930 ns/iter (± 4015100) 0.94
es/fixer/typescript 86814490 ns/iter (± 610088) 86912428 ns/iter (± 470601) 1.00
es/hygiene/typescript 190336323 ns/iter (± 2892377) 200724923 ns/iter (± 2274196) 0.95
es/resolver_with_hygiene/typescript 321832300 ns/iter (± 2687353) 338863316 ns/iter (± 776061) 0.95
es/visitor/base-perf/module_clone 80983 ns/iter (± 600) 80751 ns/iter (± 369) 1.00
es/visitor/base-perf/fold_empty 90903 ns/iter (± 250) 90949 ns/iter (± 395) 1.00
es/visitor/base-perf/fold_noop_impl_all 91274 ns/iter (± 388) 90880 ns/iter (± 484) 1.00
es/visitor/base-perf/fold_noop_impl_vec 91441 ns/iter (± 445) 91747 ns/iter (± 349) 1.00
es/visitor/base-perf/boxing_boxed_clone 56 ns/iter (± 0) 56 ns/iter (± 0) 1
es/visitor/base-perf/boxing_unboxed_clone 42 ns/iter (± 0) 42 ns/iter (± 0) 1
es/visitor/base-perf/boxing_boxed 104 ns/iter (± 0) 105 ns/iter (± 0) 0.99
es/visitor/base-perf/boxing_unboxed 78 ns/iter (± 0) 80 ns/iter (± 0) 0.97
es/visitor/base-perf/visit_contains_this 3650 ns/iter (± 64) 3356 ns/iter (± 81) 1.09
es/base/parallel/resolver/typescript 6457017670 ns/iter (± 515271659) 5758831979 ns/iter (± 543405085) 1.12
es/base/parallel/hygiene/typescript 2176684035 ns/iter (± 16616356) 2253374882 ns/iter (± 25398573) 0.97
misc/visitors/time-complexity/time 5 104 ns/iter (± 0) 105 ns/iter (± 10) 0.99
misc/visitors/time-complexity/time 10 326 ns/iter (± 0) 326 ns/iter (± 0) 1
misc/visitors/time-complexity/time 15 661 ns/iter (± 6) 661 ns/iter (± 8) 1
misc/visitors/time-complexity/time 20 1218 ns/iter (± 3) 1221 ns/iter (± 2) 1.00
misc/visitors/time-complexity/time 40 6216 ns/iter (± 27) 6200 ns/iter (± 14) 1.00
misc/visitors/time-complexity/time 60 15585 ns/iter (± 19) 15577 ns/iter (± 11) 1.00
es/full-target/es2016 252365 ns/iter (± 1700) 253256 ns/iter (± 378) 1.00
es/full-target/es2017 246342 ns/iter (± 364) 246019 ns/iter (± 329) 1.00
es/full-target/es2018 234916 ns/iter (± 374) 234988 ns/iter (± 240) 1.00
es2020_nullish_coalescing 92634 ns/iter (± 287) 92697 ns/iter (± 267) 1.00
es2020_optional_chaining 124332 ns/iter (± 107) 124239 ns/iter (± 215) 1.00
es2022_class_properties 149017 ns/iter (± 185) 147928 ns/iter (± 251) 1.01
es2018_object_rest_spread 96319 ns/iter (± 225) 96590 ns/iter (± 251) 1.00
es2019_optional_catch_binding 85295 ns/iter (± 285) 85373 ns/iter (± 140) 1.00
es2017_async_to_generator 85939 ns/iter (± 305) 85953 ns/iter (± 176) 1.00
es2016_exponentiation 90044 ns/iter (± 198) 90452 ns/iter (± 100) 1.00
es2015_arrow 93812 ns/iter (± 341) 94191 ns/iter (± 255) 1.00
es2015_block_scoped_fn 91810 ns/iter (± 202) 92120 ns/iter (± 307) 1.00
es2015_block_scoping 169290 ns/iter (± 405) 169871 ns/iter (± 430) 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.