diff --git a/crates/swc/src/builder.rs b/crates/swc/src/builder.rs index dd3c965f4d5..48d3a9513fd 100644 --- a/crates/swc/src/builder.rs +++ b/crates/swc/src/builder.rs @@ -12,7 +12,7 @@ use swc_common::{ FileName, Mark, SourceMap, }; use swc_ecma_ast::{EsVersion, Module}; -use swc_ecma_minifier::option::MinifyOptions; +use swc_ecma_minifier::option::{terser::TerserTopLevelOptions, MinifyOptions}; use swc_ecma_parser::Syntax; use swc_ecma_transforms::{ compat, compat::es2022::private_in_object, fixer, helpers, hygiene, @@ -342,11 +342,16 @@ impl VisitMut for MinifierPass { fn visit_mut_module(&mut self, m: &mut Module) { if let Some(options) = &self.options { let opts = MinifyOptions { - compress: options - .compress - .clone() - .into_obj() - .map(|v| v.into_config(self.cm.clone())), + compress: options.compress.clone().into_obj().map(|mut v| { + if v.const_to_let.is_none() { + v.const_to_let = Some(true); + } + if v.toplevel.is_none() { + v.toplevel = Some(TerserTopLevelOptions::Bool(true)); + } + + v.into_config(self.cm.clone()) + }), mangle: options.mangle.clone().into_obj(), ..Default::default() }; diff --git a/crates/swc/src/config/mod.rs b/crates/swc/src/config/mod.rs index a3a86d768d8..6ab8448c2ab 100644 --- a/crates/swc/src/config/mod.rs +++ b/crates/swc/src/config/mod.rs @@ -800,7 +800,7 @@ pub struct JsMinifyOptions { #[serde(default)] pub safari10: bool, - #[serde(default)] + #[serde(default = "true_by_default")] pub toplevel: bool, #[serde(default)] diff --git a/crates/swc_ecma_minifier/src/option/mod.rs b/crates/swc_ecma_minifier/src/option/mod.rs index 0b41d0a499a..50fbf4af9ba 100644 --- a/crates/swc_ecma_minifier/src/option/mod.rs +++ b/crates/swc_ecma_minifier/src/option/mod.rs @@ -43,7 +43,7 @@ pub struct MangleOptions { #[serde(default, alias = "properties")] pub props: Option, - #[serde(default, alias = "toplevel")] + #[serde(default = "true_by_default", alias = "toplevel")] pub top_level: bool, #[serde(default, alias = "keep_classnames")] diff --git a/crates/swc_ecma_minifier/tests/compress.rs b/crates/swc_ecma_minifier/tests/compress.rs index be9e9f5b17b..dd86096fb7d 100644 --- a/crates/swc_ecma_minifier/tests/compress.rs +++ b/crates/swc_ecma_minifier/tests/compress.rs @@ -76,6 +76,12 @@ fn is_ignored(path: &Path) -> bool { false } +#[derive(Debug, Default, Clone, Deserialize)] +struct TopLevelOnly { + #[serde(default, alias = "toplevel")] + top_level: bool, +} + #[derive(Debug, Clone, Deserialize)] #[serde(deny_unknown_fields)] #[serde(untagged)] @@ -84,6 +90,20 @@ enum TestMangleOptions { Normal(MangleOptions), } +impl TestMangleOptions { + fn parse(s: &str) -> Self { + let top_level = serde_json::from_str::(s).unwrap_or_default(); + + let mut data = serde_json::from_str::(s).expect("failed to deserialize mangle.json"); + + if let TestMangleOptions::Normal(v) = &mut data { + v.top_level = top_level.top_level; + } + + data + } +} + #[derive(Debug, Clone, Deserialize)] struct TestOptions { #[serde(default)] @@ -184,7 +204,10 @@ fn run( mangle: mangle.and_then(|v| match v { TestMangleOptions::Bool(v) => { if v { - Some(Default::default()) + Some(MangleOptions { + top_level: false, + ..Default::default() + }) } else { None } @@ -338,8 +361,7 @@ fn fixture(input: PathBuf) { ); } - let mangle: Option = - mangle.map(|s| serde_json::from_str(&s).expect("failed to deserialize mangle.json")); + let mangle: Option = mangle.map(|s| TestMangleOptions::parse(&s)); let output = run(cm.clone(), &handler, &input, &config, mangle, false); let output_module = match output {