feat(minifier): minify string PropertyKey (#8147)

This commit is contained in:
Boshen 2024-12-27 15:09:41 +00:00
parent 79af10070d
commit 8fb71f518f
3 changed files with 56 additions and 9 deletions

View file

@ -190,6 +190,10 @@ impl<'a> Traverse<'a> for LatePeepholeOptimizations {
fn exit_call_expression(&mut self, expr: &mut CallExpression<'a>, ctx: &mut TraverseCtx<'a>) {
self.x4_peephole_substitute_alternate_syntax.exit_call_expression(expr, ctx);
}
fn exit_property_key(&mut self, key: &mut PropertyKey<'a>, ctx: &mut TraverseCtx<'a>) {
self.x4_peephole_substitute_alternate_syntax.exit_property_key(key, ctx);
}
}
// See `createPeepholeOptimizationsPass`

View file

@ -77,6 +77,10 @@ impl<'a> Traverse<'a> for PeepholeSubstituteAlternateSyntax {
self.in_define_export = false;
}
fn exit_property_key(&mut self, key: &mut PropertyKey<'a>, ctx: &mut TraverseCtx<'a>) {
self.try_compress_property_key(key, ctx);
}
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
let ctx = Ctx(ctx);
@ -687,6 +691,39 @@ impl<'a, 'b> PeepholeSubstituteAlternateSyntax {
fn empty_array_literal(ctx: Ctx<'a, 'b>) -> Expression<'a> {
Self::array_literal(ctx.ast.vec(), ctx)
}
// https://github.com/swc-project/swc/blob/4e2dae558f60a9f5c6d2eac860743e6c0b2ec562/crates/swc_ecma_minifier/src/compress/pure/properties.rs
#[allow(clippy::cast_lossless)]
fn try_compress_property_key(&mut self, key: &mut PropertyKey<'a>, ctx: &mut TraverseCtx<'a>) {
use oxc_syntax::identifier::is_identifier_name;
let PropertyKey::StringLiteral(s) = key else { return };
if match ctx.parent() {
Ancestor::ObjectPropertyKey(key) => *key.computed(),
Ancestor::BindingPropertyKey(key) => *key.computed(),
Ancestor::MethodDefinitionKey(key) => *key.computed(),
Ancestor::PropertyDefinitionKey(key) => *key.computed(),
Ancestor::AccessorPropertyKey(key) => *key.computed(),
_ => true,
} {
return;
}
if is_identifier_name(&s.value) {
self.changed = true;
*key = PropertyKey::StaticIdentifier(
ctx.ast.alloc_identifier_name(s.span, s.value.clone()),
);
} else if (!s.value.starts_with('0') && !s.value.starts_with('+')) || s.value.len() <= 1 {
if let Ok(value) = s.value.parse::<u32>() {
self.changed = true;
*key = PropertyKey::NumericLiteral(ctx.ast.alloc_numeric_literal(
s.span,
value as f64,
None,
NumberBase::Decimal,
));
}
}
}
}
/// Port from <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/PeepholeSubstituteAlternateSyntaxTest.java>
@ -1137,4 +1174,10 @@ mod test {
test("typeof foo !== `number`", "typeof foo != 'number'");
test("`number` !== typeof foo", "'number' != typeof foo");
}
#[test]
fn test_object_key() {
test("({ '0': _, 'a': _ })", "({ 0: _, a: _ })");
test_same("({ '1.1': _, '😊': _, 'a.a': _ })");
}
}

View file

@ -5,23 +5,23 @@ Original | minified | minified | gzip | gzip | Fixture
173.90 kB | 60.22 kB | 59.82 kB | 19.49 kB | 19.33 kB | moment.js
287.63 kB | 90.74 kB | 90.07 kB | 32.21 kB | 31.95 kB | jquery.js
287.63 kB | 90.61 kB | 90.07 kB | 32.19 kB | 31.95 kB | jquery.js
342.15 kB | 118.77 kB | 118.14 kB | 44.54 kB | 44.37 kB | vue.js
342.15 kB | 118.76 kB | 118.14 kB | 44.54 kB | 44.37 kB | vue.js
544.10 kB | 72.53 kB | 72.48 kB | 26.23 kB | 26.20 kB | lodash.js
544.10 kB | 72.05 kB | 72.48 kB | 26.19 kB | 26.20 kB | lodash.js
555.77 kB | 274.26 kB | 270.13 kB | 91.26 kB | 90.80 kB | d3.js
555.77 kB | 274.04 kB | 270.13 kB | 91.20 kB | 90.80 kB | d3.js
1.01 MB | 461.13 kB | 458.89 kB | 126.91 kB | 126.71 kB | bundle.min.js
1.25 MB | 657.23 kB | 646.76 kB | 164.23 kB | 163.73 kB | three.js
1.25 MB | 656.86 kB | 646.76 kB | 164.20 kB | 163.73 kB | three.js
2.14 MB | 735.67 kB | 724.14 kB | 181.09 kB | 181.07 kB | victory.js
2.14 MB | 735.43 kB | 724.14 kB | 181.01 kB | 181.07 kB | victory.js
3.20 MB | 1.01 MB | 1.01 MB | 332.35 kB | 331.56 kB | echarts.js
3.20 MB | 1.01 MB | 1.01 MB | 332.34 kB | 331.56 kB | echarts.js
6.69 MB | 2.38 MB | 2.31 MB | 495.33 kB | 488.28 kB | antd.js
6.69 MB | 2.36 MB | 2.31 MB | 495.04 kB | 488.28 kB | antd.js
10.95 MB | 3.51 MB | 3.49 MB | 910.94 kB | 915.50 kB | typescript.js
10.95 MB | 3.51 MB | 3.49 MB | 910.95 kB | 915.50 kB | typescript.js