From 57ecc786a880561b8e82073ef7b71a6fd2aad5ac Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Wed, 16 Nov 2022 06:23:49 +0300 Subject: [PATCH 1/9] fix(html/minifier): bug with mangling --- crates/swc_html_minifier/src/lib.rs | 6 +-- .../output.min.html | 2 +- .../attribute/exportparts/output.min.html | 2 +- .../element/script-group/output.min.html | 41 ++++++++++--------- .../tests/fixture/element/script/input.html | 25 +++++++++++ .../fixture/element/script/output.min.html | 15 ++++--- .../tests/fixture/text/slot-3/output.min.html | 2 +- .../tests/fixture/text/slot/output.min.html | 2 +- 8 files changed, 61 insertions(+), 34 deletions(-) diff --git a/crates/swc_html_minifier/src/lib.rs b/crates/swc_html_minifier/src/lib.rs index bf6f343c271b..5490440c2e27 100644 --- a/crates/swc_html_minifier/src/lib.rs +++ b/crates/swc_html_minifier/src/lib.rs @@ -1969,11 +1969,7 @@ impl Minifier<'_> { match &self.options.minify_js { MinifyJsOption::Bool(_) => JsOptions { parser: JsParserOptions::default(), - minifier: swc_ecma_minifier::option::MinifyOptions { - compress: Some(swc_ecma_minifier::option::CompressOptions::default()), - mangle: Some(swc_ecma_minifier::option::MangleOptions::default()), - ..Default::default() - }, + minifier: swc_ecma_minifier::option::MinifyOptions::default(), codegen: swc_ecma_codegen::Config::default(), }, MinifyJsOption::Options(js_options) => *js_options.clone(), diff --git a/crates/swc_html_minifier/tests/fixture/attribute/disabled-normalize_attributes/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/disabled-normalize_attributes/output.min.html index 6d7d554503bf..b4c123c2b3cb 100644 --- a/crates/swc_html_minifier/tests/fixture/attribute/disabled-normalize_attributes/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/attribute/disabled-normalize_attributes/output.min.html @@ -1,2 +1,2 @@ Document -
\ No newline at end of file +
\ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/attribute/exportparts/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/exportparts/output.min.html index 25d0ef832cf3..f817e875050b 100644 --- a/crates/swc_html_minifier/tests/fixture/attribute/exportparts/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/attribute/exportparts/output.min.html @@ -19,4 +19,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html b/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html index 761bfadc4b90..89f32c92c8f5 100644 --- a/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html @@ -1,33 +1,33 @@ Document
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
@@ -35,26 +35,26 @@
breaker
- +
breaker
- +
breaker
breaker
- +
breaker
- +
breaker
breaker
- +
breaker
@@ -63,31 +63,31 @@
breaker
- +
breaker
breaker
- +
breaker
breaker
- +
breaker
- +
breaker
- +
breaker
breaker
- +
breaker
@@ -109,4 +109,5 @@ -
breaker
\ No newline at end of file +
breaker
+ \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/element/script/input.html b/crates/swc_html_minifier/tests/fixture/element/script/input.html index 85d4becb9c3e..1f3a78154c8e 100644 --- a/crates/swc_html_minifier/tests/fixture/element/script/input.html +++ b/crates/swc_html_minifier/tests/fixture/element/script/input.html @@ -186,5 +186,30 @@

Party coffee cake recipe

test
+
topLevel - script
+ +
topLevel - module
+ + diff --git a/crates/swc_html_minifier/tests/fixture/element/script/output.min.html b/crates/swc_html_minifier/tests/fixture/element/script/output.min.html index ce945121482d..417e9df5121e 100644 --- a/crates/swc_html_minifier/tests/fixture/element/script/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/element/script/output.min.html @@ -19,7 +19,7 @@

Party coffee cake recipe

+

Party coffee cake recipe

by Mary Stone, 2018-03-10

@@ -42,7 +42,7 @@ - + @@ -54,5 +54,10 @@ alert('test') - -
test
\ No newline at end of file + +
test
+ +
topLevel - script
+ +
topLevel - module
+ \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/text/slot-3/output.min.html b/crates/swc_html_minifier/tests/fixture/text/slot-3/output.min.html index 4e721de55e94..4446bcc1c37b 100644 --- a/crates/swc_html_minifier/tests/fixture/text/slot-3/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/text/slot-3/output.min.html @@ -1 +1 @@ -element-details - web component using <template> and <slot>

element-details - web component using <template> and <slot>

test foo \ No newline at end of file +element-details - web component using <template> and <slot>

element-details - web component using <template> and <slot>

test foo \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/text/slot/output.min.html b/crates/swc_html_minifier/tests/fixture/text/slot/output.min.html index 877312d0a282..bbaaac670339 100644 --- a/crates/swc_html_minifier/tests/fixture/text/slot/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/text/slot/output.min.html @@ -1 +1 @@ -element-details - web component using <template> and <slot>

element-details - web component using <template> and <slot>

1 2 3 4 \ No newline at end of file +element-details - web component using <template> and <slot>

element-details - web component using <template> and <slot>

1 2 3 4 \ No newline at end of file From 119baad9a4653d171d8e9c44371a60cca8eb953d Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Thu, 17 Nov 2022 03:37:51 +0300 Subject: [PATCH 2/9] fix: use valid default options --- crates/swc_html_minifier/src/lib.rs | 6 ++- .../output.min.html | 2 +- .../attribute/exportparts/output.min.html | 2 +- .../element/script-group/output.min.html | 41 ++++++++++--------- .../fixture/element/script/output.min.html | 12 +++--- .../tests/fixture/text/slot-3/output.min.html | 2 +- .../tests/fixture/text/slot/output.min.html | 2 +- 7 files changed, 36 insertions(+), 31 deletions(-) diff --git a/crates/swc_html_minifier/src/lib.rs b/crates/swc_html_minifier/src/lib.rs index 5490440c2e27..bf6f343c271b 100644 --- a/crates/swc_html_minifier/src/lib.rs +++ b/crates/swc_html_minifier/src/lib.rs @@ -1969,7 +1969,11 @@ impl Minifier<'_> { match &self.options.minify_js { MinifyJsOption::Bool(_) => JsOptions { parser: JsParserOptions::default(), - minifier: swc_ecma_minifier::option::MinifyOptions::default(), + minifier: swc_ecma_minifier::option::MinifyOptions { + compress: Some(swc_ecma_minifier::option::CompressOptions::default()), + mangle: Some(swc_ecma_minifier::option::MangleOptions::default()), + ..Default::default() + }, codegen: swc_ecma_codegen::Config::default(), }, MinifyJsOption::Options(js_options) => *js_options.clone(), diff --git a/crates/swc_html_minifier/tests/fixture/attribute/disabled-normalize_attributes/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/disabled-normalize_attributes/output.min.html index b4c123c2b3cb..6d7d554503bf 100644 --- a/crates/swc_html_minifier/tests/fixture/attribute/disabled-normalize_attributes/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/attribute/disabled-normalize_attributes/output.min.html @@ -1,2 +1,2 @@ Document -
\ No newline at end of file +
\ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/attribute/exportparts/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/exportparts/output.min.html index f817e875050b..25d0ef832cf3 100644 --- a/crates/swc_html_minifier/tests/fixture/attribute/exportparts/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/attribute/exportparts/output.min.html @@ -19,4 +19,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html b/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html index 89f32c92c8f5..31a0f76a80dd 100644 --- a/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html @@ -1,33 +1,33 @@ Document
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
@@ -35,26 +35,26 @@
breaker
- +
breaker
- +
breaker
breaker
- +
breaker
- +
breaker
breaker
- +
breaker
@@ -63,31 +63,31 @@
breaker
- +
breaker
breaker
- +
breaker
breaker
- +
breaker
- +
breaker
- +
breaker
breaker
- +
breaker
@@ -110,4 +110,5 @@
breaker
- \ No newline at end of file + + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/element/script/output.min.html b/crates/swc_html_minifier/tests/fixture/element/script/output.min.html index 417e9df5121e..9e392c4202f7 100644 --- a/crates/swc_html_minifier/tests/fixture/element/script/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/element/script/output.min.html @@ -19,7 +19,7 @@

Party coffee cake recipe

+

Party coffee cake recipe

by Mary Stone, 2018-03-10

@@ -42,7 +42,7 @@ - + @@ -54,10 +54,10 @@ alert('test') - +
test
topLevel - script
- +
topLevel - module
- \ No newline at end of file + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/text/slot-3/output.min.html b/crates/swc_html_minifier/tests/fixture/text/slot-3/output.min.html index 4446bcc1c37b..4e721de55e94 100644 --- a/crates/swc_html_minifier/tests/fixture/text/slot-3/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/text/slot-3/output.min.html @@ -1 +1 @@ -element-details - web component using <template> and <slot>

element-details - web component using <template> and <slot>

test foo \ No newline at end of file +element-details - web component using <template> and <slot>

element-details - web component using <template> and <slot>

test foo \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/text/slot/output.min.html b/crates/swc_html_minifier/tests/fixture/text/slot/output.min.html index bbaaac670339..877312d0a282 100644 --- a/crates/swc_html_minifier/tests/fixture/text/slot/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/text/slot/output.min.html @@ -1 +1 @@ -element-details - web component using <template> and <slot>

element-details - web component using <template> and <slot>

1 2 3 4 \ No newline at end of file +element-details - web component using <template> and <slot>

element-details - web component using <template> and <slot>

1 2 3 4 \ No newline at end of file From 443493a6bd5a580dcb99070ad9bfedfb042e3926 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Thu, 17 Nov 2022 04:37:36 +0300 Subject: [PATCH 3/9] fix(ecma/minifier): compress bug for script --- crates/swc_ecma_minifier/src/compress/mod.rs | 4 + crates/swc_ecma_minifier/src/debug.rs | 93 ++++++++++++++++++- crates/swc_ecma_minifier/src/util/unit.rs | 37 +++++++- .../javascript-prefix/output.min.html | 4 +- .../attribute/script-type/output.min.html | 4 +- .../element/script-group/output.min.html | 13 +-- .../fixture/element/script/output.min.html | 6 +- .../output.min.html | 2 +- .../collapse-whitespace-smart/output.min.html | 2 +- .../tests/fixture/text/slot-3/output.min.html | 2 +- .../tests/fixture/text/slot/output.min.html | 2 +- 11 files changed, 150 insertions(+), 19 deletions(-) diff --git a/crates/swc_ecma_minifier/src/compress/mod.rs b/crates/swc_ecma_minifier/src/compress/mod.rs index 62e8586c9609..c5c153c639a3 100644 --- a/crates/swc_ecma_minifier/src/compress/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/mod.rs @@ -340,6 +340,10 @@ where self.optimize_unit_repeatedly(n); } + fn visit_mut_script(&mut self, n: &mut Script) { + self.optimize_unit_repeatedly(n); + } + fn visit_mut_module_items(&mut self, stmts: &mut Vec) { stmts.retain(|stmt| match stmt { ModuleItem::Stmt(Stmt::Empty(..)) => false, diff --git a/crates/swc_ecma_minifier/src/debug.rs b/crates/swc_ecma_minifier/src/debug.rs index 5b2bd547edad..8decb9502cb2 100644 --- a/crates/swc_ecma_minifier/src/debug.rs +++ b/crates/swc_ecma_minifier/src/debug.rs @@ -66,7 +66,7 @@ where /// /// If the cargo feature `debug` is disabled or the environment variable /// `SWC_RUN` is not `1`, this function is noop. -pub(crate) fn invoke(module: &Module) { +pub(crate) fn invoke_module(module: &Module) { debug_assert_valid(module); let _noop_sub = tracing::subscriber::set_default(tracing::subscriber::NoSubscriber::default()); @@ -153,3 +153,94 @@ pub(crate) fn invoke(module: &Module) { ) } } + +/// Invokes code using node.js. +/// +/// If the cargo feature `debug` is disabled or the environment variable +/// `SWC_RUN` is not `1`, this function is noop. +pub(crate) fn invoke_script(script: &Script) { + debug_assert_valid(script); + + let _noop_sub = tracing::subscriber::set_default(tracing::subscriber::NoSubscriber::default()); + + let should_run = + cfg!(debug_assertions) && cfg!(feature = "debug") && option_env!("SWC_RUN") == Some("1"); + let should_check = cfg!(debug_assertions) && option_env!("SWC_CHECK") == Some("1"); + + if !should_run && !should_check { + return; + } + + let script = script + .clone() + .fold_with(&mut hygiene()) + .fold_with(&mut fixer(None)); + let script = drop_span(script); + + let mut buf = vec![]; + let cm = Lrc::new(SourceMap::default()); + + { + let mut emitter = Emitter { + cfg: Default::default(), + cm: cm.clone(), + comments: None, + wr: Box::new(JsWriter::new(cm, "\n", &mut buf, None)), + }; + + emitter.emit_script(&script).unwrap(); + } + + let code = String::from_utf8(buf).unwrap(); + + debug!("Validating with node.js:\n{}", code); + + if should_check { + let mut child = Command::new("node") + .arg("-") + .arg("--check") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .expect("failed to spawn node"); + + { + let child_stdin = child.stdin.as_mut().unwrap(); + child_stdin + .write_all(code.as_bytes()) + .expect("failed to write"); + } + + let output = child.wait_with_output().expect("failed to check syntax"); + + if !output.status.success() { + panic!( + "[SWC_CHECK] Failed to validate code:\n{}\n===== ===== ===== ===== =====\n{}\n{}", + code, + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr), + ); + } + } else { + let output = Command::new("node") + .arg("-e") + .arg(&code) + .output() + .expect("[SWC_RUN] failed to validate code using `node`"); + if !output.status.success() { + panic!( + "[SWC_RUN] Failed to validate code:\n{}\n===== ===== ===== ===== =====\n{}\n{}", + code, + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr), + ); + } + + tracing::info!( + "[SWC_RUN]\n{}\n{}", + code, + String::from_utf8_lossy(&output.stdout) + ) + } +} diff --git a/crates/swc_ecma_minifier/src/util/unit.rs b/crates/swc_ecma_minifier/src/util/unit.rs index f50be0a4be74..107b01ac1f56 100644 --- a/crates/swc_ecma_minifier/src/util/unit.rs +++ b/crates/swc_ecma_minifier/src/util/unit.rs @@ -69,7 +69,42 @@ impl CompileUnit for Module { { self.visit_mut_with(&mut *visitor); - crate::debug::invoke(self); + crate::debug::invoke_module(self); + } + + fn remove_mark(&mut self) -> Mark { + Mark::root() + } +} + +impl CompileUnit for Script { + fn is_module() -> bool { + false + } + + fn force_dump(&self) -> String { + let _noop_sub = + tracing::subscriber::set_default(tracing::subscriber::NoSubscriber::default()); + + dump( + &self + .clone() + .fold_with(&mut fixer(None)) + .fold_with(&mut hygiene()) + .fold_with(&mut as_folder(DropSpan { + preserve_ctxt: false, + })), + true, + ) + } + + fn apply(&mut self, visitor: &mut V) + where + V: VisitMut, + { + self.visit_mut_with(&mut *visitor); + + crate::debug::invoke_script(self); } fn remove_mark(&mut self) -> Mark { diff --git a/crates/swc_html_minifier/tests/fixture/attribute/javascript-prefix/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/javascript-prefix/output.min.html index 176f7a3cd6d7..408869084607 100644 --- a/crates/swc_html_minifier/tests/fixture/attribute/javascript-prefix/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/attribute/javascript-prefix/output.min.html @@ -8,5 +8,5 @@
test
- Click me - Click me \ No newline at end of file + Click me + Click me \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/attribute/script-type/output.min.html b/crates/swc_html_minifier/tests/fixture/attribute/script-type/output.min.html index 0827cecf8365..560c6b776f6a 100644 --- a/crates/swc_html_minifier/tests/fixture/attribute/script-type/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/attribute/script-type/output.min.html @@ -1,6 +1,6 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html b/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html index 31a0f76a80dd..5545e7bbbee3 100644 --- a/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html @@ -23,7 +23,7 @@
breaker
- +
breaker
@@ -75,19 +75,19 @@
breaker
- +
breaker
- +
breaker
- +
breaker
breaker
- +
breaker
@@ -111,4 +111,5 @@
breaker
- \ No newline at end of file + + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/element/script/output.min.html b/crates/swc_html_minifier/tests/fixture/element/script/output.min.html index 9e392c4202f7..a3da4cfab0ae 100644 --- a/crates/swc_html_minifier/tests/fixture/element/script/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/element/script/output.min.html @@ -27,7 +27,7 @@ var q = "WRONG" ; -

Party coffee cake recipe

+

Party coffee cake recipe

by Mary Stone, 2018-03-10

@@ -54,10 +54,10 @@ alert('test') - +
test
topLevel - script
- +
topLevel - module
\ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/text/collapse-whitespace-advanced-conservative/output.min.html b/crates/swc_html_minifier/tests/fixture/text/collapse-whitespace-advanced-conservative/output.min.html index 40772446a8fc..1b4487d9c299 100644 --- a/crates/swc_html_minifier/tests/fixture/text/collapse-whitespace-advanced-conservative/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/text/collapse-whitespace-advanced-conservative/output.min.html @@ -29,4 +29,4 @@ foo baz -
a c
Empty
a b
a b c d
text
text text
test
test test
\ No newline at end of file +
a c
Empty
a b
a b c d
text
text text
test
test test
\ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/text/collapse-whitespace-smart/output.min.html b/crates/swc_html_minifier/tests/fixture/text/collapse-whitespace-smart/output.min.html index 91a99a487500..c7ef9c917cf7 100644 --- a/crates/swc_html_minifier/tests/fixture/text/collapse-whitespace-smart/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/text/collapse-whitespace-smart/output.min.html @@ -29,4 +29,4 @@ foo baz -
a c
Empty
a b
a b c d
text
text text
test test
test testtest
test test
test test
test test
test test
testtest test
test
test test
test
test
test test test test test This is bold and red This is bold and red testtestThis is bold and red This is bold and red
test a b test test a b test test a b test
test test
a
\ No newline at end of file +
a c
Empty
a b
a b c d
text
text text
test test
test testtest
test test
test test
test test
test test
testtest test
test
test test
test
test
test test test test test This is bold and red This is bold and red testtestThis is bold and red This is bold and red
test a b test test a b test test a b test
test test
a
\ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/text/slot-3/output.min.html b/crates/swc_html_minifier/tests/fixture/text/slot-3/output.min.html index 4e721de55e94..c1f13e419e9a 100644 --- a/crates/swc_html_minifier/tests/fixture/text/slot-3/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/text/slot-3/output.min.html @@ -1 +1 @@ -element-details - web component using <template> and <slot>

element-details - web component using <template> and <slot>

test foo \ No newline at end of file +element-details - web component using <template> and <slot>

element-details - web component using <template> and <slot>

test foo \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/text/slot/output.min.html b/crates/swc_html_minifier/tests/fixture/text/slot/output.min.html index 877312d0a282..4a2f5c3a928b 100644 --- a/crates/swc_html_minifier/tests/fixture/text/slot/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/text/slot/output.min.html @@ -1 +1 @@ -element-details - web component using <template> and <slot>

element-details - web component using <template> and <slot>

1 2 3 4 \ No newline at end of file +element-details - web component using <template> and <slot>

element-details - web component using <template> and <slot>

1 2 3 4 \ No newline at end of file From d2fad55f83a5a067262c46796589889e00687a87 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Thu, 17 Nov 2022 04:40:40 +0300 Subject: [PATCH 4/9] fix(ecma/minifier): handle `script` in bundle mode --- crates/swc_ecma_minifier/src/metadata/mod.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/crates/swc_ecma_minifier/src/metadata/mod.rs b/crates/swc_ecma_minifier/src/metadata/mod.rs index 9f72e4105a45..80c6413f7b28 100644 --- a/crates/swc_ecma_minifier/src/metadata/mod.rs +++ b/crates/swc_ecma_minifier/src/metadata/mod.rs @@ -191,12 +191,23 @@ impl VisitMut for InfoMarker<'_> { fn visit_mut_lit(&mut self, _: &mut Lit) {} - fn visit_mut_module(&mut self, m: &mut Module) { - m.visit_mut_children_with(self); + fn visit_mut_module(&mut self, n: &mut Module) { + n.visit_mut_children_with(self); + + if self.state.is_bundle { + tracing::info!("Running minifier in the bundle mode"); + n.span = n.span.apply_mark(self.marks.bundle_of_standalone); + } else { + tracing::info!("Running minifier in the normal mode"); + } + } + + fn visit_mut_script(&mut self, n: &mut Script) { + n.visit_mut_children_with(self); if self.state.is_bundle { tracing::info!("Running minifier in the bundle mode"); - m.span = m.span.apply_mark(self.marks.bundle_of_standalone); + n.span = n.span.apply_mark(self.marks.bundle_of_standalone); } else { tracing::info!("Running minifier in the normal mode"); } From 00d7695d0365e327f554b118a49d77e9761947b7 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Thu, 17 Nov 2022 04:43:31 +0300 Subject: [PATCH 5/9] refactor(ecma/minifier): code --- crates/swc_ecma_minifier/src/analyzer/mod.rs | 8 ++++++++ crates/swc_ecma_minifier/src/compress/mod.rs | 4 ++-- crates/swc_ecma_minifier/src/metadata/mod.rs | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/crates/swc_ecma_minifier/src/analyzer/mod.rs b/crates/swc_ecma_minifier/src/analyzer/mod.rs index c9b4447b6da0..c3aa336dc78b 100644 --- a/crates/swc_ecma_minifier/src/analyzer/mod.rs +++ b/crates/swc_ecma_minifier/src/analyzer/mod.rs @@ -1150,6 +1150,14 @@ where n.visit_children_with(&mut *self.with_ctx(ctx)) } + fn visit_script(&mut self, n: &Script) { + let ctx = Ctx { + skip_standalone: true, + ..self.ctx + }; + n.visit_children_with(&mut *self.with_ctx(ctx)) + } + fn visit_named_export(&mut self, n: &NamedExport) { if n.src.is_some() { return; diff --git a/crates/swc_ecma_minifier/src/compress/mod.rs b/crates/swc_ecma_minifier/src/compress/mod.rs index c5c153c639a3..553fe940ef27 100644 --- a/crates/swc_ecma_minifier/src/compress/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/mod.rs @@ -336,11 +336,11 @@ where { noop_visit_mut_type!(); - fn visit_mut_module(&mut self, n: &mut Module) { + fn visit_mut_script(&mut self, n: &mut Script) { self.optimize_unit_repeatedly(n); } - fn visit_mut_script(&mut self, n: &mut Script) { + fn visit_mut_module(&mut self, n: &mut Module) { self.optimize_unit_repeatedly(n); } diff --git a/crates/swc_ecma_minifier/src/metadata/mod.rs b/crates/swc_ecma_minifier/src/metadata/mod.rs index 80c6413f7b28..5feaa1cede55 100644 --- a/crates/swc_ecma_minifier/src/metadata/mod.rs +++ b/crates/swc_ecma_minifier/src/metadata/mod.rs @@ -191,7 +191,7 @@ impl VisitMut for InfoMarker<'_> { fn visit_mut_lit(&mut self, _: &mut Lit) {} - fn visit_mut_module(&mut self, n: &mut Module) { + fn visit_mut_script(&mut self, n: &mut Script) { n.visit_mut_children_with(self); if self.state.is_bundle { @@ -202,7 +202,7 @@ impl VisitMut for InfoMarker<'_> { } } - fn visit_mut_script(&mut self, n: &mut Script) { + fn visit_mut_module(&mut self, n: &mut Module) { n.visit_mut_children_with(self); if self.state.is_bundle { From 8eecdf0b5934c07e5276c41a37ea9c9acc766ce6 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Thu, 17 Nov 2022 05:03:57 +0300 Subject: [PATCH 6/9] refactor(ecma/minifier): code --- crates/swc_ecma_minifier/src/lib.rs | 42 +++++++++---------- .../src/rename/mod.rs | 9 ++-- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/crates/swc_ecma_minifier/src/lib.rs b/crates/swc_ecma_minifier/src/lib.rs index 427192037f8f..f0418bbf9bd3 100644 --- a/crates/swc_ecma_minifier/src/lib.rs +++ b/crates/swc_ecma_minifier/src/lib.rs @@ -87,7 +87,7 @@ pub(crate) static HEAVY_TASK_PARALLELS: Lazy = Lazy::new(|| *CPU_COUNT * pub(crate) static LIGHT_TASK_PARALLELS: Lazy = Lazy::new(|| *CPU_COUNT * 100); pub fn optimize( - mut m: Program, + mut n: Program, _cm: Lrc, comments: Option<&dyn Comments>, mut timings: Option<&mut Timings>, @@ -99,7 +99,7 @@ pub fn optimize( let mut marks = Marks::new(); marks.unresolved_mark = extra.unresolved_mark; - debug_assert_valid(&m); + debug_assert_valid(&n); if let Some(defs) = options.compress.as_ref().map(|c| &c.global_defs) { let _timer = timer!("inline global defs"); @@ -111,7 +111,7 @@ pub fn optimize( if !defs.is_empty() { let defs = defs.iter().map(|(k, v)| (k.clone(), v.clone())).collect(); - m.visit_mut_with(&mut global_defs::globals_defs( + n.visit_mut_with(&mut global_defs::globals_defs( defs, extra.unresolved_mark, extra.top_level_mark, @@ -119,7 +119,7 @@ pub fn optimize( } } - let module_info = match &m { + let module_info = match &n { Program::Script(_) => ModuleInfo::default(), Program::Module(m) => ModuleInfo { blackbox_imports: m @@ -162,20 +162,20 @@ pub fn optimize( if let Some(_options) = &options.compress { let _timer = timer!("precompress"); - m.visit_mut_with(&mut precompress_optimizer()); - debug_assert_valid(&m); + n.visit_mut_with(&mut precompress_optimizer()); + debug_assert_valid(&n); } if options.compress.is_some() { - m.visit_mut_with(&mut info_marker( + n.visit_mut_with(&mut info_marker( options.compress.as_ref(), comments, marks, extra.unresolved_mark, )); - debug_assert_valid(&m); + debug_assert_valid(&n); } - m.visit_mut_with(&mut unique_scope()); + n.visit_mut_with(&mut unique_scope()); if options.wrap { // TODO: wrap_common_js @@ -191,8 +191,8 @@ pub fn optimize( } if let Some(options) = &options.compress { if options.unused { - perform_dce(&mut m, options, extra); - debug_assert_valid(&m); + perform_dce(&mut n, options, extra); + debug_assert_valid(&n); } } @@ -207,7 +207,7 @@ pub fn optimize( if options.rename && DISABLE_BUGGY_PASSES { // toplevel.figure_out_scope(options.mangle); // TODO: Pass `options.mangle` to name expander. - m.visit_mut_with(&mut name_expander()); + n.visit_mut_with(&mut name_expander()); } if let Some(ref mut t) = timings { @@ -217,14 +217,14 @@ pub fn optimize( { let _timer = timer!("compress ast"); - m.visit_mut_with(&mut compressor(&module_info, marks, options, &Minification)) + n.visit_mut_with(&mut compressor(&module_info, marks, options, &Minification)) } // Again, we don't need to validate ast let _timer = timer!("postcompress"); - m.visit_mut_with(&mut postcompress_optimizer(options)); + n.visit_mut_with(&mut postcompress_optimizer(options)); let mut pass = 0; loop { @@ -241,7 +241,7 @@ pub fn optimize( debug_infinite_loop: false, }, ); - m.visit_mut_with(&mut v); + n.visit_mut_with(&mut v); if !v.changed() || options.passes <= pass { break; } @@ -263,30 +263,30 @@ pub fn optimize( let _timer = timer!("mangle names"); // TODO: base54.reset(); - let preserved = idents_to_preserve(mangle.clone(), &m); + let preserved = idents_to_preserve(mangle.clone(), &n); let chars = CharFreq::compute( - &m, + &n, &preserved, SyntaxContext::empty().apply_mark(marks.unresolved_mark), ) .compile(); - m.visit_mut_with(&mut name_mangler(mangle.clone(), preserved, chars)); + n.visit_mut_with(&mut name_mangler(mangle.clone(), preserved, chars)); if let Some(property_mangle_options) = &mangle.props { - mangle_properties(&mut m, &module_info, property_mangle_options.clone(), chars); + mangle_properties(&mut n, &module_info, property_mangle_options.clone(), chars); } } - m.visit_mut_with(&mut merge_exports()); + n.visit_mut_with(&mut merge_exports()); if let Some(ref mut t) = timings { t.section("hygiene"); t.end_section(); } - m + n } fn perform_dce(m: &mut Program, options: &CompressOptions, extra: &ExtraOptions) { diff --git a/crates/swc_ecma_transforms_base/src/rename/mod.rs b/crates/swc_ecma_transforms_base/src/rename/mod.rs index e1686a445d5d..19bd3019b5e8 100644 --- a/crates/swc_ecma_transforms_base/src/rename/mod.rs +++ b/crates/swc_ecma_transforms_base/src/rename/mod.rs @@ -242,12 +242,11 @@ where if contains_eval(s, true) { s.visit_mut_children_with(self); - return; - } - - let map = self.get_map(s, false, true); + } else { + let map = self.get_map(s, false, true); - s.visit_mut_with(&mut rename_with_config(&map, self.config.clone())); + s.visit_mut_with(&mut rename_with_config(&map, self.config.clone())); + } } } From 79345a314dc87197621fa759708764144884bae0 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Thu, 17 Nov 2022 05:13:08 +0300 Subject: [PATCH 7/9] test: fix --- .../tests/fixture/element/script-group/output.min.html | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html b/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html index 5545e7bbbee3..426c5d0614c9 100644 --- a/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html @@ -90,7 +90,7 @@
breaker
- +
breaker
@@ -109,7 +109,4 @@ -
breaker
- - - \ No newline at end of file +
breaker
\ No newline at end of file From 9750befcf2ebb9e7338a7c1bb7eb64dfe995fd35 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Thu, 17 Nov 2022 05:26:00 +0300 Subject: [PATCH 8/9] fix(ecma/minifier): respect `topLevel` for `script` --- .../src/pass/mangle_names/preserver.rs | 7 ++++ .../element/script-group/output.min.html | 40 +++++++++---------- .../fixture/element/script/output.min.html | 6 +-- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/crates/swc_ecma_minifier/src/pass/mangle_names/preserver.rs b/crates/swc_ecma_minifier/src/pass/mangle_names/preserver.rs index 283299c0ecd1..08a35f2d2809 100644 --- a/crates/swc_ecma_minifier/src/pass/mangle_names/preserver.rs +++ b/crates/swc_ecma_minifier/src/pass/mangle_names/preserver.rs @@ -121,6 +121,13 @@ impl Visit for Preserver { fn visit_ident(&mut self, _: &Ident) {} + fn visit_script(&mut self, n: &Script) { + for n in n.body.iter() { + self.in_top_level = true; + n.visit_with(self); + } + } + fn visit_module_items(&mut self, n: &[ModuleItem]) { for n in n { self.in_top_level = true; diff --git a/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html b/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html index 426c5d0614c9..6da26e2abce7 100644 --- a/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/element/script-group/output.min.html @@ -1,33 +1,33 @@ Document
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
- +
breaker
@@ -35,26 +35,26 @@
breaker
- +
breaker
- +
breaker
breaker
- +
breaker
- +
breaker
breaker
- +
breaker
@@ -63,34 +63,34 @@
breaker
- +
breaker
breaker
- +
breaker
breaker
- +
breaker
- +
breaker
- +
breaker
breaker
- +
breaker
- +
breaker
diff --git a/crates/swc_html_minifier/tests/fixture/element/script/output.min.html b/crates/swc_html_minifier/tests/fixture/element/script/output.min.html index a3da4cfab0ae..0b9477f4835f 100644 --- a/crates/swc_html_minifier/tests/fixture/element/script/output.min.html +++ b/crates/swc_html_minifier/tests/fixture/element/script/output.min.html @@ -19,7 +19,7 @@

Party coffee cake recipe

+

Party coffee cake recipe

by Mary Stone, 2018-03-10

@@ -58,6 +58,6 @@
test
topLevel - script
- +
topLevel - module
\ No newline at end of file From 2c321170c57e0464e8a6db84078145aff70fadbb Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Thu, 17 Nov 2022 05:30:39 +0300 Subject: [PATCH 9/9] test: more --- .../element/script-options-2/config.json | 17 +++++++++ .../element/script-options-2/input.html | 36 +++++++++++++++++++ .../element/script-options-2/output.min.html | 5 +++ .../tests/fixture/element/script/input.html | 2 ++ 4 files changed, 60 insertions(+) create mode 100644 crates/swc_html_minifier/tests/fixture/element/script-options-2/config.json create mode 100644 crates/swc_html_minifier/tests/fixture/element/script-options-2/input.html create mode 100644 crates/swc_html_minifier/tests/fixture/element/script-options-2/output.min.html diff --git a/crates/swc_html_minifier/tests/fixture/element/script-options-2/config.json b/crates/swc_html_minifier/tests/fixture/element/script-options-2/config.json new file mode 100644 index 000000000000..206c9ac16fa8 --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/element/script-options-2/config.json @@ -0,0 +1,17 @@ +{ + "minifyJs": { + "parser": { + "comments": true, + "syntax": "ecmascript", + "target": "es2022" + }, + "minifier": { + "mangle": { + "topLevel": true + } + }, + "codegen": { + "asciiOnly": true + } + } +} diff --git a/crates/swc_html_minifier/tests/fixture/element/script-options-2/input.html b/crates/swc_html_minifier/tests/fixture/element/script-options-2/input.html new file mode 100644 index 000000000000..9b1789da264e --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/element/script-options-2/input.html @@ -0,0 +1,36 @@ + + + + Document + + + +
Script:
+ + +
Module:
+ + + \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/element/script-options-2/output.min.html b/crates/swc_html_minifier/tests/fixture/element/script-options-2/output.min.html new file mode 100644 index 000000000000..6d41c04d5b3d --- /dev/null +++ b/crates/swc_html_minifier/tests/fixture/element/script-options-2/output.min.html @@ -0,0 +1,5 @@ +Document
Script:
+ + +
Module:
+ \ No newline at end of file diff --git a/crates/swc_html_minifier/tests/fixture/element/script/input.html b/crates/swc_html_minifier/tests/fixture/element/script/input.html index 1f3a78154c8e..8ebf37e3d74a 100644 --- a/crates/swc_html_minifier/tests/fixture/element/script/input.html +++ b/crates/swc_html_minifier/tests/fixture/element/script/input.html @@ -188,6 +188,7 @@

Party coffee cake recipe

topLevel - script
topLevel - module