summaryrefslogtreecommitdiff
path: root/cli/ops/runtime_compiler.rs
diff options
context:
space:
mode:
authorKitson Kelly <me@kitsonkelly.com>2021-11-09 12:26:39 +1100
committerGitHub <noreply@github.com>2021-11-09 12:26:39 +1100
commitf5eb177f50a0bf37bc6bd9d87b447c73a53b6ea5 (patch)
tree1990dadf311de59b45c677e234219a161f3ebf9d /cli/ops/runtime_compiler.rs
parent45425c114610516287c8e5831c9b6f023dfc8180 (diff)
feat(cli): support React 17 JSX transforms (#12631)
Closes #8440
Diffstat (limited to 'cli/ops/runtime_compiler.rs')
-rw-r--r--cli/ops/runtime_compiler.rs80
1 files changed, 72 insertions, 8 deletions
diff --git a/cli/ops/runtime_compiler.rs b/cli/ops/runtime_compiler.rs
index 8f7a75146..b16fbcf69 100644
--- a/cli/ops/runtime_compiler.rs
+++ b/cli/ops/runtime_compiler.rs
@@ -7,6 +7,7 @@ use crate::emit;
use crate::errors::get_error_class_name;
use crate::proc_state::ProcState;
use crate::resolver::ImportMapResolver;
+use crate::resolver::JsxResolver;
use deno_core::error::custom_error;
use deno_core::error::generic_error;
@@ -71,14 +72,66 @@ struct EmitResult {
stats: emit::Stats,
}
+/// Provides inferred imported modules from configuration options, like the
+/// `"types"` and `"jsxImportSource"` imports.
fn to_maybe_imports(
referrer: &ModuleSpecifier,
maybe_options: Option<&HashMap<String, Value>>,
) -> Option<Vec<(ModuleSpecifier, Vec<String>)>> {
- let options = maybe_options.as_ref()?;
- let types_value = options.get("types")?;
- let types: Vec<String> = serde_json::from_value(types_value.clone()).ok()?;
- Some(vec![(referrer.clone(), types)])
+ let options = maybe_options?;
+ let mut imports = Vec::new();
+ if let Some(types_value) = options.get("types") {
+ if let Ok(types) =
+ serde_json::from_value::<Vec<String>>(types_value.clone())
+ {
+ imports.extend(types);
+ }
+ }
+ if let Some(jsx_value) = options.get("jsx") {
+ if let Ok(jsx) = serde_json::from_value::<String>(jsx_value.clone()) {
+ let jsx_import_source =
+ if let Some(jsx_import_source_value) = options.get("jsxImportSource") {
+ if let Ok(jsx_import_source) =
+ serde_json::from_value::<String>(jsx_import_source_value.clone())
+ {
+ jsx_import_source
+ } else {
+ "react".to_string()
+ }
+ } else {
+ "react".to_string()
+ };
+ match jsx.as_str() {
+ "react-jsx" => {
+ imports.push(format!("{}/jsx-runtime", jsx_import_source));
+ }
+ "react-jsxdev" => {
+ imports.push(format!("{}/jsx-dev-runtime", jsx_import_source));
+ }
+ _ => (),
+ }
+ }
+ }
+ if !imports.is_empty() {
+ Some(vec![(referrer.clone(), imports)])
+ } else {
+ None
+ }
+}
+
+/// Converts the compiler options to the JSX import source module that will be
+/// loaded when transpiling JSX.
+fn to_maybe_jsx_import_source_module(
+ maybe_options: Option<&HashMap<String, Value>>,
+) -> Option<String> {
+ let options = maybe_options?;
+ let jsx_value = options.get("jsx")?;
+ let jsx: String = serde_json::from_value(jsx_value.clone()).ok()?;
+ match jsx.as_str() {
+ "react-jsx" => Some("jsx-runtime".to_string()),
+ "react-jsxdev" => Some("jsx-dev-runtime".to_string()),
+ _ => None,
+ }
}
async fn op_emit(
@@ -108,7 +161,9 @@ async fn op_emit(
runtime_permissions.clone(),
))
};
- let maybe_import_map = if let Some(import_map_str) = args.import_map_path {
+ let maybe_import_map_resolver = if let Some(import_map_str) =
+ args.import_map_path
+ {
let import_map_specifier = resolve_url_or_path(&import_map_str)
.context(format!("Bad URL (\"{}\") for import map.", import_map_str))?;
let import_map = if let Some(value) = args.import_map {
@@ -126,23 +181,32 @@ async fn op_emit(
})?;
ImportMap::from_json(import_map_specifier.as_str(), &file.source)?
};
- Some(import_map)
+ Some(ImportMapResolver::new(Arc::new(import_map)))
} else if args.import_map.is_some() {
return Err(generic_error("An importMap was specified, but no importMapPath was provided, which is required."));
} else {
None
};
+ let maybe_jsx_resolver =
+ to_maybe_jsx_import_source_module(args.compiler_options.as_ref())
+ .map(|im| JsxResolver::new(im, maybe_import_map_resolver.clone()));
+ let maybe_resolver = if maybe_jsx_resolver.is_some() {
+ maybe_jsx_resolver.as_ref().map(|jr| jr.as_resolver())
+ } else {
+ maybe_import_map_resolver
+ .as_ref()
+ .map(|imr| imr.as_resolver())
+ };
let roots = vec![resolve_url_or_path(&root_specifier)?];
let maybe_imports =
to_maybe_imports(&roots[0], args.compiler_options.as_ref());
- let maybe_resolver = maybe_import_map.as_ref().map(ImportMapResolver::new);
let graph = Arc::new(
deno_graph::create_graph(
roots,
true,
maybe_imports,
cache.as_mut_loader(),
- maybe_resolver.as_ref().map(|r| r.as_resolver()),
+ maybe_resolver,
None,
None,
)