mirror of
https://github.com/denoland/deno.git
synced 2024-12-31 11:34:15 -05:00
feat: Expand 'imports' section of deno.json (#22087)
This commit adds automatic expansion of "imports" field in "deno.json" file. If "npm:" or "jsr:" imports are encountered we automatically try to add a "directory" remapping. Previously users had to specify entries for both `foo` and `foo/` to be able to import like `import { symbol1 } from "foo";` and `import { symbol2 } from "foo/some_file.js"`: ``` { "imports": { "foo": "npm:@foo/bar", "foo/": "npm:/@foo/bar/", } ``` With this change users can only add entry for `foo`: ``` { "imports": { "foo": "npm:@foo/bar", } ``` The entry for `foo/` will be provided automatically. Similarly if user provides "directory" remapping explicitly, we will not overwrite it.
This commit is contained in:
parent
801ed74118
commit
44f8b05f5b
5 changed files with 110 additions and 6 deletions
|
@ -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<i64> {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
2
cli/tests/testdata/compile/npm_fs/main.ts
vendored
2
cli/tests/testdata/compile/npm_fs/main.ts
vendored
|
@ -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);
|
||||
|
|
3
cli/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/other.mjs
vendored
Normal file
3
cli/tests/testdata/npm/registry/@denotest/esm-basic/1.0.0/other.mjs
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
export function hello() {
|
||||
return "hello, world!";
|
||||
}
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue