From 8801ca2ccc22f462c939e42ae8369b9772377d77 Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Tue, 14 Mar 2023 11:26:06 -0700 Subject: [PATCH] feat(ecmascript): support jsximport/runtime options --- .../turbopack-ecmascript/src/transform/mod.rs | 55 ++++++++++++++----- crates/turbopack-tests/tests/snapshot.rs | 4 +- crates/turbopack/src/module_options/mod.rs | 6 +- .../module_options/module_options_context.rs | 10 +++- 4 files changed, 58 insertions(+), 17 deletions(-) diff --git a/crates/turbopack-ecmascript/src/transform/mod.rs b/crates/turbopack-ecmascript/src/transform/mod.rs index e5c5786e64626..de95bbd84b7a7 100644 --- a/crates/turbopack-ecmascript/src/transform/mod.rs +++ b/crates/turbopack-ecmascript/src/transform/mod.rs @@ -16,7 +16,7 @@ use swc_core::{ visit::{FoldWith, VisitMutWith}, }, }; -use turbo_tasks::primitives::StringVc; +use turbo_tasks::primitives::{OptionStringVc, StringVc}; use turbo_tasks_fs::json::parse_json_with_source_context; use turbopack_core::environment::EnvironmentVc; @@ -33,6 +33,10 @@ pub enum EcmascriptInputTransform { React { #[serde(default)] refresh: bool, + // swc.jsc.transform.react.importSource + import_source: OptionStringVc, + // swc.jsc.transform.react.runtime, + runtime: OptionStringVc, }, StyledComponents, StyledJsx, @@ -83,22 +87,45 @@ impl EcmascriptInputTransform { }: &TransformContext<'_>, ) -> Result<()> { match *self { - EcmascriptInputTransform::React { refresh } => { + EcmascriptInputTransform::React { + refresh, + import_source, + runtime, + } => { + use swc_core::ecma::transforms::react::{Options, Runtime}; + let runtime = if let Some(runtime) = &*runtime.await? { + match runtime.as_str() { + "classic" => Runtime::Classic, + "automatic" => Runtime::Automatic, + _ => { + return Err(anyhow::anyhow!( + "Invalid value for swc.jsc.transform.react.runtime: {}", + runtime + )) + } + } + } else { + Runtime::Automatic + }; + + let config = Options { + runtime: Some(runtime), + development: Some(true), + import_source: (&*import_source.await?).clone(), + refresh: if refresh { + Some(swc_core::ecma::transforms::react::RefreshOptions { + ..Default::default() + }) + } else { + None + }, + ..Default::default() + }; + program.visit_mut_with(&mut react( source_map.clone(), Some(comments.clone()), - swc_core::ecma::transforms::react::Options { - runtime: Some(swc_core::ecma::transforms::react::Runtime::Automatic), - development: Some(true), - refresh: if refresh { - Some(swc_core::ecma::transforms::react::RefreshOptions { - ..Default::default() - }) - } else { - None - }, - ..Default::default() - }, + config, top_level_mark, )); } diff --git a/crates/turbopack-tests/tests/snapshot.rs b/crates/turbopack-tests/tests/snapshot.rs index c4b4a417e8924..271af87859b63 100644 --- a/crates/turbopack-tests/tests/snapshot.rs +++ b/crates/turbopack-tests/tests/snapshot.rs @@ -192,7 +192,9 @@ async fn run_test(resource: String) -> Result { TransitionsByNameVc::cell(HashMap::new()), compile_time_info, ModuleOptionsContext { - enable_jsx: true, + enable_jsx: Some(JsxTransformOptionsVc::cell(JsxTransformOptions { + ..Default::default() + })), enable_emotion: true, enable_styled_components: true, preset_env_versions: Some(env), diff --git a/crates/turbopack/src/module_options/mod.rs b/crates/turbopack/src/module_options/mod.rs index ee07a2c8397a4..3835e77c1c21c 100644 --- a/crates/turbopack/src/module_options/mod.rs +++ b/crates/turbopack/src/module_options/mod.rs @@ -6,6 +6,7 @@ use anyhow::{Context, Result}; pub use module_options_context::*; pub use module_rule::*; pub use rule_condition::*; +use turbo_tasks::primitives::OptionStringVc; use turbo_tasks_fs::FileSystemPathVc; use turbopack_core::{ reference_type::{ReferenceType, UrlReferenceSubType}, @@ -97,9 +98,12 @@ impl ModuleOptionsVc { if enable_styled_components { transforms.push(EcmascriptInputTransform::StyledComponents) } - if enable_jsx { + if let Some(enable_jsx) = enable_jsx { + let jsx = enable_jsx.await?; transforms.push(EcmascriptInputTransform::React { refresh: enable_react_refresh, + import_source: OptionStringVc::cell(jsx.import_source.clone()), + runtime: OptionStringVc::cell(jsx.runtime.clone()), }); } diff --git a/crates/turbopack/src/module_options/module_options_context.rs b/crates/turbopack/src/module_options/module_options_context.rs index 742dd119e2954..71048a34c08e9 100644 --- a/crates/turbopack/src/module_options/module_options_context.rs +++ b/crates/turbopack/src/module_options/module_options_context.rs @@ -60,11 +60,19 @@ impl WebpackLoadersOptions { } } +// [TODO]: should enabled_react_refresh belong to this options? +#[turbo_tasks::value(shared)] +#[derive(Default, Clone, Debug)] +pub struct JsxTransformOptions { + pub import_source: Option, + pub runtime: Option, +} + #[turbo_tasks::value(shared)] #[derive(Default, Clone)] pub struct ModuleOptionsContext { #[serde(default)] - pub enable_jsx: bool, + pub enable_jsx: Option, #[serde(default)] pub enable_emotion: bool, #[serde(default)]