Skip to content

Commit cf5175c

Browse files
committed
fix(transformer/styled-components): remove unnecessary whitespace when removing block comments in CSS minification (#13390)
Remove special logic for inserting spaces when removing comments. Instead, treat comments as equivalent to whitespace, and apply the same rules. This fixes 2 problems: 1. Don't add unnecessary space when a block comment appears after a character like `{`. 2. *Do* add a space when a block comment is the whole quasi between 2 interpolations, to prevent them being merged. Simplifying this logic also gives 1%-2% speed-up on transformer benchmarks. Input: ```js styled.div`.a {/* blah */color: green; }`; styled.div`${x}/* blah */${y}`; ``` Previous output post-minification: ```js styled.div`.a{ color:green;}`; styled.div`${x}${y}`; ``` After this PR: ```js styled.div`.a{color:green;}`; styled.div`${x} ${y}`; ```
1 parent 95d4311 commit cf5175c

File tree

3 files changed

+21
-34
lines changed

3 files changed

+21
-34
lines changed

crates/oxc_transformer/src/plugins/styled_components.rs

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -920,34 +920,24 @@ fn minify_template_literal<'a>(lit: &mut TemplateLiteral<'a>, ast: AstBuilder<'a
920920

921921
// Find end of comment
922922
let start_index = if is_block_comment {
923-
let Some(mut pos) = bytes.windows(2).position(|q| q == b"*/") else {
923+
let Some(pos) = bytes.windows(2).position(|q| q == b"*/") else {
924924
// Comment contains whole of this quasi
925925
continue;
926926
};
927-
928-
pos += 2;
929-
if pos == bytes.len() {
930-
// Comment ends at end of quasi
931-
comment_type = None;
932-
continue;
933-
}
934-
935-
// Add a space when this is a own line block comment
936-
if !bytes[pos].is_ascii_whitespace()
937-
&& output.last().is_some_and(|&last| last != b' ')
938-
{
939-
output.push(b' ');
940-
}
941-
942-
pos
927+
pos + 2 // After `*/`
943928
} else {
944929
let Some(pos) = bytes.iter().position(|&b| matches!(b, b'\n' | b'\r')) else {
945930
// Comment contains whole of this quasi
946931
continue;
947932
};
948-
pos
933+
pos + 1 // After `\n` or `\r`
949934
};
950935

936+
// Comments behave like whitespace.
937+
// Block comments: `padding: 10/* */0` is equivalent to `padding: 10 0`, not `padding: 100`.
938+
// Line comments: End with a newline (whitespace).
939+
insert_space_if_required(&mut output, quasi_index);
940+
951941
// Trim off to end of comment
952942
bytes = &bytes[start_index..];
953943

@@ -1018,19 +1008,11 @@ fn minify_template_literal<'a>(lit: &mut TemplateLiteral<'a>, ast: AstBuilder<'a
10181008
let end_index =
10191009
bytes[i + 2..].windows(2).position(|q| q == b"*/");
10201010
if let Some(end_index) = end_index {
1021-
i += end_index + 4; // After `*/`
1011+
// Block comments behave like whitespace.
1012+
// `padding: 10/* */0` is equivalent to `padding: 10 0`, not `padding: 100`.
1013+
insert_space_if_required(&mut output, quasi_index);
10221014

1023-
if i == bytes.len() {
1024-
// Comment ends at end of quasi
1025-
break;
1026-
}
1027-
1028-
// Add a space when this is a own line block comment
1029-
if !bytes[i].is_ascii_whitespace()
1030-
&& output.last().is_some_and(|&last| last != b' ')
1031-
{
1032-
output.push(b' ');
1033-
}
1015+
i += end_index + 4; // After `*/`
10341016
continue;
10351017
}
10361018

@@ -1046,7 +1028,10 @@ fn minify_template_literal<'a>(lit: &mut TemplateLiteral<'a>, ast: AstBuilder<'a
10461028
let end_index =
10471029
bytes[i + 2..].iter().position(|&b| matches!(b, b'\n' | b'\r'));
10481030
if let Some(end_index) = end_index {
1049-
i += end_index + 2; // On `\n` or `\r`
1031+
// Insert space in place of `\n` / `\r`
1032+
insert_space_if_required(&mut output, quasi_index);
1033+
1034+
i += end_index + 3; // After `\n` or `\r`
10501035
continue;
10511036
}
10521037

tasks/transform_conformance/tests/plugin-styled-components/test/fixtures/minify-comments/input.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ const Bar = styled.div`
1515
const Qux = styled.div`
1616
color: /* blah */ red;
1717
.a /* blah */ { color: blue; }
18+
.b {/* blah */color: green; }
1819
`;
1920

2021
const Bing = styled.div`
2122
color: /* ${123} */ red;
2223
.a /* ${123} */ { color: blue; }
24+
.b {/* ${123} */color: green; }
2325
`;
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import styled from 'styled-components';
2-
const Button = styled.div`${x}${z}`;
2+
const Button = styled.div`${x} ${z}`;
33
const Foo = styled.div`.a{color:red;}`;
44
const Bar = styled.div`.a{color:red;}`;
5-
const Qux = styled.div`color:red;.a{color:blue;}`;
6-
const Bing = styled.div`color:red;.a{color:blue;}`;
5+
const Qux = styled.div`color:red;.a{color:blue;}.b{color:green;}`;
6+
const Bing = styled.div`color:red;.a{color:blue;}.b{color:green;}`;

0 commit comments

Comments
 (0)