diff --git a/cli/args/mod.rs b/cli/args/mod.rs index 13ee9eeef4..1e5d8754de 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -889,7 +889,19 @@ impl CliOptions { .members .iter() .map(|member| { - let import_map_value = member.config_file.to_import_map_value(); + let mut import_map_value = member.config_file.to_import_map_value(); + + let expanded_import_map_value = ::import_map::ext::expand_imports( + ::import_map::ext::ImportMapConfig { + base_url: member.config_file.specifier.clone(), + import_map_value: import_map_value.clone(), + }, + ); + + import_map_value + .as_object_mut() + .unwrap() + .insert("imports".to_string(), expanded_import_map_value); ::import_map::ext::ImportMapConfig { base_url: member.config_file.specifier.clone(), import_map_value, @@ -906,12 +918,24 @@ impl CliOptions { "Workspace config generated this import map {}", serde_json::to_string_pretty(&import_map).unwrap() ); - return import_map::import_map_from_value( + let maybe_import_map_result = import_map::import_map_from_value( // TODO(bartlomieju): maybe should be stored on the workspace config? &self.maybe_config_file.as_ref().unwrap().specifier, import_map, ) .map(Some); + + return match maybe_import_map_result { + Ok(maybe_import_map) => { + if let Some(mut import_map) = maybe_import_map { + import_map.ext_expand_imports(); + Ok(Some(import_map)) + } else { + Ok(None) + } + } + Err(err) => Err(err), + }; } } @@ -919,7 +943,8 @@ impl CliOptions { Some(specifier) => specifier, None => return Ok(None), }; - resolve_import_map_from_specifier( + + let maybe_import_map_result = resolve_import_map_from_specifier( &import_map_specifier, self.maybe_config_file().as_ref(), file_fetcher, @@ -928,7 +953,22 @@ impl CliOptions { .with_context(|| { format!("Unable to load '{import_map_specifier}' import map") }) - .map(Some) + .map(Some); + + match maybe_import_map_result { + Ok(maybe_import_map) => { + if let Some(mut import_map) = maybe_import_map { + let url = import_map.base_url().as_str(); + if url.ends_with("deno.json") || url.ends_with("deno.jsonc") { + import_map.ext_expand_imports(); + } + Ok(Some(import_map)) + } else { + Ok(None) + } + } + Err(err) => Err(err), + } } pub fn node_ipc_fd(&self) -> Option { diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs index 6c82cfeec7..b8acce94de 100644 --- a/cli/tests/integration/run_tests.rs +++ b/cli/tests/integration/run_tests.rs @@ -5113,3 +5113,64 @@ itest!(warn_on_deprecated_api_with_env_var { http_server: true, exit_code: 0, }); + +#[test] +fn deno_json_imports_expand() { + let test_context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let dir = test_context.temp_dir(); + dir.write( + "deno.json", + r#"{ + "imports": { + "basic": "npm:@denotest/esm-basic" + } +}"#, + ); + + dir.write( + "main.ts", + r#" +// import map should resolve +import { setValue, getValue } from "basic"; +// this entry should have been added automatically +import { hello } from "basic/other.mjs"; + +setValue(5); +console.log(getValue()); +console.log(hello()); +"#, + ); + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text("[WILDCARD]5\nhello, world!\n"); +} + +#[test] +fn deno_json_imports_expand_doesnt_overwrite_existing_entries() { + let test_context = TestContextBuilder::for_npm().use_temp_cwd().build(); + let dir = test_context.temp_dir(); + dir.write( + "deno.json", + r#"{ + "imports": { + "basic": "npm:@denotest/esm-basic", + "basic/": "npm:/@denotest/sub-folders/folder_index_js/" + } +}"#, + ); + + dir.write( + "main.ts", + r#" +// import map should resolve +import { setValue, getValue } from "basic"; +// this entry should map to explicitly specified "basic/" mapping +import { add } from "basic/index.js"; + +setValue(5); +console.log(getValue()); +console.log(add(3, 4)); +"#, + ); + let output = test_context.new_command().args("run main.ts").run(); + output.assert_matches_text("[WILDCARD]5\n7\n"); +} diff --git a/cli/tests/testdata/compile/npm_fs/main.ts b/cli/tests/testdata/compile/npm_fs/main.ts index f9951d7a46..6361610a9e 100644 --- a/cli/tests/testdata/compile/npm_fs/main.ts +++ b/cli/tests/testdata/compile/npm_fs/main.ts @@ -154,7 +154,7 @@ await assert.rejects( } // read dir -const readDirNames = ["main.d.mts", "main.mjs", "package.json"]; +const readDirNames = ["main.d.mts", "main.mjs", "other.mjs", "package.json"]; { const names = Array.from(Deno.readDirSync(dirPath)) .map((e) => e.name); diff --git a/cli/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/other.mjs b/cli/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/other.mjs new file mode 100644 index 0000000000..00ed99da45 --- /dev/null +++ b/cli/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/other.mjs @@ -0,0 +1,3 @@ +export function hello() { + return "hello, world!"; +} \ No newline at end of file diff --git a/cli/tests/testdata/package_json/basic/main.info.out b/cli/tests/testdata/package_json/basic/main.info.out index b283a0ee0a..892c0612ae 100644 --- a/cli/tests/testdata/package_json/basic/main.info.out +++ b/cli/tests/testdata/package_json/basic/main.info.out @@ -5,4 +5,4 @@ size: [WILDCARD] file:///[WILDCARD]/main.ts (63B) └─┬ file:///[WILDCARD]/lib.ts (166B) - └── npm:/@denotest/esm-basic@1.0.0 (416B) + └── npm:/@denotest/esm-basic@1.0.0 (471B)