diff options
-rw-r--r-- | cli/compat/esm_resolver.rs | 48 | ||||
-rw-r--r-- | cli/compat/mod.rs | 6 | ||||
-rw-r--r-- | cli/proc_state.rs | 4 | ||||
-rw-r--r-- | cli/tests/integration/compat_tests.rs | 5 | ||||
-rw-r--r-- | cli/tests/testdata/compat/import_map.json | 5 | ||||
-rw-r--r-- | cli/tests/testdata/compat/import_map_https_imports.mjs | 7 | ||||
-rw-r--r-- | cli/tests/testdata/compat/import_map_https_imports.out | 3 |
7 files changed, 70 insertions, 8 deletions
diff --git a/cli/compat/esm_resolver.rs b/cli/compat/esm_resolver.rs index a4ea8cffc..f069428e5 100644 --- a/cli/compat/esm_resolver.rs +++ b/cli/compat/esm_resolver.rs @@ -1,6 +1,7 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use super::errors; +use crate::resolver::ImportMapResolver; use deno_core::error::generic_error; use deno_core::error::AnyError; use deno_core::serde_json; @@ -13,21 +14,60 @@ use regex::Regex; use std::path::PathBuf; #[derive(Debug, Default)] -pub struct NodeEsmResolver; +pub(crate) struct NodeEsmResolver<'a> { + maybe_import_map_resolver: Option<ImportMapResolver<'a>>, +} + +impl<'a> NodeEsmResolver<'a> { + pub fn new(maybe_import_map_resolver: Option<ImportMapResolver<'a>>) -> Self { + Self { + maybe_import_map_resolver, + } + } -impl NodeEsmResolver { pub fn as_resolver(&self) -> &dyn Resolver { self } } -impl Resolver for NodeEsmResolver { +impl Resolver for NodeEsmResolver<'_> { fn resolve( &self, specifier: &str, referrer: &ModuleSpecifier, ) -> Result<ModuleSpecifier, AnyError> { - node_resolve(specifier, referrer.as_str(), &std::env::current_dir()?) + // First try to resolve using import map, ignoring any errors + if !specifier.starts_with("node:") { + if let Some(import_map_resolver) = &self.maybe_import_map_resolver { + if let Ok(specifier) = import_map_resolver.resolve(specifier, referrer) + { + return Ok(specifier); + } + } + } + + let node_resolution = + node_resolve(specifier, referrer.as_str(), &std::env::current_dir()?); + + match node_resolution { + Ok(specifier) => { + // If node resolution succeeded, return the specifier + Ok(specifier) + } + Err(err) => { + // If node resolution failed, check if it's because of unsupported + // URL scheme, and if so try to resolve using regular resolution algorithm + if err + .to_string() + .starts_with("[ERR_UNSUPPORTED_ESM_URL_SCHEME]") + { + return deno_core::resolve_import(specifier, referrer.as_str()) + .map_err(|err| err.into()); + } + + Err(err) + } + } } } diff --git a/cli/compat/mod.rs b/cli/compat/mod.rs index bcc9473eb..997265f96 100644 --- a/cli/compat/mod.rs +++ b/cli/compat/mod.rs @@ -8,7 +8,7 @@ use deno_core::located_script_name; use deno_core::url::Url; use deno_core::JsRuntime; -pub use esm_resolver::NodeEsmResolver; +pub(crate) use esm_resolver::NodeEsmResolver; // TODO(bartlomieju): this needs to be bumped manually for // each release, a better mechanism is preferable, but it's a quick and dirty @@ -86,7 +86,7 @@ fn try_resolve_builtin_module(specifier: &str) -> Option<Url> { } } -pub async fn check_if_should_use_esm_loader( +pub(crate) async fn check_if_should_use_esm_loader( js_runtime: &mut JsRuntime, main_module: &str, ) -> Result<bool, AnyError> { @@ -113,7 +113,7 @@ pub async fn check_if_should_use_esm_loader( Ok(use_esm_loader) } -pub fn load_cjs_module( +pub(crate) fn load_cjs_module( js_runtime: &mut JsRuntime, main_module: &str, ) -> Result<(), AnyError> { diff --git a/cli/proc_state.rs b/cli/proc_state.rs index ecfc94233..0c81ab2e8 100644 --- a/cli/proc_state.rs +++ b/cli/proc_state.rs @@ -298,7 +298,9 @@ impl ProcState { ); let maybe_locker = as_maybe_locker(self.lockfile.clone()); let maybe_imports = self.get_maybe_imports(); - let node_resolver = NodeEsmResolver; + let node_resolver = NodeEsmResolver::new( + self.maybe_import_map.as_ref().map(ImportMapResolver::new), + ); let import_map_resolver = self.maybe_import_map.as_ref().map(ImportMapResolver::new); let maybe_resolver = if self.flags.compat { diff --git a/cli/tests/integration/compat_tests.rs b/cli/tests/integration/compat_tests.rs index 2886056ec..81d2985b3 100644 --- a/cli/tests/integration/compat_tests.rs +++ b/cli/tests/integration/compat_tests.rs @@ -18,6 +18,11 @@ itest!(node_prefix_fs_promises { output: "compat/fs_promises.out", }); +itest!(compat_with_import_map_and_https_imports { + args: "run --quiet --compat --unstable -A --import-map=compat/import_map.json compat/import_map_https_imports.mjs", + output: "compat/import_map_https_imports.out", +}); + #[test] fn globals_in_repl() { let (out, _err) = util::run_and_collect_output_with_args( diff --git a/cli/tests/testdata/compat/import_map.json b/cli/tests/testdata/compat/import_map.json new file mode 100644 index 000000000..2c7b8a6d0 --- /dev/null +++ b/cli/tests/testdata/compat/import_map.json @@ -0,0 +1,5 @@ +{ + "imports": { + "std/": "https://deno.land/std@0.113.0/" + } +} diff --git a/cli/tests/testdata/compat/import_map_https_imports.mjs b/cli/tests/testdata/compat/import_map_https_imports.mjs new file mode 100644 index 000000000..f4f27fdb9 --- /dev/null +++ b/cli/tests/testdata/compat/import_map_https_imports.mjs @@ -0,0 +1,7 @@ +import { sortBy } from "std/collections/sort_by.ts"; +import { findSingle } from "https://deno.land/std@0.113.0/collections/find_single.ts"; +import os from "node:os"; + +console.log(sortBy([2, 3, 1], (it) => it)); +console.log(findSingle([2, 3, 1], (it) => it == 2)); +console.log("arch", os.arch()); diff --git a/cli/tests/testdata/compat/import_map_https_imports.out b/cli/tests/testdata/compat/import_map_https_imports.out new file mode 100644 index 000000000..7ee30676e --- /dev/null +++ b/cli/tests/testdata/compat/import_map_https_imports.out @@ -0,0 +1,3 @@ +[ 1, 2, 3 ] +2 +arch [WILDCARD] |