From a69d15f2990a2271b65b0e6c3ba7a4ee56fa4274 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Wed, 8 Jan 2025 12:07:46 +0000 Subject: [PATCH] feat(minifier): compress `new Array(2)` -> `[,,]` (#8344) For an integer value `n` smaller than 6, `Array(n)` can be compressed to `[,,]` (the number of `,` is `n`). --- .../peephole_substitute_alternate_syntax.rs | 21 ++++++++++++++++++- tasks/minsize/minsize.snap | 4 ++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs b/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs index e35eed20c8a01..763405d231d70 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs @@ -762,7 +762,24 @@ impl<'a, 'b> PeepholeSubstituteAlternateSyntax { Some(ctx.ast.expression_array(span, ctx.ast.vec(), None)) } // `new Array(8)` -> `Array(8)` - else if let Expression::NumericLiteral(_) = arg { + else if let Expression::NumericLiteral(n) = arg { + // new Array(2) -> `[,,]` + // this does not work with IE8 and below + // learned from https://github.com/babel/minify/pull/45 + #[expect(clippy::cast_possible_truncation)] + if n.value.fract() == 0.0 { + let n_int = n.value as i64; + if (1..=6).contains(&n_int) { + return Some(ctx.ast.expression_array( + span, + ctx.ast.vec_from_iter((0..n_int).map(|_| { + ArrayExpressionElement::Elision(Elision { span: SPAN }) + })), + None, + )); + } + } + let callee = ctx.ast.expression_identifier_reference(SPAN, "Array"); let args = ctx.ast.move_vec(args); Some(ctx.ast.expression_call(span, callee, NONE, args, false)) @@ -1143,6 +1160,8 @@ mod test { // One argument test("x = new Array(0)", "x = []"); test("x = new Array(\"a\")", "x = [\"a\"]"); + test("x = new Array(1)", "x = [,]"); + test("x = new Array(6)", "x = [,,,,,,]"); test("x = new Array(7)", "x = Array(7)"); test("x = new Array(7n)", "x = [7n]"); test("x = new Array(y)", "x = Array(y)"); diff --git a/tasks/minsize/minsize.snap b/tasks/minsize/minsize.snap index de8d0ea670d32..1ab509dc6d1b3 100644 --- a/tasks/minsize/minsize.snap +++ b/tasks/minsize/minsize.snap @@ -11,7 +11,7 @@ Original | minified | minified | gzip | gzip | Fixture 544.10 kB | 71.75 kB | 72.48 kB | 26.16 kB | 26.20 kB | lodash.js -555.77 kB | 272.91 kB | 270.13 kB | 90.92 kB | 90.80 kB | d3.js +555.77 kB | 272.82 kB | 270.13 kB | 90.92 kB | 90.80 kB | d3.js 1.01 MB | 460.22 kB | 458.89 kB | 126.83 kB | 126.71 kB | bundle.min.js @@ -23,5 +23,5 @@ Original | minified | minified | gzip | gzip | Fixture 6.69 MB | 2.32 MB | 2.31 MB | 492.72 kB | 488.28 kB | antd.js -10.95 MB | 3.50 MB | 3.49 MB | 908.29 kB | 915.50 kB | typescript.js +10.95 MB | 3.50 MB | 3.49 MB | 908.28 kB | 915.50 kB | typescript.js