diff --git a/.changeset/spicy-hairs-run.md b/.changeset/spicy-hairs-run.md new file mode 100644 index 00000000000..cc31aec11e1 --- /dev/null +++ b/.changeset/spicy-hairs-run.md @@ -0,0 +1,7 @@ +--- +swc: patch +swc_core: patch +swc_ecma_lints: patch +--- + +feat(es): Add options to disable all `esnext` transforms and lints diff --git a/crates/swc/src/builder.rs b/crates/swc/src/builder.rs index 1f01c7fce18..6dbc76db89b 100644 --- a/crates/swc/src/builder.rs +++ b/crates/swc/src/builder.rs @@ -506,6 +506,6 @@ impl VisitMut for MinifierPass<'_> { } } -fn should_enable(target: EsVersion, feature: EsVersion) -> bool { +pub(crate) fn should_enable(target: EsVersion, feature: EsVersion) -> bool { target < feature } diff --git a/crates/swc/src/config/mod.rs b/crates/swc/src/config/mod.rs index d063549541f..7154208ba94 100644 --- a/crates/swc/src/config/mod.rs +++ b/crates/swc/src/config/mod.rs @@ -74,7 +74,9 @@ use swc_ecma_visit::{Fold, VisitMutWith}; pub use crate::plugin::PluginConfig; use crate::{ - builder::PassBuilder, dropped_comments_preserver::dropped_comments_preserver, SwcImportResolver, + builder::{should_enable, PassBuilder}, + dropped_comments_preserver::dropped_comments_preserver, + SwcImportResolver, }; #[cfg(test)] @@ -579,6 +581,7 @@ impl Options { ); let keep_import_attributes = experimental.keep_import_attributes.into_bool(); + let disable_all_lints = experimental.disable_all_lints.into_bool(); #[cfg(feature = "plugin")] let plugin_transforms = { @@ -697,23 +700,33 @@ impl Options { }; Box::new(chain!( - lint_to_fold(swc_ecma_lints::rules::all(LintParams { - program: &program, - lint_config: &lints, - top_level_ctxt, - unresolved_ctxt, - es_version, - source_map: cm.clone(), - })), + Optional::new( + lint_to_fold(swc_ecma_lints::rules::all(LintParams { + program: &program, + lint_config: &lints, + top_level_ctxt, + unresolved_ctxt, + es_version, + source_map: cm.clone(), + })), + !disable_all_lints + ), // Decorators may use type information - Optional::new(decorator_pass, syntax.decorators()), + Optional::new( + decorator_pass, + should_enable(es_version, EsVersion::EsNext) && syntax.decorators() + ), Optional::new( explicit_resource_management(), - syntax.explicit_resource_management() + should_enable(es_version, EsVersion::EsNext) + && syntax.explicit_resource_management() ), // The transform strips import assertions, so it's only enabled if // keep_import_assertions is false. - Optional::new(import_assertions(), !keep_import_attributes), + Optional::new( + import_assertions(), + should_enable(es_version, EsVersion::EsNext) && !keep_import_attributes + ), Optional::new( typescript::tsx::>( cm.clone(), @@ -1229,6 +1242,9 @@ pub struct JscExperimental { /// This requires `isolatedDeclartion` feature of TypeScript 5.5. #[serde(default)] pub emit_isolated_dts: BoolConfig, + + #[serde(default)] + pub disable_all_lints: BoolConfig, } #[derive(Debug, Clone, Copy, Serialize, Deserialize)] diff --git a/crates/swc_ecma_lints/src/rule.rs b/crates/swc_ecma_lints/src/rule.rs index fabefbe1d5d..1b23b47e257 100644 --- a/crates/swc_ecma_lints/src/rule.rs +++ b/crates/swc_ecma_lints/src/rule.rs @@ -20,6 +20,10 @@ pub trait Rule: Debug + Send + Sync { macro_rules! for_vec { ($name:ident, $program:ident, $s:expr) => {{ + if $s.is_empty() { + return; + } + let program = $program; if cfg!(target_arch = "wasm32") { for rule in $s {