Skip to content

Commit

Permalink
feat(ecmascript): support jsximport/runtime options (#4198)
Browse files Browse the repository at this point in the history
### Description

First part of WEB-719 implementation. PR expands enable_jsx option to
accept few more configuration point to jsx transforms, mainly its import
source. We'll likely to expand options more in the future.

One thing I noted in the code but didn't make change is
`enable_react_refresh`, if it needs to be under the jsx option or should
be independent. Given react_refresh only should be enabled when jsx is
enabled, for me it makes more sense to move it.
kwonoj authored Mar 20, 2023
1 parent 3db969f commit a52e66b
Showing 4 changed files with 59 additions and 18 deletions.
55 changes: 41 additions & 14 deletions crates/turbopack-ecmascript/src/transform/mod.rs
Original file line number Diff line number Diff line change
@@ -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,
@@ -104,22 +108,45 @@ impl EcmascriptInputTransform {
..
} = ctx;
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,
));
}
6 changes: 4 additions & 2 deletions crates/turbopack-tests/tests/snapshot.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ use turbo_tasks_memory::MemoryBackend;
use turbopack::{
condition::ContextCondition,
ecmascript::{chunk::EcmascriptChunkPlaceablesVc, EcmascriptModuleAssetVc},
module_options::ModuleOptionsContext,
module_options::{JsxTransformOptions, JsxTransformOptionsVc, ModuleOptionsContext},
resolve_options_context::ResolveOptionsContext,
transition::TransitionsByNameVc,
ModuleAssetContextVc,
@@ -191,7 +191,9 @@ async fn run_test(resource: &str) -> Result<FileSystemPathVc> {
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),
6 changes: 5 additions & 1 deletion crates/turbopack/src/module_options/mod.rs
Original file line number Diff line number Diff line change
@@ -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()),
});
}

10 changes: 9 additions & 1 deletion crates/turbopack/src/module_options/module_options_context.rs
Original file line number Diff line number Diff line change
@@ -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<String>,
pub runtime: Option<String>,
}

#[turbo_tasks::value(shared)]
#[derive(Default, Clone)]
pub struct ModuleOptionsContext {
#[serde(default)]
pub enable_jsx: bool,
pub enable_jsx: Option<JsxTransformOptionsVc>,
#[serde(default)]
pub enable_emotion: bool,
#[serde(default)]

1 comment on commit a52e66b

@vercel
Copy link

@vercel vercel bot commented on a52e66b Mar 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.