diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 44db97b044b28..e842c8a6a54ac 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -477,7 +477,7 @@ impl Gen for ReturnStatement<'_> { p.print_space_before_identifier(); p.print_str("return"); if let Some(arg) = &self.argument { - p.print_hard_space(); + p.print_soft_space(); p.print_expression(arg); } p.print_semicolon_after_statement(); @@ -531,7 +531,8 @@ impl Gen for ThrowStatement<'_> { fn gen(&self, p: &mut Codegen, _ctx: Context) { p.add_source_mapping(self.span); p.print_indent(); - p.print_str("throw "); + p.print_str("throw"); + p.print_soft_space(); p.print_expression(&self.argument); p.print_semicolon_after_statement(); } @@ -1316,8 +1317,8 @@ impl Gen for StringLiteral<'_> { impl Gen for ThisExpression { fn gen(&self, p: &mut Codegen, _ctx: Context) { - p.add_source_mapping(self.span); p.print_space_before_identifier(); + p.add_source_mapping(self.span); p.print_str("this"); } } @@ -1628,14 +1629,11 @@ impl GenExpr for ArrowFunctionExpression<'_> { p.wrap(precedence >= Precedence::Assign, |p| { p.print_annotation_comments(self.span.start); if self.r#async { + p.print_space_before_identifier(); p.add_source_mapping(self.span); p.print_str("async"); + p.print_soft_space(); } - - if self.r#async { - p.print_hard_space(); - } - if let Some(type_parameters) = &self.type_parameters { type_parameters.print(p, ctx); } @@ -1666,8 +1664,8 @@ impl GenExpr for ArrowFunctionExpression<'_> { impl GenExpr for YieldExpression<'_> { fn gen_expr(&self, p: &mut Codegen, precedence: Precedence, _ctx: Context) { p.wrap(precedence >= Precedence::Assign, |p| { - p.add_source_mapping(self.span); p.print_space_before_identifier(); + p.add_source_mapping(self.span); p.print_str("yield"); if self.delegate { p.print_ascii_byte(b'*'); @@ -1992,6 +1990,7 @@ impl GenExpr for ImportExpression<'_> { || self.arguments.first().is_some_and(|argument| p.has_comment(argument.span().start)); p.wrap(wrap, |p| { + p.print_space_before_identifier(); p.add_source_mapping(self.span); p.print_str("import("); if has_comment { @@ -2059,6 +2058,7 @@ impl Gen for TaggedTemplateExpression<'_> { impl Gen for Super { fn gen(&self, p: &mut Codegen, _ctx: Context) { + p.print_space_before_identifier(); p.add_source_mapping(self.span); p.print_str("super"); } @@ -2067,8 +2067,10 @@ impl Gen for Super { impl GenExpr for AwaitExpression<'_> { fn gen_expr(&self, p: &mut Codegen, precedence: Precedence, ctx: Context) { p.wrap(precedence >= self.precedence(), |p| { + p.print_space_before_identifier(); p.add_source_mapping(self.span); - p.print_str("await "); + p.print_str("await"); + p.print_soft_space(); self.argument.print_expr(p, Precedence::Exponentiation, ctx); }); } @@ -2181,6 +2183,7 @@ impl GenExpr for TSTypeAssertion<'_> { impl Gen for MetaProperty<'_> { fn gen(&self, p: &mut Codegen, ctx: Context) { + p.print_space_before_identifier(); p.add_source_mapping(self.span); self.meta.print(p, ctx); p.print_ascii_byte(b'.'); @@ -2198,6 +2201,8 @@ impl Gen for Class<'_> { decorator.print(p, ctx); p.print_hard_space(); } + p.print_space_before_identifier(); + p.add_source_mapping(self.span); if self.declare { p.print_str("declare "); } diff --git a/crates/oxc_codegen/tests/integration/tester.rs b/crates/oxc_codegen/tests/integration/tester.rs index 5f8d8a3993171..db34cc449f81a 100644 --- a/crates/oxc_codegen/tests/integration/tester.rs +++ b/crates/oxc_codegen/tests/integration/tester.rs @@ -29,3 +29,7 @@ pub fn test_minify(source_text: &str, expected: &str) { .code; assert_eq!(result, expected, "\nfor minify source: {source_text}"); } + +pub fn test_minify_same(source_text: &str) { + test_minify(source_text, source_text); +} diff --git a/crates/oxc_codegen/tests/integration/unit.rs b/crates/oxc_codegen/tests/integration/unit.rs index cb38a9608cae9..94bbf98faf3e2 100644 --- a/crates/oxc_codegen/tests/integration/unit.rs +++ b/crates/oxc_codegen/tests/integration/unit.rs @@ -1,4 +1,4 @@ -use crate::tester::{test, test_minify, test_without_source}; +use crate::tester::{test, test_minify, test_minify_same, test_without_source}; #[test] fn module_decl() { @@ -15,6 +15,15 @@ fn expr() { test("1000000000000000128.0.toFixed(0)", "0xde0b6b3a7640080.toFixed(0);\n"); test_minify("1000000000000000128.0.toFixed(0)", "0xde0b6b3a7640080.toFixed(0);"); + + test_minify("throw 'foo'", "throw\"foo\";"); + test_minify("return 'foo'", "return\"foo\";"); + test_minify("return class {}", "return class{};"); + test_minify("return async function foo() {}", "return async function foo(){};"); + test_minify_same("return super();"); + test_minify_same("return new.target;"); + test_minify_same("throw await 1;"); + test_minify_same("await import(\"\");"); } #[test] @@ -121,7 +130,7 @@ fn assignment() { test_minify("({a,b} = (1, 2))", "({a,b}=(1,2));"); test_minify("a *= yield b", "a*=yield b;"); test_minify("a /= () => {}", "a/=()=>{};"); - test_minify("a %= async () => {}", "a%=async ()=>{};"); + test_minify("a %= async () => {}", "a%=async()=>{};"); test_minify("a -= (1, 2)", "a-=(1,2);"); test_minify("a >>= b >>= c", "a>>=b>>=c;"); } @@ -132,11 +141,11 @@ fn r#yield() { test_minify("function *foo() { yield * a ? b : c }", "function*foo(){yield*a?b:c}"); test_minify("function *foo() { yield * yield * a }", "function*foo(){yield*yield*a}"); test_minify("function *foo() { yield * () => {} }", "function*foo(){yield*()=>{}}"); - test_minify("function *foo() { yield * async () => {} }", "function*foo(){yield*async ()=>{}}"); + test_minify("function *foo() { yield * async () => {} }", "function*foo(){yield*async()=>{}}"); test_minify("function *foo() { yield a ? b : c }", "function*foo(){yield a?b:c}"); test_minify("function *foo() { yield yield a }", "function*foo(){yield yield a}"); test_minify("function *foo() { yield () => {} }", "function*foo(){yield ()=>{}}"); - test_minify("function *foo() { yield async () => {} }", "function*foo(){yield async ()=>{}}"); + test_minify("function *foo() { yield async () => {} }", "function*foo(){yield async()=>{}}"); test_minify( "function *foo() { yield { a } = [ b ] = c ? b : d }", "function*foo(){yield {a}=[b]=c?b:d}", diff --git a/tasks/minsize/minsize.snap b/tasks/minsize/minsize.snap index c558032d6af2c..9bb0b3b5ec7ed 100644 --- a/tasks/minsize/minsize.snap +++ b/tasks/minsize/minsize.snap @@ -1,26 +1,26 @@ Original | Minified | esbuild | Gzip | esbuild -72.14 kB | 24.12 kB | 23.70 kB | 8.62 kB | 8.54 kB | react.development.js +72.14 kB | 24.09 kB | 23.70 kB | 8.62 kB | 8.54 kB | react.development.js -173.90 kB | 61.67 kB | 59.82 kB | 19.54 kB | 19.33 kB | moment.js +173.90 kB | 61.61 kB | 59.82 kB | 19.55 kB | 19.33 kB | moment.js -287.63 kB | 92.70 kB | 90.07 kB | 32.26 kB | 31.95 kB | jquery.js +287.63 kB | 92.61 kB | 90.07 kB | 32.27 kB | 31.95 kB | jquery.js -342.15 kB | 121.90 kB | 118.14 kB | 44.59 kB | 44.37 kB | vue.js +342.15 kB | 121.79 kB | 118.14 kB | 44.59 kB | 44.37 kB | vue.js -544.10 kB | 73.48 kB | 72.48 kB | 26.12 kB | 26.20 kB | lodash.js +544.10 kB | 73.37 kB | 72.48 kB | 26.13 kB | 26.20 kB | lodash.js -555.77 kB | 276.48 kB | 270.13 kB | 91.15 kB | 90.80 kB | d3.js +555.77 kB | 276.22 kB | 270.13 kB | 91.15 kB | 90.80 kB | d3.js -1.01 MB | 467.59 kB | 458.89 kB | 126.73 kB | 126.71 kB | bundle.min.js +1.01 MB | 467.14 kB | 458.89 kB | 126.74 kB | 126.71 kB | bundle.min.js -1.25 MB | 662.83 kB | 646.76 kB | 164.00 kB | 163.73 kB | three.js +1.25 MB | 662.69 kB | 646.76 kB | 164.02 kB | 163.73 kB | three.js -2.14 MB | 741.55 kB | 724.14 kB | 181.45 kB | 181.07 kB | victory.js +2.14 MB | 740.94 kB | 724.14 kB | 181.49 kB | 181.07 kB | victory.js -3.20 MB | 1.02 MB | 1.01 MB | 332.07 kB | 331.56 kB | echarts.js +3.20 MB | 1.02 MB | 1.01 MB | 332.09 kB | 331.56 kB | echarts.js -6.69 MB | 2.39 MB | 2.31 MB | 496.11 kB | 488.28 kB | antd.js +6.69 MB | 2.39 MB | 2.31 MB | 496.17 kB | 488.28 kB | antd.js -10.95 MB | 3.56 MB | 3.49 MB | 911.20 kB | 915.50 kB | typescript.js +10.95 MB | 3.56 MB | 3.49 MB | 911.37 kB | 915.50 kB | typescript.js