Skip to content

Commit

Permalink
feat(minifier): compress typeof foo == "undefined" into `typeof foo…
Browse files Browse the repository at this point in the history
… > "u"` (#4412)

```
> monitor-oxc@ test /home/runner/work/monitor-oxc/monitor-oxc
> node src/main.test.mjs

/home/runner/work/monitor-oxc/monitor-oxc/node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:2375
		if (void 0 === __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1;
		^

ReferenceError: __REACT_DEVTOOLS_GLOBAL_HOOK__ is not defined
    at injectInternals (/home/runner/work/monitor-oxc/monitor-oxc/node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:2375:3)
```
  • Loading branch information
Boshen committed Jul 22, 2024
1 parent 267f7c4 commit e33ec18
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 32 deletions.
58 changes: 28 additions & 30 deletions crates/oxc_minifier/src/compressor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,44 +208,42 @@ impl<'a> Compressor<'a> {
false
}

/// Transforms `typeof foo == "undefined"` into `foo === void 0`
/// Compress `typeof foo == "undefined"` into `typeof foo > "u"`
/// Enabled by `compress.typeofs`
fn compress_typeof_undefined(&self, expr: &mut BinaryExpression<'a>) {
if !self.options.typeofs {
return;
}
match expr.operator {
BinaryOperator::Equality | BinaryOperator::StrictEquality => {
let pair = self.commutative_pair(
(&expr.left, &expr.right),
|a| {
if a.is_specific_string_literal("undefined") {
return Some(());
}
None
},
|b| {
if let Expression::UnaryExpression(op) = b {
if op.operator == UnaryOperator::Typeof {
if let Expression::Identifier(id) = &op.argument {
return Some((*id).clone());
}
}
if !matches!(expr.operator, BinaryOperator::Equality | BinaryOperator::StrictEquality) {
return;
}
let pair = self.commutative_pair(
(&expr.left, &expr.right),
|a| a.is_specific_string_literal("undefined").then_some(()),
|b| {
if let Expression::UnaryExpression(op) = b {
if op.operator == UnaryOperator::Typeof {
if let Expression::Identifier(id) = &op.argument {
return Some((*id).clone());
}
None
},
);
if let Some((_void_exp, id_ref)) = pair {
let span = expr.span;
let left = self.ast.void_0();
let operator = BinaryOperator::StrictEquality;
let right = self.ast.expression_from_identifier_reference(id_ref);
let cmp = BinaryExpression { span, left, operator, right };
*expr = cmp;
}
}
}
_ => {}
None
},
);
let Some((_void_exp, id_ref)) = pair else {
return;
};
let argument = self.ast.expression_from_identifier_reference(id_ref);
let left = self.ast.unary_expression(SPAN, UnaryOperator::Typeof, argument);
let right = self.ast.string_literal(SPAN, "u");
let binary_expr = self.ast.binary_expression(
expr.span,
self.ast.expression_from_unary(left),
BinaryOperator::GreaterThan,
self.ast.expression_from_string_literal(right),
);
*expr = binary_expr;
}

fn commutative_pair<A, F, G, RetF: 'a, RetG: 'a>(
Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_minifier/tests/oxc/folding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ fn addition_folding() {

#[test]
fn typeof_folding() {
test("typeof x === 'undefined'", "void 0===x");
test("'undefined' === typeof x", "void 0===x");
test("typeof x === 'undefined'", "typeof x>'u'");
test("'undefined' === typeof x", "typeof x>'u'");
}

#[test]
Expand Down

0 comments on commit e33ec18

Please sign in to comment.