From b1893e65f20cf92585f59415eb23e709e32149b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Mon, 15 Jun 2020 17:53:05 +0200 Subject: [PATCH] fix(compiler): JSX compilation and provide better error message (#6300) --- cli/global_state.rs | 61 +++++++++++++++++++++++++--- cli/tests/integration_tests.rs | 5 +++ cli/tests/jsx_import_from_ts.App.jsx | 11 +++++ cli/tests/jsx_import_from_ts.ts | 3 ++ cli/tests/jsx_import_from_ts.ts.out | 1 + 5 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 cli/tests/jsx_import_from_ts.App.jsx create mode 100644 cli/tests/jsx_import_from_ts.ts create mode 100644 cli/tests/jsx_import_from_ts.ts.out diff --git a/cli/global_state.rs b/cli/global_state.rs index c9c86ff965..959d794ca5 100644 --- a/cli/global_state.rs +++ b/cli/global_state.rs @@ -9,6 +9,7 @@ use crate::module_graph::ModuleGraphFile; use crate::module_graph::ModuleGraphLoader; use crate::msg; use crate::msg::MediaType; +use crate::op_error::OpError; use crate::permissions::Permissions; use crate::state::exit_unstable; use crate::tsc::CompiledModule; @@ -203,7 +204,16 @@ impl GlobalState { }; let compiled_module = if was_compiled { - state1.ts_compiler.get_compiled_module(&out.url)? + state1 + .ts_compiler + .get_compiled_module(&out.url) + .map_err(|e| { + let msg = e.to_string(); + OpError::other(format!( + "Failed to get compiled source code of {}.\nReason: {}", + out.url, msg + )) + })? } else { CompiledModule { code: String::from_utf8(out.source_code.clone())?, @@ -245,12 +255,14 @@ impl GlobalState { } /// Determine if TS compiler should be run with `allowJs` setting on. This -/// is the case when there's a JavaScript file with non-JavaScript import. +/// is the case when there's either: +/// - a JavaScript file with non-JavaScript import +/// - JSX import fn should_allow_js(module_graph_files: &[&ModuleGraphFile]) -> bool { module_graph_files.iter().any(|module_file| { - if module_file.media_type != (MediaType::JavaScript as i32) { - false - } else { + if module_file.media_type == (MediaType::JSX as i32) { + true + } else if module_file.media_type == (MediaType::JavaScript as i32) { module_file.imports.iter().any(|import_desc| { let import_file = module_graph_files .iter() @@ -263,6 +275,8 @@ fn should_allow_js(module_graph_files: &[&ModuleGraphFile]) -> bool { || media_type == (MediaType::TSX as i32) || media_type == (MediaType::JSX as i32) }) + } else { + false } }) } @@ -342,6 +356,43 @@ fn test_should_allow_js() { }, ],)); + assert!(should_allow_js(&[ + &ModuleGraphFile { + specifier: "file:///some/file.jsx".to_string(), + url: "file:///some/file.jsx".to_string(), + redirect: None, + filename: "some/file.jsx".to_string(), + imports: vec![], + referenced_files: vec![], + lib_directives: vec![], + types_directives: vec![], + type_headers: vec![], + media_type: MediaType::JSX as i32, + source_code: "function foo() {}".to_string(), + }, + &ModuleGraphFile { + specifier: "file:///some/file.ts".to_string(), + url: "file:///some/file.ts".to_string(), + redirect: None, + filename: "some/file.ts".to_string(), + imports: vec![ImportDescriptor { + specifier: "./file.jsx".to_string(), + resolved_specifier: ModuleSpecifier::resolve_url( + "file:///some/file.jsx", + ) + .unwrap(), + type_directive: None, + resolved_type_directive: None, + }], + referenced_files: vec![], + lib_directives: vec![], + types_directives: vec![], + type_headers: vec![], + media_type: MediaType::TypeScript as i32, + source_code: "function foo() {}".to_string(), + }, + ])); + assert!(!should_allow_js(&[ &ModuleGraphFile { specifier: "file:///some/file.js".to_string(), diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 66308a4992..36e2bc90b4 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -2015,6 +2015,11 @@ itest!(ts_import_from_js { http_server: true, }); +itest!(jsx_import_from_ts { + args: "run --quiet --reload jsx_import_from_ts.ts", + output: "jsx_import_from_ts.ts.out", +}); + itest!(single_compile_with_reload { args: "run --reload --allow-read single_compile_with_reload.ts", output: "single_compile_with_reload.ts.out", diff --git a/cli/tests/jsx_import_from_ts.App.jsx b/cli/tests/jsx_import_from_ts.App.jsx new file mode 100644 index 0000000000..6ea58436ba --- /dev/null +++ b/cli/tests/jsx_import_from_ts.App.jsx @@ -0,0 +1,11 @@ +const React = { + createElement() {} +} + +export default function app() { + return ( +
+

asdf

+
+ ); +} \ No newline at end of file diff --git a/cli/tests/jsx_import_from_ts.ts b/cli/tests/jsx_import_from_ts.ts new file mode 100644 index 0000000000..3cc916698d --- /dev/null +++ b/cli/tests/jsx_import_from_ts.ts @@ -0,0 +1,3 @@ +import app from "./jsx_import_from_ts.App.jsx"; + +console.log(app); diff --git a/cli/tests/jsx_import_from_ts.ts.out b/cli/tests/jsx_import_from_ts.ts.out new file mode 100644 index 0000000000..d449b8c9ae --- /dev/null +++ b/cli/tests/jsx_import_from_ts.ts.out @@ -0,0 +1 @@ +[Function: app]