diff --git a/crates/oxc_minifier/src/compressor/mod.rs b/crates/oxc_minifier/src/compressor/mod.rs index 35b7e7a7ebbc7..f5b1d5c82167c 100644 --- a/crates/oxc_minifier/src/compressor/mod.rs +++ b/crates/oxc_minifier/src/compressor/mod.rs @@ -53,6 +53,16 @@ impl<'a> Compressor<'a> { self.ast.expression_binary(SPAN, left, BinaryOperator::Division, right) } + /// Test `Object.defineProperty(exports, ...)` + fn is_object_define_property_exports(expr: &Expression<'a>) -> bool { + let Expression::CallExpression(call_expr) = expr else { return false }; + let Some(Argument::Identifier(ident)) = call_expr.arguments.first() else { return false }; + if ident.name != "exports" { + return false; + } + call_expr.callee.is_specific_member_access("Object", "defineProperty") + } + /* Statements */ /// Remove block from single line blocks @@ -345,6 +355,10 @@ impl<'a> VisitMut<'a> for Compressor<'a> { } fn visit_expression(&mut self, expr: &mut Expression<'a>) { + // Bail cjs `Object.defineProperty(exports, ...)` + if Self::is_object_define_property_exports(expr) { + return; + } walk_mut::walk_expression(self, expr); self.compress_console(expr); self.folder.fold_expression(expr); diff --git a/crates/oxc_minifier/tests/mod.rs b/crates/oxc_minifier/tests/mod.rs index cc2bdd929bb3b..4eae2c93d970d 100644 --- a/crates/oxc_minifier/tests/mod.rs +++ b/crates/oxc_minifier/tests/mod.rs @@ -6,11 +6,20 @@ mod oxc; // mod terser; use oxc_allocator::Allocator; -use oxc_codegen::{CodegenOptions, WhitespaceRemover}; +use oxc_codegen::{CodeGenerator, CodegenOptions}; use oxc_minifier::{CompressOptions, Minifier, MinifierOptions}; use oxc_parser::Parser; use oxc_span::SourceType; +fn codegen(source_text: &str, source_type: SourceType) -> String { + let allocator = Allocator::default(); + let ret = Parser::new(&allocator, source_text, source_type).parse(); + CodeGenerator::new() + .with_options(CodegenOptions { single_quote: true }) + .build(&ret.program) + .source_text +} + pub(crate) fn minify( source_text: &str, source_type: SourceType, @@ -20,7 +29,7 @@ pub(crate) fn minify( let ret = Parser::new(&allocator, source_text, source_type).parse(); let program = allocator.alloc(ret.program); Minifier::new(options).build(&allocator, program); - WhitespaceRemover::new() + CodeGenerator::new() .with_options(CodegenOptions { single_quote: true }) .build(program) .source_text @@ -34,6 +43,7 @@ pub(crate) fn test(source_text: &str, expected: &str) { pub(crate) fn test_with_options(source_text: &str, expected: &str, options: MinifierOptions) { let source_type = SourceType::default(); let minified = minify(source_text, source_type, options); + let expected = codegen(expected, source_type); assert_eq!(expected, minified, "for source {source_text}"); } diff --git a/crates/oxc_minifier/tests/oxc/booleans.rs b/crates/oxc_minifier/tests/oxc/booleans.rs new file mode 100644 index 0000000000000..f5ddde9f5725f --- /dev/null +++ b/crates/oxc_minifier/tests/oxc/booleans.rs @@ -0,0 +1,15 @@ +use crate::test_same; + +#[test] +fn cjs() { + // Export is undefined when `enumerable` is "!0". + // https://github.com/nodejs/cjs-module-lexer/issues/64 + test_same( + "Object.defineProperty(exports, 'ConnectableObservable', { + enumerable: true, + get: function() { + return ConnectableObservable_1.ConnectableObservable; + } + });", + ); +} diff --git a/crates/oxc_minifier/tests/oxc/mod.rs b/crates/oxc_minifier/tests/oxc/mod.rs index 6542a6737ee32..54cd63b544eae 100644 --- a/crates/oxc_minifier/tests/oxc/mod.rs +++ b/crates/oxc_minifier/tests/oxc/mod.rs @@ -1,5 +1,6 @@ mod code_removal; mod folding; // mod precedence; +mod booleans; mod remove_dead_code; mod replace_global_defines; diff --git a/crates/oxc_minifier/tests/snapshots/addition_folding.snap b/crates/oxc_minifier/tests/snapshots/addition_folding.snap index 1bfeebf844e77..be1c5f34f36cd 100644 --- a/crates/oxc_minifier/tests/snapshots/addition_folding.snap +++ b/crates/oxc_minifier/tests/snapshots/addition_folding.snap @@ -6,82 +6,104 @@ expression: snapshot let x = 1 + 1 =================================== MINIFIED =================================== -let x=2 +let x = 2; + ==================================== SOURCE ==================================== function foo() { return 1 + 1; } =================================== MINIFIED =================================== -function foo(){return 2} +function foo() { + return 2; +} + ==================================== SOURCE ==================================== '' + true =================================== MINIFIED =================================== -;'true' +; +'true'; + ==================================== SOURCE ==================================== '' + false =================================== MINIFIED =================================== -;'false' +; +'false'; + ==================================== SOURCE ==================================== '' + null =================================== MINIFIED =================================== -;'null' +; +'null'; + ==================================== SOURCE ==================================== false + null =================================== MINIFIED =================================== -!1+null +!1 + null; + ==================================== SOURCE ==================================== '1' + '1' =================================== MINIFIED =================================== -;'11' +; +'11'; + ==================================== SOURCE ==================================== NaN + NaN =================================== MINIFIED =================================== -NaN+NaN +NaN + NaN; + ==================================== SOURCE ==================================== '' + NaN =================================== MINIFIED =================================== -;'NaN' +; +'NaN'; + ==================================== SOURCE ==================================== let x = 1; let y = x + 1 =================================== MINIFIED =================================== -let x=1,y=x+1 +let x = 1, y = x + 1; + ==================================== SOURCE ==================================== var x = 1; x + 1 === 2 =================================== MINIFIED =================================== -var x=1;x+1===2 +var x = 1; +x + 1 === 2; + ==================================== SOURCE ==================================== var y = 1; 1 + y === 2 =================================== MINIFIED =================================== -var y=1;1+y===2 +var y = 1; +1 + y === 2; + ==================================== SOURCE ==================================== null - Number(1) =================================== MINIFIED =================================== -null-Number(1) +null - Number(1); + ==================================== SOURCE ==================================== 1 + 1.0000001 =================================== MINIFIED =================================== -2.0000001000000003 +2.0000001000000003;