diff --git a/crates/oxc_transformer/src/context.rs b/crates/oxc_transformer/src/context.rs index 5c3c2cb63..edc7feb20 100644 --- a/crates/oxc_transformer/src/context.rs +++ b/crates/oxc_transformer/src/context.rs @@ -13,7 +13,7 @@ use crate::{ statement_injector::StatementInjectorStore, top_level_statements::TopLevelStatementsStore, var_declarations::VarDeclarationsStore, }, - TransformOptions, + Module, TransformOptions, }; pub struct TransformCtx<'a> { @@ -29,6 +29,9 @@ pub struct TransformCtx<'a> { pub source_text: &'a str, + #[expect(unused)] + pub module: Module, + // Helpers /// Manage helper loading pub helper_loader: HelperLoaderStore<'a>, @@ -58,6 +61,7 @@ impl<'a> TransformCtx<'a> { source_path, source_type: SourceType::default(), source_text: "", + module: options.env.module, helper_loader: HelperLoaderStore::new(&options.helper_loader), module_imports: ModuleImportsStore::new(), var_declarations: VarDeclarationsStore::new(), diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs index b80458ab4..dd321309b 100644 --- a/crates/oxc_transformer/src/lib.rs +++ b/crates/oxc_transformer/src/lib.rs @@ -56,7 +56,7 @@ pub use crate::{ jsx::{JsxOptions, JsxRuntime, ReactRefreshOptions}, options::{ babel::{BabelEnvOptions, BabelOptions}, - ESTarget, Engine, EngineTargets, EnvOptions, TransformOptions, + ESTarget, Engine, EngineTargets, EnvOptions, Module, TransformOptions, }, plugins::*, typescript::{RewriteExtensionsMode, TypeScriptOptions}, diff --git a/crates/oxc_transformer/src/options/babel/env/mod.rs b/crates/oxc_transformer/src/options/babel/env/mod.rs index bd2498716..06a635099 100644 --- a/crates/oxc_transformer/src/options/babel/env/mod.rs +++ b/crates/oxc_transformer/src/options/babel/env/mod.rs @@ -4,7 +4,7 @@ use serde::Deserialize; pub use self::targets::BabelTargets; -use crate::options::EngineTargets; +use crate::{options::EngineTargets, Module}; fn default_as_true() -> bool { true @@ -26,8 +26,7 @@ pub struct BabelEnvOptions { #[deprecated = "Not Implemented"] pub loose: bool, - #[deprecated = "Not Implemented"] - pub modules: Option, + pub modules: Module, #[deprecated = "Not Implemented"] pub debug: bool, @@ -56,3 +55,20 @@ pub struct BabelEnvOptions { #[deprecated = "Not Implemented"] pub shipped_proposals: bool, } + +#[derive(Default, Debug, Clone, Deserialize)] +pub enum BabelModule { + #[default] + #[serde(rename = "auto")] + Auto, + #[serde(rename = "amd")] + Amd, + #[serde(rename = "umd")] + Umd, + #[serde(rename = "systemjs")] + Systemjs, + #[serde(rename = "commonjs", alias = "cjs")] + Commonjs, + #[serde(untagged)] + Boolean(bool), +} diff --git a/crates/oxc_transformer/src/options/babel/mod.rs b/crates/oxc_transformer/src/options/babel/mod.rs index a185ddf95..276874a1d 100644 --- a/crates/oxc_transformer/src/options/babel/mod.rs +++ b/crates/oxc_transformer/src/options/babel/mod.rs @@ -8,7 +8,7 @@ use serde::{de::DeserializeOwned, Deserialize}; use crate::CompilerAssumptions; -pub use self::env::{BabelEnvOptions, BabelTargets}; +pub use self::env::{BabelEnvOptions, BabelModule, BabelTargets}; use self::{plugins::BabelPlugins, presets::BabelPresets}; /// Babel options diff --git a/crates/oxc_transformer/src/options/env.rs b/crates/oxc_transformer/src/options/env.rs index 0377782e7..dbc88013e 100644 --- a/crates/oxc_transformer/src/options/env.rs +++ b/crates/oxc_transformer/src/options/env.rs @@ -16,11 +16,14 @@ use crate::{ EngineTargets, }; -use super::{babel::BabelEnvOptions, ESFeature, ESTarget, Engine}; +use super::{babel::BabelEnvOptions, ESFeature, ESTarget, Engine, Module}; #[derive(Debug, Default, Clone, Copy, Deserialize)] #[serde(try_from = "BabelEnvOptions")] pub struct EnvOptions { + /// Specify what module code is generated. + pub module: Module, + pub regexp: RegExpOptions, pub es2015: ES2015Options, @@ -47,6 +50,7 @@ impl EnvOptions { #[doc(hidden)] pub fn enable_all(include_unfinished_plugins: bool) -> Self { Self { + module: Module::default(), regexp: RegExpOptions { sticky_flag: true, unicode_flag: true, @@ -149,6 +153,7 @@ impl From for EnvOptions { fn from(o: EngineTargets) -> Self { use ESFeature::*; Self { + module: Module::default(), regexp: RegExpOptions { sticky_flag: o.has_feature(ES2015StickyRegex), unicode_flag: o.has_feature(ES2015UnicodeRegex), diff --git a/crates/oxc_transformer/src/options/mod.rs b/crates/oxc_transformer/src/options/mod.rs index f85ce5944..b465ef93d 100644 --- a/crates/oxc_transformer/src/options/mod.rs +++ b/crates/oxc_transformer/src/options/mod.rs @@ -6,6 +6,7 @@ mod engine_targets; mod env; mod es_features; mod es_target; +mod module; use std::path::PathBuf; @@ -30,7 +31,7 @@ use crate::{ pub use self::{ browserslist_query::BrowserslistQuery, engine::Engine, engine_targets::EngineTargets, - env::EnvOptions, es_features::ESFeature, es_target::ESTarget, + env::EnvOptions, es_features::ESFeature, es_target::ESTarget, module::Module, }; use self::babel::BabelOptions; @@ -163,6 +164,8 @@ impl TryFrom<&BabelOptions> for TransformOptions { let env = options.presets.env.unwrap_or_default(); + let module = options.presets.env.as_ref().map(|env| env.module).unwrap_or_default(); + let regexp = RegExpOptions { sticky_flag: env.regexp.sticky_flag || options.plugins.sticky_flag, unicode_flag: env.regexp.unicode_flag || options.plugins.unicode_flag, @@ -239,6 +242,7 @@ impl TryFrom<&BabelOptions> for TransformOptions { typescript, jsx, env: EnvOptions { + module, regexp, es2015, es2016, diff --git a/crates/oxc_transformer/src/options/module.rs b/crates/oxc_transformer/src/options/module.rs new file mode 100644 index 000000000..0a1e32477 --- /dev/null +++ b/crates/oxc_transformer/src/options/module.rs @@ -0,0 +1,42 @@ +use oxc_diagnostics::Error; +use serde::Deserialize; + +use crate::options::babel::BabelModule; + +/// Specify what module code is generated. +/// +/// References: +/// - esbuild: +/// - Babel: +/// - TypeScript: +#[derive(Debug, Default, Clone, Copy, Deserialize)] +#[serde(try_from = "BabelModule")] +#[non_exhaustive] +pub enum Module { + #[default] + ESM, + CommonJS, +} + +impl Module { + /// Check if the module is ECMAScript Module(ESM). + pub fn is_esm(&self) -> bool { + matches!(self, Self::ESM) + } + + /// Check if the module is CommonJS. + pub fn is_commonjs(&self) -> bool { + matches!(self, Self::CommonJS) + } +} + +impl TryFrom for Module { + type Error = Error; + fn try_from(value: BabelModule) -> Result { + match value { + BabelModule::Commonjs => Ok(Self::CommonJS), + BabelModule::Auto | BabelModule::Boolean(false) => Ok(Self::ESM), + _ => Err(Error::msg(format!("{value:?} module is not implemented."))), + } + } +} diff --git a/tasks/transform_conformance/snapshots/babel.snap.md b/tasks/transform_conformance/snapshots/babel.snap.md index 2314b99ed..76bf986d2 100644 --- a/tasks/transform_conformance/snapshots/babel.snap.md +++ b/tasks/transform_conformance/snapshots/babel.snap.md @@ -18,31 +18,31 @@ Passed: 316/626 x Output mismatch * dynamic-import/modules-amd/input.js -x Output mismatch +env: Amd module is not implemented. * dynamic-import/modules-cjs/input.mjs x Output mismatch * dynamic-import/modules-systemjs/input.mjs -x Output mismatch +env: Systemjs module is not implemented. * dynamic-import/modules-umd/input.mjs -x Output mismatch +env: Umd module is not implemented. * dynamic-import-babel-7/auto-esm-unsupported-import-unsupported/input.mjs x Output mismatch * dynamic-import-babel-7/modules-amd/input.js -x Output mismatch +env: Amd module is not implemented. * dynamic-import-babel-7/modules-cjs/input.mjs x Output mismatch * dynamic-import-babel-7/modules-systemjs/input.mjs -x Output mismatch +env: Systemjs module is not implemented. * dynamic-import-babel-7/modules-umd/input.mjs -x Output mismatch +env: Umd module is not implemented. * export-namespace-from/auto-esm-not-supported/input.mjs x Output mismatch @@ -69,10 +69,10 @@ x Output mismatch x Output mismatch * modules/modules-systemjs/input.mjs -x Output mismatch +env: Systemjs module is not implemented. * modules/modules-umd/input.mjs -x Output mismatch +env: Umd module is not implemented. * plugins-integration/block-scoping-inside-generator/input.js x Output mismatch @@ -90,7 +90,7 @@ x Output mismatch x Output mismatch * plugins-integration/issue-10662/input.mjs -x Output mismatch +env: Umd module is not implemented. * plugins-integration/issue-11278/input.mjs x Output mismatch