From 1ff525e25b6ca833893c03f720a1298adffb37db Mon Sep 17 00:00:00 2001 From: David Sherret Date: Wed, 4 Oct 2023 23:05:12 -0400 Subject: refactor(node): combine node resolution code for resolving a package subpath from external code (#20791) We had two methods that did the same functionality. --- ext/node/resolution.rs | 180 ++++++++++++++++++++++++------------------------- 1 file changed, 87 insertions(+), 93 deletions(-) (limited to 'ext/node/resolution.rs') diff --git a/ext/node/resolution.rs b/ext/node/resolution.rs index dd89dc1fd..8b09077b6 100644 --- a/ext/node/resolution.rs +++ b/ext/node/resolution.rs @@ -327,18 +327,24 @@ impl NodeResolver { pub fn resolve_npm_reference( &self, - package_folder: &Path, - sub_path: Option<&str>, + package_dir: &Path, + package_subpath: Option<&str>, mode: NodeResolutionMode, permissions: &dyn NodePermissions, ) -> Result, AnyError> { + let package_json_path = package_dir.join("package.json"); + let referrer = ModuleSpecifier::from_directory_path(package_dir).unwrap(); + let package_json = + self.load_package_json(permissions, package_json_path.clone())?; let node_module_kind = NodeModuleKind::Esm; + let package_subpath = package_subpath + .map(|s| format!("./{s}")) + .unwrap_or_else(|| ".".to_string()); let maybe_resolved_path = self - .package_config_resolve( - &sub_path - .map(|s| format!("./{s}")) - .unwrap_or_else(|| ".".to_string()), - package_folder, + .resolve_package_subpath( + &package_json, + &package_subpath, + &referrer, node_module_kind, DEFAULT_CONDITIONS, mode, @@ -346,8 +352,9 @@ impl NodeResolver { ) .with_context(|| { format!( - "Failed resolving package config for '{}'", - package_folder.join("package.json").display() + "Failed resolving package subpath '{}' for '{}'", + package_subpath, + package_json.path.display() ) })?; let resolved_path = match maybe_resolved_path { @@ -440,53 +447,6 @@ impl NodeResolver { } } - fn package_config_resolve( - &self, - package_subpath: &str, - package_dir: &Path, - referrer_kind: NodeModuleKind, - conditions: &[&str], - mode: NodeResolutionMode, - permissions: &dyn NodePermissions, - ) -> Result, AnyError> { - let package_json_path = package_dir.join("package.json"); - let referrer = ModuleSpecifier::from_directory_path(package_dir).unwrap(); - let package_config = - self.load_package_json(permissions, package_json_path.clone())?; - if let Some(exports) = &package_config.exports { - let result = self.package_exports_resolve( - &package_json_path, - package_subpath.to_string(), - exports, - &referrer, - referrer_kind, - conditions, - mode, - permissions, - ); - match result { - Ok(found) => return Ok(Some(found)), - Err(exports_err) => { - if mode.is_types() && package_subpath == "." { - if let Ok(Some(path)) = - self.legacy_main_resolve(&package_config, referrer_kind, mode) - { - return Ok(Some(path)); - } else { - return Ok(None); - } - } - return Err(exports_err); - } - } - } - if package_subpath == "." { - return self.legacy_main_resolve(&package_config, referrer_kind, mode); - } - - Ok(Some(package_dir.join(package_subpath))) - } - /// Checks if the resolved file has a corresponding declaration file. pub(super) fn path_to_declaration_path( &self, @@ -592,8 +552,8 @@ impl NodeResolver { let maybe_resolved = self.resolve_package_target( package_json_path.as_ref().unwrap(), imports.get(name).unwrap().to_owned(), - "".to_string(), - name.to_string(), + "", + name, referrer, referrer_kind, false, @@ -635,8 +595,8 @@ impl NodeResolver { let maybe_resolved = self.resolve_package_target( package_json_path.as_ref().unwrap(), target, - best_match_subpath.unwrap(), - best_match.to_string(), + &best_match_subpath.unwrap(), + best_match, referrer, referrer_kind, true, @@ -665,8 +625,8 @@ impl NodeResolver { fn resolve_package_target_string( &self, target: String, - subpath: String, - match_: String, + subpath: &str, + match_: &str, package_json_path: &Path, referrer: &ModuleSpecifier, referrer_kind: NodeModuleKind, @@ -746,9 +706,9 @@ impl NodeResolver { if subpath.is_empty() { return Ok(resolved_path); } - if invalid_segment_re.is_match(&subpath) { + if invalid_segment_re.is_match(subpath) { let request = if pattern { - match_.replace('*', &subpath) + match_.replace('*', subpath) } else { format!("{match_}{subpath}") }; @@ -767,7 +727,7 @@ impl NodeResolver { }); return Ok(PathBuf::from(replaced.to_string())); } - Ok(resolved_path.join(&subpath).clean()) + Ok(resolved_path.join(subpath).clean()) } #[allow(clippy::too_many_arguments)] @@ -775,8 +735,8 @@ impl NodeResolver { &self, package_json_path: &Path, target: Value, - subpath: String, - package_subpath: String, + subpath: &str, + package_subpath: &str, referrer: &ModuleSpecifier, referrer_kind: NodeModuleKind, pattern: bool, @@ -901,7 +861,7 @@ impl NodeResolver { pub fn package_exports_resolve( &self, package_json_path: &Path, - package_subpath: String, + package_subpath: &str, package_exports: &Map, referrer: &ModuleSpecifier, referrer_kind: NodeModuleKind, @@ -909,16 +869,16 @@ impl NodeResolver { mode: NodeResolutionMode, permissions: &dyn NodePermissions, ) -> Result { - if package_exports.contains_key(&package_subpath) + if package_exports.contains_key(package_subpath) && package_subpath.find('*').is_none() && !package_subpath.ends_with('/') { - let target = package_exports.get(&package_subpath).unwrap().to_owned(); + let target = package_exports.get(package_subpath).unwrap().to_owned(); let resolved = self.resolve_package_target( package_json_path, target, - "".to_string(), - package_subpath.to_string(), + "", + package_subpath, referrer, referrer_kind, false, @@ -977,8 +937,8 @@ impl NodeResolver { let maybe_resolved = self.resolve_package_target( package_json_path, target, - best_match_subpath.unwrap(), - best_match.to_string(), + &best_match_subpath.unwrap(), + best_match, referrer, referrer_kind, true, @@ -1032,7 +992,7 @@ impl NodeResolver { return self .package_exports_resolve( &package_config.path, - package_subpath, + &package_subpath, exports, referrer, referrer_kind, @@ -1065,26 +1025,60 @@ impl NodeResolver { // Package match. let package_json = self.load_package_json(permissions, package_json_path)?; + self.resolve_package_subpath( + &package_json, + &package_subpath, + referrer, + referrer_kind, + conditions, + mode, + permissions, + ) + } + + #[allow(clippy::too_many_arguments)] + fn resolve_package_subpath( + &self, + package_json: &PackageJson, + package_subpath: &str, + referrer: &ModuleSpecifier, + referrer_kind: NodeModuleKind, + conditions: &[&str], + mode: NodeResolutionMode, + permissions: &dyn NodePermissions, + ) -> Result, AnyError> { if let Some(exports) = &package_json.exports { - return self - .package_exports_resolve( - &package_json.path, - package_subpath, - exports, - referrer, - referrer_kind, - conditions, - mode, - permissions, - ) - .map(Some); + let result = self.package_exports_resolve( + &package_json.path, + package_subpath, + exports, + referrer, + referrer_kind, + conditions, + mode, + permissions, + ); + match result { + Ok(found) => return Ok(Some(found)), + Err(exports_err) => { + if mode.is_types() && package_subpath == "." { + if let Ok(Some(path)) = + self.legacy_main_resolve(package_json, referrer_kind, mode) + { + return Ok(Some(path)); + } else { + return Ok(None); + } + } + return Err(exports_err); + } + } } if package_subpath == "." { - return self.legacy_main_resolve(&package_json, referrer_kind, mode); + return self.legacy_main_resolve(package_json, referrer_kind, mode); } - let file_path = package_json.path.parent().unwrap().join(&package_subpath); - + let file_path = package_json.path.parent().unwrap().join(package_subpath); if mode.is_types() { let maybe_declaration_path = self.path_to_declaration_path(file_path, referrer_kind); @@ -1443,14 +1437,14 @@ fn throw_import_not_defined( } fn throw_invalid_package_target( - subpath: String, + subpath: &str, target: String, package_json_path: &Path, internal: bool, referrer: &ModuleSpecifier, ) -> AnyError { errors::err_invalid_package_target( - package_json_path.parent().unwrap().display().to_string(), + &package_json_path.parent().unwrap().display().to_string(), subpath, target, internal, @@ -1478,7 +1472,7 @@ fn throw_invalid_subpath( } fn throw_exports_not_found( - subpath: String, + subpath: &str, package_json_path: &Path, referrer: &ModuleSpecifier, mode: NodeResolutionMode, -- cgit v1.2.3