From 6237c0527fb6d741b29c8e20bf674e5afecd3487 Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Tue, 24 Dec 2024 09:54:12 +0000 Subject: [PATCH] feat(codegen): minify more whitespace (#8089) --- crates/oxc_codegen/src/gen.rs | 56 +++++++++++++------- crates/oxc_codegen/tests/integration/unit.rs | 4 +- tasks/minsize/minsize.snap | 6 +-- 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 034fc420c6f69..6d0cd25e50d98 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -396,7 +396,7 @@ impl Gen for ForInStatement<'_> { p.print_soft_space(); p.print_space_before_identifier(); p.print_str("in"); - p.print_hard_space(); + p.print_soft_space(); p.print_expression(&self.right); p.print_ascii_byte(b')'); p.print_body(&self.body, false, ctx); @@ -503,7 +503,7 @@ impl Gen for ContinueStatement<'_> { p.print_indent(); p.print_str("continue"); if let Some(label) = &self.label { - p.print_hard_space(); + p.print_soft_space(); label.print(p, ctx); } p.print_semicolon_after_statement(); @@ -516,7 +516,7 @@ impl Gen for BreakStatement<'_> { p.print_indent(); p.print_str("break"); if let Some(label) = &self.label { - p.print_hard_space(); + p.print_soft_space(); label.print(p, ctx); } p.print_semicolon_after_statement(); @@ -800,14 +800,17 @@ impl Gen for FormalParameter<'_> { fn gen(&self, p: &mut Codegen, ctx: Context) { for decorator in &self.decorators { decorator.print(p, ctx); - p.print_hard_space(); + p.print_soft_space(); } if let Some(accessibility) = self.accessibility { + p.print_space_before_identifier(); p.print_str(accessibility.as_str()); - p.print_hard_space(); + p.print_soft_space(); } if self.readonly { - p.print_str("readonly "); + p.print_space_before_identifier(); + p.print_str("readonly"); + p.print_soft_space(); } self.pattern.print(p, ctx); } @@ -1237,6 +1240,7 @@ impl Gen for BindingIdentifier<'_> { impl Gen for LabelIdentifier<'_> { fn gen(&self, p: &mut Codegen, _ctx: Context) { + p.print_space_before_identifier(); p.add_source_mapping_for_name(self.span, &self.name); p.print_str(self.name.as_str()); } @@ -1843,7 +1847,7 @@ impl GenExpr for UnaryExpression<'_> { if self.operator.is_keyword() { p.print_space_before_identifier(); p.print_str(operator); - p.print_hard_space(); + p.print_soft_space(); } else { p.print_space_before_operator(self.operator.into()); p.print_str(operator); @@ -2089,21 +2093,33 @@ impl Gen for AssignmentTargetPropertyIdentifier<'_> { impl Gen for AssignmentTargetPropertyProperty<'_> { fn gen(&self, p: &mut Codegen, ctx: Context) { - match &self.name { - PropertyKey::StaticIdentifier(ident) => { - ident.print(p, ctx); - } - PropertyKey::PrivateIdentifier(ident) => { - ident.print(p, ctx); - } - key @ match_expression!(PropertyKey) => { - p.print_ascii_byte(b'['); - key.to_expression().print_expr(p, Precedence::Comma, Context::empty()); - p.print_ascii_byte(b']'); + let omit_key = if p.options.minify { + let key_name = match &self.name { + PropertyKey::StaticIdentifier(ident) => Some(&ident.name), + _ => None, + }; + let value_name = self.binding.name(); + key_name.is_some() && value_name.is_some() && key_name == value_name.as_ref() + } else { + false + }; + if !omit_key { + match &self.name { + PropertyKey::StaticIdentifier(ident) => { + ident.print(p, ctx); + } + PropertyKey::PrivateIdentifier(ident) => { + ident.print(p, ctx); + } + key @ match_expression!(PropertyKey) => { + p.print_ascii_byte(b'['); + key.to_expression().print_expr(p, Precedence::Comma, Context::empty()); + p.print_ascii_byte(b']'); + } } + p.print_colon(); + p.print_soft_space(); } - p.print_colon(); - p.print_soft_space(); self.binding.print(p, ctx); } } diff --git a/crates/oxc_codegen/tests/integration/unit.rs b/crates/oxc_codegen/tests/integration/unit.rs index 0a94081d4f7e0..65962f8930d0d 100644 --- a/crates/oxc_codegen/tests/integration/unit.rs +++ b/crates/oxc_codegen/tests/integration/unit.rs @@ -37,7 +37,7 @@ fn expr() { test_minify_same("await import(\"\");"); test("delete 2e308", "delete (0, Infinity);\n"); - test_minify("delete 2e308", "delete (1/0);"); + test_minify("delete 2e308", "delete(1/0);"); } #[test] @@ -154,7 +154,7 @@ fn assignment() { test_minify("a /= () => {}", "a/=()=>{};"); test_minify("a %= async () => {}", "a%=async()=>{};"); test_minify("a -= (1, 2)", "a-=(1,2);"); - test_minify("a >>= b >>= c", "a>>=b>>=c;"); + test_minify("({ x: x = flag1 = true } = {})", "({x=flag1=true}={});"); } #[test] diff --git a/tasks/minsize/minsize.snap b/tasks/minsize/minsize.snap index d1d640a2b34bd..2bafb223e0892 100644 --- a/tasks/minsize/minsize.snap +++ b/tasks/minsize/minsize.snap @@ -13,7 +13,7 @@ Original | minified | minified | gzip | gzip | Fixture 555.77 kB | 276.06 kB | 270.13 kB | 91.14 kB | 90.80 kB | d3.js -1.01 MB | 466.83 kB | 458.89 kB | 126.74 kB | 126.71 kB | bundle.min.js +1.01 MB | 466.82 kB | 458.89 kB | 126.74 kB | 126.71 kB | bundle.min.js 1.25 MB | 661.47 kB | 646.76 kB | 163.94 kB | 163.73 kB | three.js @@ -21,7 +21,7 @@ Original | minified | minified | gzip | gzip | Fixture 3.20 MB | 1.02 MB | 1.01 MB | 332.00 kB | 331.56 kB | echarts.js -6.69 MB | 2.39 MB | 2.31 MB | 495.62 kB | 488.28 kB | antd.js +6.69 MB | 2.39 MB | 2.31 MB | 495.63 kB | 488.28 kB | antd.js -10.95 MB | 3.54 MB | 3.49 MB | 909.70 kB | 915.50 kB | typescript.js +10.95 MB | 3.54 MB | 3.49 MB | 909.72 kB | 915.50 kB | typescript.js