summaryrefslogtreecommitdiff
path: root/resolvers/node
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2024-11-14 15:24:25 -0500
committerGitHub <noreply@github.com>2024-11-14 15:24:25 -0500
commit617350e79c58b6e01984e3d7c7436d243d0e5cff (patch)
treedadb3c7675d1d49952a30c525bbc6ee3086a78e3 /resolvers/node
parentde34c7ed29bcce8b46a65f5effe45090b8493ba5 (diff)
refactor(resolver): move more resolution code into deno_resolver (#26873)
Follow-up to cjs refactor. This moves most of the resolution code into the deno_resolver crate. Still pending is the npm resolution code.
Diffstat (limited to 'resolvers/node')
-rw-r--r--resolvers/node/analyze.rs6
-rw-r--r--resolvers/node/lib.rs5
-rw-r--r--resolvers/node/npm.rs9
-rw-r--r--resolvers/node/resolution.rs51
4 files changed, 58 insertions, 13 deletions
diff --git a/resolvers/node/analyze.rs b/resolvers/node/analyze.rs
index c7415933d..912689080 100644
--- a/resolvers/node/analyze.rs
+++ b/resolvers/node/analyze.rs
@@ -23,7 +23,7 @@ use crate::npm::InNpmPackageCheckerRc;
use crate::resolution::NodeResolverRc;
use crate::NodeModuleKind;
use crate::NodeResolutionMode;
-use crate::NpmResolverRc;
+use crate::NpmPackageFolderResolverRc;
use crate::PackageJsonResolverRc;
use crate::PathClean;
@@ -66,7 +66,7 @@ pub struct NodeCodeTranslator<
env: TNodeResolverEnv,
in_npm_pkg_checker: InNpmPackageCheckerRc,
node_resolver: NodeResolverRc<TNodeResolverEnv>,
- npm_resolver: NpmResolverRc,
+ npm_resolver: NpmPackageFolderResolverRc,
pkg_json_resolver: PackageJsonResolverRc<TNodeResolverEnv>,
}
@@ -78,7 +78,7 @@ impl<TCjsCodeAnalyzer: CjsCodeAnalyzer, TNodeResolverEnv: NodeResolverEnv>
env: TNodeResolverEnv,
in_npm_pkg_checker: InNpmPackageCheckerRc,
node_resolver: NodeResolverRc<TNodeResolverEnv>,
- npm_resolver: NpmResolverRc,
+ npm_resolver: NpmPackageFolderResolverRc,
pkg_json_resolver: PackageJsonResolverRc<TNodeResolverEnv>,
) -> Self {
Self {
diff --git a/resolvers/node/lib.rs b/resolvers/node/lib.rs
index 18b0a8536..87bd62994 100644
--- a/resolvers/node/lib.rs
+++ b/resolvers/node/lib.rs
@@ -15,13 +15,14 @@ mod sync;
pub use deno_package_json::PackageJson;
pub use npm::InNpmPackageChecker;
pub use npm::InNpmPackageCheckerRc;
-pub use npm::NpmResolver;
-pub use npm::NpmResolverRc;
+pub use npm::NpmPackageFolderResolver;
+pub use npm::NpmPackageFolderResolverRc;
pub use package_json::PackageJsonResolver;
pub use package_json::PackageJsonResolverRc;
pub use package_json::PackageJsonThreadLocalCache;
pub use path::PathClean;
pub use resolution::parse_npm_pkg_name;
+pub use resolution::resolve_specifier_into_node_modules;
pub use resolution::NodeModuleKind;
pub use resolution::NodeResolution;
pub use resolution::NodeResolutionMode;
diff --git a/resolvers/node/npm.rs b/resolvers/node/npm.rs
index 2132f0b54..ab3a17942 100644
--- a/resolvers/node/npm.rs
+++ b/resolvers/node/npm.rs
@@ -13,10 +13,13 @@ use crate::sync::MaybeSend;
use crate::sync::MaybeSync;
#[allow(clippy::disallowed_types)]
-pub type NpmResolverRc = crate::sync::MaybeArc<dyn NpmResolver>;
+pub type NpmPackageFolderResolverRc =
+ crate::sync::MaybeArc<dyn NpmPackageFolderResolver>;
-pub trait NpmResolver: std::fmt::Debug + MaybeSend + MaybeSync {
- /// Resolves an npm package folder path from an npm package referrer.
+pub trait NpmPackageFolderResolver:
+ std::fmt::Debug + MaybeSend + MaybeSync
+{
+ /// Resolves an npm package folder path from the specified referrer.
fn resolve_package_folder_from_package(
&self,
specifier: &str,
diff --git a/resolvers/node/resolution.rs b/resolvers/node/resolution.rs
index fcff29242..673a61abe 100644
--- a/resolvers/node/resolution.rs
+++ b/resolvers/node/resolution.rs
@@ -41,7 +41,7 @@ use crate::errors::TypesNotFoundErrorData;
use crate::errors::UnsupportedDirImportError;
use crate::errors::UnsupportedEsmUrlSchemeError;
use crate::npm::InNpmPackageCheckerRc;
-use crate::NpmResolverRc;
+use crate::NpmPackageFolderResolverRc;
use crate::PackageJsonResolverRc;
use crate::PathClean;
use deno_package_json::PackageJson;
@@ -101,7 +101,7 @@ pub type NodeResolverRc<TEnv> = crate::sync::MaybeArc<NodeResolver<TEnv>>;
pub struct NodeResolver<TEnv: NodeResolverEnv> {
env: TEnv,
in_npm_pkg_checker: InNpmPackageCheckerRc,
- npm_resolver: NpmResolverRc,
+ npm_pkg_folder_resolver: NpmPackageFolderResolverRc,
pkg_json_resolver: PackageJsonResolverRc<TEnv>,
}
@@ -109,13 +109,13 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
pub fn new(
env: TEnv,
in_npm_pkg_checker: InNpmPackageCheckerRc,
- npm_resolver: NpmResolverRc,
+ npm_pkg_folder_resolver: NpmPackageFolderResolverRc,
pkg_json_resolver: PackageJsonResolverRc<TEnv>,
) -> Self {
Self {
env,
in_npm_pkg_checker,
- npm_resolver,
+ npm_pkg_folder_resolver,
pkg_json_resolver,
}
}
@@ -1126,7 +1126,7 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
mode: NodeResolutionMode,
) -> Result<Url, PackageResolveError> {
let package_dir_path = self
- .npm_resolver
+ .npm_pkg_folder_resolver
.resolve_package_folder_from_package(package_name, referrer)?;
// todo: error with this instead when can't find package
@@ -1412,6 +1412,25 @@ impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
)
}
}
+
+ /// Resolves a specifier that is pointing into a node_modules folder by canonicalizing it.
+ ///
+ /// Returns `None` when the specifier is not in a node_modules folder.
+ pub fn handle_if_in_node_modules(&self, specifier: &Url) -> Option<Url> {
+ // skip canonicalizing if we definitely know it's unnecessary
+ if specifier.scheme() == "file"
+ && specifier.path().contains("/node_modules/")
+ {
+ // Specifiers in the node_modules directory are canonicalized
+ // so canoncalize then check if it's in the node_modules directory.
+ let specifier = resolve_specifier_into_node_modules(specifier, &|path| {
+ self.env.realpath_sync(path)
+ });
+ return Some(specifier);
+ }
+
+ None
+ }
}
fn resolve_bin_entry_value<'a>(
@@ -1660,6 +1679,28 @@ pub fn parse_npm_pkg_name(
Ok((package_name, package_subpath, is_scoped))
}
+/// Resolves a specifier that is pointing into a node_modules folder.
+///
+/// Note: This should be called whenever getting the specifier from
+/// a Module::External(module) reference because that module might
+/// not be fully resolved at the time deno_graph is analyzing it
+/// because the node_modules folder might not exist at that time.
+pub fn resolve_specifier_into_node_modules(
+ specifier: &Url,
+ canonicalize: &impl Fn(&Path) -> std::io::Result<PathBuf>,
+) -> Url {
+ deno_path_util::url_to_file_path(specifier)
+ .ok()
+ // this path might not exist at the time the graph is being created
+ // because the node_modules folder might not yet exist
+ .and_then(|path| {
+ deno_path_util::canonicalize_path_maybe_not_exists(&path, canonicalize)
+ .ok()
+ })
+ .and_then(|path| deno_path_util::url_from_file_path(&path).ok())
+ .unwrap_or_else(|| specifier.clone())
+}
+
fn pattern_key_compare(a: &str, b: &str) -> i32 {
let a_pattern_index = a.find('*');
let b_pattern_index = b.find('*');