diff options
Diffstat (limited to 'cli/resolver.rs')
-rw-r--r-- | cli/resolver.rs | 121 |
1 files changed, 113 insertions, 8 deletions
diff --git a/cli/resolver.rs b/cli/resolver.rs index f48e62aae..c4037a75a 100644 --- a/cli/resolver.rs +++ b/cli/resolver.rs @@ -13,7 +13,13 @@ use deno_graph::source::ResolveError; use deno_graph::source::Resolver; use deno_graph::source::UnknownBuiltInNodeModuleError; use deno_graph::source::DEFAULT_JSX_IMPORT_SOURCE_MODULE; +use deno_runtime::deno_fs::FileSystem; use deno_runtime::deno_node::is_builtin_node_module; +use deno_runtime::deno_node::NodeResolution; +use deno_runtime::deno_node::NodeResolutionMode; +use deno_runtime::deno_node::NodeResolver; +use deno_runtime::permissions::PermissionsContainer; +use deno_semver::npm::NpmPackageReqReference; use deno_semver::package::PackageReq; use import_map::ImportMap; use std::path::PathBuf; @@ -22,6 +28,7 @@ use std::sync::Arc; use crate::args::package_json::PackageJsonDeps; use crate::args::JsxImportSourceConfig; use crate::args::PackageJsonDepsProvider; +use crate::module_loader::CjsResolutionStore; use crate::npm::CliNpmResolver; use crate::npm::InnerCliNpmResolverRef; use crate::util::sync::AtomicFlag; @@ -99,16 +106,24 @@ impl MappedSpecifierResolver { /// import map, JSX settings. #[derive(Debug)] pub struct CliGraphResolver { + fs: Arc<dyn FileSystem>, mapped_specifier_resolver: MappedSpecifierResolver, maybe_default_jsx_import_source: Option<String>, maybe_jsx_import_source_module: Option<String>, maybe_vendor_specifier: Option<ModuleSpecifier>, + cjs_resolutions: Option<Arc<CjsResolutionStore>>, + node_resolver: Option<Arc<NodeResolver>>, npm_resolver: Option<Arc<dyn CliNpmResolver>>, found_package_json_dep_flag: Arc<AtomicFlag>, bare_node_builtins_enabled: bool, } pub struct CliGraphResolverOptions<'a> { + pub fs: Arc<dyn FileSystem>, + pub cjs_resolutions: Option<Arc<CjsResolutionStore>>, + pub node_resolver: Option<Arc<NodeResolver>>, + pub npm_resolver: Option<Arc<dyn CliNpmResolver>>, + pub package_json_deps_provider: Arc<PackageJsonDepsProvider>, pub maybe_jsx_import_source_config: Option<JsxImportSourceConfig>, pub maybe_import_map: Option<Arc<ImportMap>>, pub maybe_vendor_dir: Option<&'a PathBuf>, @@ -116,15 +131,23 @@ pub struct CliGraphResolverOptions<'a> { } impl CliGraphResolver { - pub fn new( - npm_resolver: Option<Arc<dyn CliNpmResolver>>, - package_json_deps_provider: Arc<PackageJsonDepsProvider>, - options: CliGraphResolverOptions, - ) -> Self { + pub fn new(options: CliGraphResolverOptions) -> Self { + let is_byonm = options + .npm_resolver + .as_ref() + .map(|n| n.as_byonm().is_some()) + .unwrap_or(false); Self { + fs: options.fs, + cjs_resolutions: options.cjs_resolutions, mapped_specifier_resolver: MappedSpecifierResolver::new( options.maybe_import_map, - package_json_deps_provider, + if is_byonm { + // don't resolve from the root package.json deps for byonm + Arc::new(PackageJsonDepsProvider::new(None)) + } else { + options.package_json_deps_provider + }, ), maybe_default_jsx_import_source: options .maybe_jsx_import_source_config @@ -136,7 +159,8 @@ impl CliGraphResolver { maybe_vendor_specifier: options .maybe_vendor_dir .and_then(|v| ModuleSpecifier::from_directory_path(v).ok()), - npm_resolver, + node_resolver: options.node_resolver, + npm_resolver: options.npm_resolver, found_package_json_dep_flag: Default::default(), bare_node_builtins_enabled: options.bare_node_builtins_enabled, } @@ -171,8 +195,15 @@ impl Resolver for CliGraphResolver { &self, specifier: &str, referrer: &ModuleSpecifier, - _mode: ResolutionMode, + mode: ResolutionMode, ) -> Result<ModuleSpecifier, ResolveError> { + fn to_node_mode(mode: ResolutionMode) -> NodeResolutionMode { + match mode { + ResolutionMode::Execution => NodeResolutionMode::Execution, + ResolutionMode::Types => NodeResolutionMode::Types, + } + } + let result = match self .mapped_specifier_resolver .resolve(specifier, referrer)? @@ -200,6 +231,80 @@ impl Resolver for CliGraphResolver { } } + if let Some(resolver) = + self.npm_resolver.as_ref().and_then(|r| r.as_byonm()) + { + match &result { + Ok(specifier) => { + if let Ok(npm_req_ref) = + NpmPackageReqReference::from_specifier(specifier) + { + let package_folder = resolver + .resolve_pkg_folder_from_deno_module_req( + npm_req_ref.req(), + referrer, + )?; + let node_resolver = self.node_resolver.as_ref().unwrap(); + let package_json_path = package_folder.join("package.json"); + if !self.fs.exists_sync(&package_json_path) { + return Err(ResolveError::Other(anyhow!( + "Could not find '{}'. Maybe run `npm install`?", + package_json_path.display() + ))); + } + let maybe_resolution = node_resolver + .resolve_package_subpath_from_deno_module( + &package_folder, + npm_req_ref.sub_path(), + referrer, + to_node_mode(mode), + &PermissionsContainer::allow_all(), + )?; + match maybe_resolution { + Some(resolution) => { + if let Some(cjs_resolutions) = &self.cjs_resolutions { + if let NodeResolution::CommonJs(specifier) = &resolution { + // remember that this was a common js resolution + cjs_resolutions.insert(specifier.clone()); + } + } + + return Ok(resolution.into_url()); + } + None => { + return Err(ResolveError::Other(anyhow!( + "Failed resolving package subpath for '{}' in '{}'.", + npm_req_ref, + package_folder.display() + ))); + } + } + } + } + Err(_) => { + if referrer.scheme() == "file" { + if let Some(node_resolver) = &self.node_resolver { + let node_result = node_resolver.resolve( + specifier, + referrer, + to_node_mode(mode), + &PermissionsContainer::allow_all(), + ); + if let Ok(Some(resolution)) = node_result { + if let Some(cjs_resolutions) = &self.cjs_resolutions { + if let NodeResolution::CommonJs(specifier) = &resolution { + // remember that this was a common js resolution + cjs_resolutions.insert(specifier.clone()); + } + } + return Ok(resolution.into_url()); + } + } + } + } + } + } + result } } |