summaryrefslogtreecommitdiff
path: root/cli/resolver.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/resolver.rs')
-rw-r--r--cli/resolver.rs121
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
}
}