diff options
Diffstat (limited to 'cli/global_state.rs')
-rw-r--r-- | cli/global_state.rs | 165 |
1 files changed, 143 insertions, 22 deletions
diff --git a/cli/global_state.rs b/cli/global_state.rs index c1ed3af61..44a3946e2 100644 --- a/cli/global_state.rs +++ b/cli/global_state.rs @@ -143,11 +143,13 @@ impl GlobalState { .expect("Source file not found"); // Check if we need to compile files. + let module_graph_files = module_graph.values().collect::<Vec<_>>(); let should_compile = needs_compilation( self.ts_compiler.compile_js, out.media_type, - module_graph.values().collect::<Vec<_>>(), + &module_graph_files, ); + let allow_js = should_allow_js(&module_graph_files); if should_compile { self @@ -158,6 +160,7 @@ impl GlobalState { target_lib, permissions, module_graph, + allow_js, ) .await?; } @@ -241,6 +244,29 @@ 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. +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 { + module_file.imports.iter().any(|import_desc| { + let import_file = module_graph_files + .iter() + .find(|f| { + f.specifier == import_desc.resolved_specifier.to_string().as_str() + }) + .expect("Failed to find imported file"); + let media_type = import_file.media_type; + media_type == (MediaType::TypeScript as i32) + || media_type == (MediaType::TSX as i32) + || media_type == (MediaType::JSX as i32) + }) + } + }) +} + // Compilation happens if either: // - `checkJs` is set to true in TS config // - entry point is a TS file @@ -248,7 +274,7 @@ impl GlobalState { fn needs_compilation( compile_js: bool, media_type: MediaType, - module_graph_files: Vec<&ModuleGraphFile>, + module_graph_files: &[&ModuleGraphFile], ) -> bool { let mut needs_compilation = match media_type { msg::MediaType::TypeScript | msg::MediaType::TSX | msg::MediaType::JSX => { @@ -276,12 +302,49 @@ fn thread_safe() { } #[test] -fn test_needs_compilation() { - assert!(!needs_compilation( - false, - MediaType::JavaScript, - vec![&ModuleGraphFile { - specifier: "some/file.js".to_string(), +fn test_should_allow_js() { + use crate::module_graph::ImportDescriptor; + + assert!(should_allow_js(&[ + &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![], + referenced_files: vec![], + lib_directives: vec![], + types_directives: vec![], + type_headers: vec![], + media_type: MediaType::TypeScript as i32, + source_code: "function foo() {}".to_string(), + }, + &ModuleGraphFile { + specifier: "file:///some/file1.js".to_string(), + url: "file:///some/file1.js".to_string(), + redirect: None, + filename: "some/file1.js".to_string(), + imports: vec![ImportDescriptor { + specifier: "./file.ts".to_string(), + resolved_specifier: ModuleSpecifier::resolve_url( + "file:///some/file.ts", + ) + .unwrap(), + type_directive: None, + resolved_type_directive: None, + }], + 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!(!should_allow_js(&[ + &ModuleGraphFile { + specifier: "file:///some/file.js".to_string(), url: "file:///some/file.js".to_string(), redirect: None, filename: "some/file.js".to_string(), @@ -292,28 +355,86 @@ fn test_needs_compilation() { 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( + }, + &ModuleGraphFile { + specifier: "file:///some/file1.js".to_string(), + url: "file:///some/file1.js".to_string(), + redirect: None, + filename: "some/file1.js".to_string(), + imports: vec![ImportDescriptor { + specifier: "./file.js".to_string(), + resolved_specifier: ModuleSpecifier::resolve_url( + "file:///some/file.js", + ) + .unwrap(), + type_directive: None, + resolved_type_directive: None, + }], + referenced_files: vec![], + lib_directives: vec![], + types_directives: vec![], + type_headers: vec![], + media_type: MediaType::JavaScript as i32, + source_code: "function foo() {}".to_string(), + }, + ],)); +} + +#[test] +fn test_needs_compilation() { + assert!(!needs_compilation( false, MediaType::JavaScript, - vec![&ModuleGraphFile { - specifier: "some/file.ts".to_string(), - url: "file:///some/file.ts".to_string(), + &[&ModuleGraphFile { + specifier: "some/file.js".to_string(), + url: "file:///some/file.js".to_string(), redirect: None, - filename: "some/file.ts".to_string(), + filename: "some/file.js".to_string(), imports: vec![], referenced_files: vec![], lib_directives: vec![], types_directives: vec![], type_headers: vec![], - media_type: MediaType::TypeScript as i32, + media_type: MediaType::JavaScript as i32, source_code: "function foo() {}".to_string(), - }] + }], + )); + + assert!(!needs_compilation(false, MediaType::JavaScript, &[])); + assert!(needs_compilation(true, MediaType::JavaScript, &[])); + assert!(needs_compilation(false, MediaType::TypeScript, &[])); + assert!(needs_compilation(false, MediaType::JSX, &[])); + assert!(needs_compilation(false, MediaType::TSX, &[])); + assert!(needs_compilation( + false, + MediaType::JavaScript, + &[ + &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![], + referenced_files: vec![], + lib_directives: vec![], + types_directives: vec![], + type_headers: vec![], + media_type: MediaType::TypeScript as i32, + source_code: "function foo() {}".to_string(), + }, + &ModuleGraphFile { + specifier: "file:///some/file1.js".to_string(), + url: "file:///some/file1.js".to_string(), + redirect: None, + filename: "some/file1.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(), + }, + ], )); } |