From c81399080686bb5293869f30714a6d1b97a75801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Mon, 1 Jun 2020 21:01:51 +0200 Subject: [PATCH] fix: compile TS dependencies of JS files (#6000) This commit fixes regression that caused TS dependencies not being compiled. Check was added that ensures TS compiler is run if any of dependencies in module graph is TS/TSX/JSX. --- cli/global_state.rs | 89 +++++++++++++++++++++++++++--- cli/tests/integration_tests.rs | 5 ++ cli/tests/ts_import_from_js.js | 1 + cli/tests/ts_import_from_js.js.out | 1 + 4 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 cli/tests/ts_import_from_js.js create mode 100644 cli/tests/ts_import_from_js.js.out diff --git a/cli/global_state.rs b/cli/global_state.rs index 3c3348fd17..c1ed3af61f 100644 --- a/cli/global_state.rs +++ b/cli/global_state.rs @@ -5,8 +5,10 @@ use crate::flags; use crate::http_cache; use crate::import_map::ImportMap; use crate::lockfile::Lockfile; +use crate::module_graph::ModuleGraphFile; use crate::module_graph::ModuleGraphLoader; use crate::msg; +use crate::msg::MediaType; use crate::permissions::Permissions; use crate::state::exit_unstable; use crate::tsc::CompiledModule; @@ -140,16 +142,14 @@ impl GlobalState { .fetch_cached_source_file(&module_specifier, permissions.clone()) .expect("Source file not found"); - // Check if we need to compile files - let needs_compilation = match out.media_type { - msg::MediaType::TypeScript - | msg::MediaType::TSX - | msg::MediaType::JSX => true, - msg::MediaType::JavaScript => self.ts_compiler.compile_js, - _ => false, - }; + // Check if we need to compile files. + let should_compile = needs_compilation( + self.ts_compiler.compile_js, + out.media_type, + module_graph.values().collect::>(), + ); - if needs_compilation { + if should_compile { self .ts_compiler .compile_module_graph( @@ -241,8 +241,79 @@ impl GlobalState { } } +// Compilation happens if either: +// - `checkJs` is set to true in TS config +// - entry point is a TS file +// - any dependency in module graph is a TS file +fn needs_compilation( + compile_js: bool, + media_type: MediaType, + module_graph_files: Vec<&ModuleGraphFile>, +) -> bool { + let mut needs_compilation = match media_type { + msg::MediaType::TypeScript | msg::MediaType::TSX | msg::MediaType::JSX => { + true + } + msg::MediaType::JavaScript => compile_js, + _ => false, + }; + + needs_compilation |= module_graph_files.iter().any(|module_file| { + let media_type = module_file.media_type; + + media_type == (MediaType::TypeScript as i32) + || media_type == (MediaType::TSX as i32) + || media_type == (MediaType::JSX as i32) + }); + + needs_compilation +} + #[test] fn thread_safe() { fn f(_: S) {} f(GlobalState::mock(vec![])); } + +#[test] +fn test_needs_compilation() { + assert!(!needs_compilation( + false, + MediaType::JavaScript, + vec![&ModuleGraphFile { + specifier: "some/file.js".to_string(), + url: "file:///some/file.js".to_string(), + redirect: None, + filename: "some/file.js".to_string(), + imports: vec![], + referenced_files: vec![], + lib_directives: vec![], + types_directives: vec![], + type_headers: vec![], + media_type: MediaType::JavaScript as i32, + source_code: "function foo() {}".to_string(), + }] + )); + assert!(!needs_compilation(false, MediaType::JavaScript, vec![])); + assert!(needs_compilation(true, MediaType::JavaScript, vec![])); + assert!(needs_compilation(false, MediaType::TypeScript, vec![])); + assert!(needs_compilation(false, MediaType::JSX, vec![])); + assert!(needs_compilation(false, MediaType::TSX, vec![])); + assert!(needs_compilation( + false, + MediaType::JavaScript, + vec![&ModuleGraphFile { + specifier: "some/file.ts".to_string(), + url: "file:///some/file.ts".to_string(), + redirect: None, + filename: "some/file.ts".to_string(), + imports: vec![], + referenced_files: vec![], + lib_directives: vec![], + types_directives: vec![], + type_headers: vec![], + media_type: MediaType::TypeScript as i32, + source_code: "function foo() {}".to_string(), + }] + )); +} diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 807efb1c53..5f4b377442 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -1837,6 +1837,11 @@ itest!(cjs_imports { output: "cjs_imports.ts.out", }); +itest!(ts_import_from_js { + args: "run --quiet --reload ts_import_from_js.js", + output: "ts_import_from_js.js.out", +}); + itest!(proto_exploit { args: "run proto_exploit.js", output: "proto_exploit.js.out", diff --git a/cli/tests/ts_import_from_js.js b/cli/tests/ts_import_from_js.js new file mode 100644 index 0000000000..e06ca15a24 --- /dev/null +++ b/cli/tests/ts_import_from_js.js @@ -0,0 +1 @@ +import "./005_more_imports.ts"; diff --git a/cli/tests/ts_import_from_js.js.out b/cli/tests/ts_import_from_js.js.out new file mode 100644 index 0000000000..e965047ad7 --- /dev/null +++ b/cli/tests/ts_import_from_js.js.out @@ -0,0 +1 @@ +Hello