mirror of
https://github.com/danbulant/oxc
synced 2026-05-20 04:38:54 +00:00
feat(minifier): minimize foo ? foo : bar and foo ? bar : foo (#8229)
This commit is contained in:
parent
0e14bd8cab
commit
51f47926ef
3 changed files with 43 additions and 4 deletions
|
|
@ -98,7 +98,6 @@ oxc_semantic = { version = "0.44.0", path = "crates/oxc_semantic" }
|
||||||
oxc_span = { version = "0.44.0", path = "crates/oxc_span" }
|
oxc_span = { version = "0.44.0", path = "crates/oxc_span" }
|
||||||
oxc_syntax = { version = "0.44.0", path = "crates/oxc_syntax" }
|
oxc_syntax = { version = "0.44.0", path = "crates/oxc_syntax" }
|
||||||
oxc_transform_napi = { version = "0.44.0", path = "napi/transform" }
|
oxc_transform_napi = { version = "0.44.0", path = "napi/transform" }
|
||||||
oxc_parser_napi = { version = "0.44.0", path = "napi/parser" }
|
|
||||||
oxc_transformer = { version = "0.44.0", path = "crates/oxc_transformer" }
|
oxc_transformer = { version = "0.44.0", path = "crates/oxc_transformer" }
|
||||||
oxc_traverse = { version = "0.44.0", path = "crates/oxc_traverse" }
|
oxc_traverse = { version = "0.44.0", path = "crates/oxc_traverse" }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ impl<'a> Traverse<'a> for PeepholeSubstituteAlternateSyntax {
|
||||||
Expression::NewExpression(e) => Self::try_fold_new_expression(e, ctx),
|
Expression::NewExpression(e) => Self::try_fold_new_expression(e, ctx),
|
||||||
Expression::TemplateLiteral(t) => Self::try_fold_template_literal(t, ctx),
|
Expression::TemplateLiteral(t) => Self::try_fold_template_literal(t, ctx),
|
||||||
Expression::BinaryExpression(e) => Self::try_compress_typeof_undefined(e, ctx),
|
Expression::BinaryExpression(e) => Self::try_compress_typeof_undefined(e, ctx),
|
||||||
|
Expression::ConditionalExpression(e) => Self::try_compress_conditional(e, ctx),
|
||||||
Expression::CallExpression(e) => {
|
Expression::CallExpression(e) => {
|
||||||
Self::try_fold_literal_constructor_call_expression(e, ctx)
|
Self::try_fold_literal_constructor_call_expression(e, ctx)
|
||||||
.or_else(|| Self::try_fold_simple_function_call(e, ctx))
|
.or_else(|| Self::try_fold_simple_function_call(e, ctx))
|
||||||
|
|
@ -265,6 +266,37 @@ impl<'a, 'b> PeepholeSubstituteAlternateSyntax {
|
||||||
Some(ctx.ast.expression_binary(expr.span, left, new_comp_op, right))
|
Some(ctx.ast.expression_binary(expr.span, left, new_comp_op, right))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_compress_conditional(
|
||||||
|
expr: &mut ConditionalExpression<'a>,
|
||||||
|
ctx: Ctx<'a, 'b>,
|
||||||
|
) -> Option<Expression<'a>> {
|
||||||
|
if let Expression::Identifier(ident_test) = &expr.test {
|
||||||
|
// `foo ? foo : bar` -> `foo || bar`
|
||||||
|
if let Expression::Identifier(ident_consequent) = &expr.consequent {
|
||||||
|
if ident_test.name == ident_consequent.name {
|
||||||
|
return Some(ctx.ast.expression_logical(
|
||||||
|
expr.span,
|
||||||
|
ctx.ast.move_expression(&mut expr.test),
|
||||||
|
LogicalOperator::Or,
|
||||||
|
ctx.ast.move_expression(&mut expr.alternate),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// `foo ? bar : foo` -> `foo && bar`
|
||||||
|
if let Expression::Identifier(ident_alternate) = &expr.alternate {
|
||||||
|
if ident_test.name == ident_alternate.name {
|
||||||
|
return Some(ctx.ast.expression_logical(
|
||||||
|
expr.span,
|
||||||
|
ctx.ast.move_expression(&mut expr.test),
|
||||||
|
LogicalOperator::And,
|
||||||
|
ctx.ast.move_expression(&mut expr.consequent),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
/// Compress `foo === null || foo === undefined` into `foo == null`.
|
/// Compress `foo === null || foo === undefined` into `foo == null`.
|
||||||
///
|
///
|
||||||
/// `foo === null || foo === undefined` => `foo == null`
|
/// `foo === null || foo === undefined` => `foo == null`
|
||||||
|
|
@ -1179,4 +1211,12 @@ mod test {
|
||||||
test("typeof foo !== `number`", "typeof foo != 'number'");
|
test("typeof foo !== `number`", "typeof foo != 'number'");
|
||||||
test("`number` !== typeof foo", "typeof foo != 'number'");
|
test("`number` !== typeof foo", "typeof foo != 'number'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn compress_conditional() {
|
||||||
|
test("foo ? foo : bar", "foo || bar");
|
||||||
|
test("foo ? bar : foo", "foo && bar");
|
||||||
|
test_same("x.y ? x.y : bar");
|
||||||
|
test_same("x.y ? bar : x.y");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,13 @@ Original | minified | minified | gzip | gzip | Fixture
|
||||||
|
|
||||||
287.63 kB | 90.16 kB | 90.07 kB | 32.08 kB | 31.95 kB | jquery.js
|
287.63 kB | 90.16 kB | 90.07 kB | 32.08 kB | 31.95 kB | jquery.js
|
||||||
|
|
||||||
342.15 kB | 118.23 kB | 118.14 kB | 44.53 kB | 44.37 kB | vue.js
|
342.15 kB | 118.23 kB | 118.14 kB | 44.52 kB | 44.37 kB | vue.js
|
||||||
|
|
||||||
544.10 kB | 71.81 kB | 72.48 kB | 26.19 kB | 26.20 kB | lodash.js
|
544.10 kB | 71.81 kB | 72.48 kB | 26.19 kB | 26.20 kB | lodash.js
|
||||||
|
|
||||||
555.77 kB | 273.19 kB | 270.13 kB | 90.99 kB | 90.80 kB | d3.js
|
555.77 kB | 273.19 kB | 270.13 kB | 90.99 kB | 90.80 kB | d3.js
|
||||||
|
|
||||||
1.01 MB | 460.32 kB | 458.89 kB | 126.85 kB | 126.71 kB | bundle.min.js
|
1.01 MB | 460.32 kB | 458.89 kB | 126.84 kB | 126.71 kB | bundle.min.js
|
||||||
|
|
||||||
1.25 MB | 652.73 kB | 646.76 kB | 163.55 kB | 163.73 kB | three.js
|
1.25 MB | 652.73 kB | 646.76 kB | 163.55 kB | 163.73 kB | three.js
|
||||||
|
|
||||||
|
|
@ -23,5 +23,5 @@ Original | minified | minified | gzip | gzip | Fixture
|
||||||
|
|
||||||
6.69 MB | 2.32 MB | 2.31 MB | 492.81 kB | 488.28 kB | antd.js
|
6.69 MB | 2.32 MB | 2.31 MB | 492.81 kB | 488.28 kB | antd.js
|
||||||
|
|
||||||
10.95 MB | 3.50 MB | 3.49 MB | 909.54 kB | 915.50 kB | typescript.js
|
10.95 MB | 3.50 MB | 3.49 MB | 909.52 kB | 915.50 kB | typescript.js
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue