summaryrefslogtreecommitdiff
path: root/cli/proc_state.rs
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2022-08-20 11:31:33 -0400
committerGitHub <noreply@github.com>2022-08-20 11:31:33 -0400
commit87f80ff6be5e2a132b583a9c380fff5db3cb2b07 (patch)
treeb2c43c9004b9ada204f3b5db7c221fa6322f026a /cli/proc_state.rs
parent1ffbd561642d05a05e18ada764d50581dea779ef (diff)
feat(unstable): initial support for npm specifiers (#15484)
Co-authored-by: Bartek IwaƄczuk <biwanczuk@gmail.com>
Diffstat (limited to 'cli/proc_state.rs')
-rw-r--r--cli/proc_state.rs117
1 files changed, 101 insertions, 16 deletions
diff --git a/cli/proc_state.rs b/cli/proc_state.rs
index 590e6a3c9..a314b55d2 100644
--- a/cli/proc_state.rs
+++ b/cli/proc_state.rs
@@ -22,10 +22,15 @@ use crate::graph_util::ModuleEntry;
use crate::http_cache;
use crate::lockfile::as_maybe_locker;
use crate::lockfile::Lockfile;
+use crate::node;
+use crate::npm::GlobalNpmPackageResolver;
+use crate::npm::NpmPackageReference;
+use crate::npm::NpmPackageResolver;
use crate::resolver::ImportMapResolver;
use crate::resolver::JsxResolver;
use deno_core::anyhow::anyhow;
+use deno_core::anyhow::bail;
use deno_core::anyhow::Context;
use deno_core::error::custom_error;
use deno_core::error::AnyError;
@@ -79,6 +84,8 @@ pub struct Inner {
pub compiled_wasm_module_store: CompiledWasmModuleStore,
maybe_resolver: Option<Arc<dyn deno_graph::source::Resolver + Send + Sync>>,
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
+ pub npm_resolver: GlobalNpmPackageResolver,
+ pub cjs_resolutions: Mutex<HashSet<ModuleSpecifier>>,
}
impl Deref for ProcState {
@@ -210,6 +217,8 @@ impl ProcState {
warn!("{}", ignored_options);
}
let emit_cache = EmitCache::new(dir.gen_cache.clone());
+ let npm_resolver =
+ GlobalNpmPackageResolver::from_deno_dir(&dir, cli_options.reload_flag())?;
Ok(ProcState(Arc::new(Inner {
dir,
@@ -232,6 +241,8 @@ impl ProcState {
compiled_wasm_module_store,
maybe_resolver,
maybe_file_watcher_reporter,
+ npm_resolver,
+ cjs_resolutions: Default::default(),
})))
}
@@ -383,8 +394,7 @@ impl ProcState {
&module.specifier,
module.maybe_source.as_ref().unwrap().to_string(),
module.media_type,
- )
- .await?;
+ )?;
let mut graph_data = self.graph_data.write();
graph_data
.add_cjs_esm_translation(&module.specifier, translated_source);
@@ -403,7 +413,7 @@ impl ProcState {
graph_data.entries().map(|(s, _)| s).cloned().collect()
};
- {
+ let npm_package_references = {
let mut graph_data = self.graph_data.write();
graph_data.add_graph(&graph, reload_on_watch);
let check_js = self.options.check_js();
@@ -414,6 +424,21 @@ impl ProcState {
check_js,
)
.unwrap()?;
+ graph_data.npm_package_reqs()
+ };
+
+ if !npm_package_references.is_empty() {
+ self
+ .npm_resolver
+ .add_package_reqs(npm_package_references)
+ .await?;
+ self.npm_resolver.cache_packages().await?;
+
+ // add the builtin node modules to the graph data
+ let node_std_graph = self
+ .create_graph(vec![(compat::MODULE_ALL_URL.clone(), ModuleKind::Esm)])
+ .await?;
+ self.graph_data.write().add_graph(&node_std_graph, false);
}
// type check if necessary
@@ -457,12 +482,48 @@ impl ProcState {
Ok(())
}
+ fn handle_node_resolve_result(
+ &self,
+ result: Result<Option<ResolveResponse>, AnyError>,
+ ) -> Result<ModuleSpecifier, AnyError> {
+ let response = match result? {
+ Some(response) => response,
+ None => bail!("Not found."),
+ };
+ if let ResolveResponse::CommonJs(specifier) = &response {
+ // remember that this was a common js resolution
+ self.cjs_resolutions.lock().insert(specifier.clone());
+ }
+ response.to_result()
+ }
+
pub fn resolve(
&self,
specifier: &str,
referrer: &str,
) -> Result<ModuleSpecifier, AnyError> {
if let Ok(referrer) = deno_core::resolve_url_or_path(referrer) {
+ if self.npm_resolver.in_npm_package(&referrer) {
+ // we're in an npm package, so use node resolution
+ return self
+ .handle_node_resolve_result(node::node_resolve(
+ specifier,
+ &referrer,
+ &self.npm_resolver,
+ ))
+ .with_context(|| {
+ format!(
+ "Could not resolve '{}' from '{}'.",
+ specifier,
+ self
+ .npm_resolver
+ .resolve_package_from_specifier(&referrer)
+ .unwrap()
+ .id
+ )
+ });
+ }
+
let graph_data = self.graph_data.read();
let found_referrer = graph_data.follow_redirect(&referrer);
let maybe_resolved = match graph_data.get(&found_referrer) {
@@ -473,7 +534,19 @@ impl ProcState {
};
match maybe_resolved {
- Some(Resolved::Ok { specifier, .. }) => return Ok(specifier.clone()),
+ Some(Resolved::Ok { specifier, .. }) => {
+ if let Ok(reference) = NpmPackageReference::from_specifier(specifier)
+ {
+ return self
+ .handle_node_resolve_result(node::node_resolve_npm_reference(
+ &reference,
+ &self.npm_resolver,
+ ))
+ .with_context(|| format!("Could not resolve '{}'.", reference));
+ } else {
+ return Ok(specifier.clone());
+ }
+ }
Some(Resolved::Err(err)) => {
return Err(custom_error(
"TypeError",
@@ -555,19 +628,31 @@ impl ProcState {
.map(|im| im.as_resolver())
};
- Ok(
- create_graph(
- roots,
- false,
- maybe_imports,
- &mut cache,
- maybe_resolver,
- maybe_locker,
- None,
- None,
- )
- .await,
+ let graph = create_graph(
+ roots,
+ false,
+ maybe_imports,
+ &mut cache,
+ maybe_resolver,
+ maybe_locker,
+ None,
+ None,
)
+ .await;
+
+ // add the found npm package references to the npm resolver and cache them
+ let mut package_reqs = Vec::new();
+ for (specifier, _) in graph.specifiers() {
+ if let Ok(reference) = NpmPackageReference::from_specifier(&specifier) {
+ package_reqs.push(reference.req);
+ }
+ }
+ if !package_reqs.is_empty() {
+ self.npm_resolver.add_package_reqs(package_reqs).await?;
+ self.npm_resolver.cache_packages().await?;
+ }
+
+ Ok(graph)
}
}