mirror of
https://github.com/denoland/deno.git
synced 2025-08-03 18:38:33 +00:00
feat: support node built-in module imports (#17264)
Co-authored-by: David Sherret <dsherret@gmail.com>
This commit is contained in:
parent
cadeaae045
commit
fc2e00152b
32 changed files with 925 additions and 445 deletions
|
@ -14,7 +14,7 @@ pub use cache::NpmCache;
|
|||
pub use registry::NpmPackageVersionDistInfo;
|
||||
pub use registry::NpmRegistryApi;
|
||||
pub use registry::RealNpmRegistryApi;
|
||||
pub use resolution::resolve_npm_package_reqs;
|
||||
pub use resolution::resolve_graph_npm_info;
|
||||
pub use resolution::NpmPackageId;
|
||||
pub use resolution::NpmPackageReference;
|
||||
pub use resolution::NpmPackageReq;
|
||||
|
|
|
@ -1081,7 +1081,7 @@ fn tag_to_version_info<'a>(
|
|||
// explicit version.
|
||||
if tag == "latest" && info.name == "@types/node" {
|
||||
return get_resolved_package_version_and_info(
|
||||
&NpmVersionReq::parse("18.0.0 - 18.8.2").unwrap(),
|
||||
&NpmVersionReq::parse("18.0.0 - 18.11.18").unwrap(),
|
||||
info,
|
||||
parent,
|
||||
);
|
||||
|
|
|
@ -28,7 +28,7 @@ mod specifier;
|
|||
|
||||
use graph::Graph;
|
||||
pub use snapshot::NpmResolutionSnapshot;
|
||||
pub use specifier::resolve_npm_package_reqs;
|
||||
pub use specifier::resolve_graph_npm_info;
|
||||
pub use specifier::NpmPackageReference;
|
||||
pub use specifier::NpmPackageReq;
|
||||
|
||||
|
|
|
@ -168,8 +168,15 @@ impl NpmVersionMatcher for NpmPackageReq {
|
|||
}
|
||||
}
|
||||
|
||||
/// Resolves the npm package requirements from the graph attempting. The order
|
||||
/// returned is the order they should be resolved in.
|
||||
pub struct GraphNpmInfo {
|
||||
/// The order of these package requirements is the order they
|
||||
/// should be resolved in.
|
||||
pub package_reqs: Vec<NpmPackageReq>,
|
||||
/// Gets if the graph had a built-in node specifier (ex. `node:fs`).
|
||||
pub has_node_builtin_specifier: bool,
|
||||
}
|
||||
|
||||
/// Resolves npm specific information from the graph.
|
||||
///
|
||||
/// This function will analyze the module graph for parent-most folder
|
||||
/// specifiers of all modules, then group npm specifiers together as found in
|
||||
|
@ -211,7 +218,7 @@ impl NpmVersionMatcher for NpmPackageReq {
|
|||
///
|
||||
/// Then it would resolve the npm specifiers in each of those groups according
|
||||
/// to that tree going by tree depth.
|
||||
pub fn resolve_npm_package_reqs(graph: &ModuleGraph) -> Vec<NpmPackageReq> {
|
||||
pub fn resolve_graph_npm_info(graph: &ModuleGraph) -> GraphNpmInfo {
|
||||
fn collect_specifiers<'a>(
|
||||
graph: &'a ModuleGraph,
|
||||
module: &'a deno_graph::Module,
|
||||
|
@ -248,6 +255,7 @@ pub fn resolve_npm_package_reqs(graph: &ModuleGraph) -> Vec<NpmPackageReq> {
|
|||
graph: &ModuleGraph,
|
||||
specifier_graph: &mut SpecifierTree,
|
||||
seen: &mut HashSet<ModuleSpecifier>,
|
||||
has_node_builtin_specifier: &mut bool,
|
||||
) {
|
||||
if !seen.insert(module.specifier.clone()) {
|
||||
return; // already visited
|
||||
|
@ -267,12 +275,22 @@ pub fn resolve_npm_package_reqs(graph: &ModuleGraph) -> Vec<NpmPackageReq> {
|
|||
.dependencies
|
||||
.insert(get_folder_path_specifier(specifier));
|
||||
}
|
||||
|
||||
if !*has_node_builtin_specifier && specifier.scheme() == "node" {
|
||||
*has_node_builtin_specifier = true;
|
||||
}
|
||||
}
|
||||
|
||||
// now visit all the dependencies
|
||||
for specifier in &specifiers {
|
||||
if let Some(module) = graph.get(specifier) {
|
||||
analyze_module(module, graph, specifier_graph, seen);
|
||||
analyze_module(
|
||||
module,
|
||||
graph,
|
||||
specifier_graph,
|
||||
seen,
|
||||
has_node_builtin_specifier,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -284,9 +302,16 @@ pub fn resolve_npm_package_reqs(graph: &ModuleGraph) -> Vec<NpmPackageReq> {
|
|||
.collect::<Vec<_>>();
|
||||
let mut seen = HashSet::new();
|
||||
let mut specifier_graph = SpecifierTree::default();
|
||||
let mut has_node_builtin_specifier = false;
|
||||
for root in &root_specifiers {
|
||||
if let Some(module) = graph.get(root) {
|
||||
analyze_module(module, graph, &mut specifier_graph, &mut seen);
|
||||
analyze_module(
|
||||
module,
|
||||
graph,
|
||||
&mut specifier_graph,
|
||||
&mut seen,
|
||||
&mut has_node_builtin_specifier,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,7 +349,10 @@ pub fn resolve_npm_package_reqs(graph: &ModuleGraph) -> Vec<NpmPackageReq> {
|
|||
}
|
||||
}
|
||||
|
||||
result
|
||||
GraphNpmInfo {
|
||||
has_node_builtin_specifier,
|
||||
package_reqs: result,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_folder_path_specifier(specifier: &ModuleSpecifier) -> ModuleSpecifier {
|
||||
|
@ -979,7 +1007,8 @@ mod tests {
|
|||
},
|
||||
)
|
||||
.await;
|
||||
let reqs = resolve_npm_package_reqs(&graph)
|
||||
let reqs = resolve_graph_npm_info(&graph)
|
||||
.package_reqs
|
||||
.into_iter()
|
||||
.map(|r| r.to_string())
|
||||
.collect::<Vec<_>>();
|
||||
|
|
|
@ -95,59 +95,51 @@ impl NpmPackageResolver {
|
|||
no_npm: bool,
|
||||
local_node_modules_path: Option<PathBuf>,
|
||||
) -> Self {
|
||||
Self::new_with_maybe_snapshot(
|
||||
Self::new_inner(cache, api, no_npm, local_node_modules_path, None, None)
|
||||
}
|
||||
|
||||
pub async fn new_with_maybe_lockfile(
|
||||
cache: NpmCache,
|
||||
api: RealNpmRegistryApi,
|
||||
no_npm: bool,
|
||||
local_node_modules_path: Option<PathBuf>,
|
||||
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
|
||||
) -> Result<Self, AnyError> {
|
||||
let maybe_snapshot = if let Some(lockfile) = &maybe_lockfile {
|
||||
if lockfile.lock().overwrite {
|
||||
None
|
||||
} else {
|
||||
Some(
|
||||
NpmResolutionSnapshot::from_lockfile(lockfile.clone(), &api)
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"failed reading lockfile '{}'",
|
||||
lockfile.lock().filename.display()
|
||||
)
|
||||
})?,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Ok(Self::new_inner(
|
||||
cache,
|
||||
api,
|
||||
no_npm,
|
||||
local_node_modules_path,
|
||||
None,
|
||||
)
|
||||
maybe_snapshot,
|
||||
maybe_lockfile,
|
||||
))
|
||||
}
|
||||
|
||||
/// This function will replace current resolver with a new one built from a
|
||||
/// snapshot created out of the lockfile.
|
||||
pub async fn add_lockfile_and_maybe_regenerate_snapshot(
|
||||
&mut self,
|
||||
lockfile: Arc<Mutex<Lockfile>>,
|
||||
) -> Result<(), AnyError> {
|
||||
self.maybe_lockfile = Some(lockfile.clone());
|
||||
|
||||
if lockfile.lock().overwrite {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let snapshot =
|
||||
NpmResolutionSnapshot::from_lockfile(lockfile.clone(), &self.api)
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"failed reading lockfile '{}'",
|
||||
lockfile.lock().filename.display()
|
||||
)
|
||||
})?;
|
||||
if let Some(node_modules_folder) = &self.local_node_modules_path {
|
||||
self.inner = Arc::new(LocalNpmPackageResolver::new(
|
||||
self.cache.clone(),
|
||||
self.api.clone(),
|
||||
node_modules_folder.clone(),
|
||||
Some(snapshot),
|
||||
));
|
||||
} else {
|
||||
self.inner = Arc::new(GlobalNpmPackageResolver::new(
|
||||
self.cache.clone(),
|
||||
self.api.clone(),
|
||||
Some(snapshot),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn new_with_maybe_snapshot(
|
||||
fn new_inner(
|
||||
cache: NpmCache,
|
||||
api: RealNpmRegistryApi,
|
||||
no_npm: bool,
|
||||
local_node_modules_path: Option<PathBuf>,
|
||||
initial_snapshot: Option<NpmResolutionSnapshot>,
|
||||
maybe_lockfile: Option<Arc<Mutex<Lockfile>>>,
|
||||
) -> Self {
|
||||
let process_npm_state = NpmProcessState::take();
|
||||
let local_node_modules_path = local_node_modules_path.or_else(|| {
|
||||
|
@ -177,7 +169,7 @@ impl NpmPackageResolver {
|
|||
local_node_modules_path,
|
||||
api,
|
||||
cache,
|
||||
maybe_lockfile: None,
|
||||
maybe_lockfile,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,12 +312,13 @@ impl NpmPackageResolver {
|
|||
|
||||
/// Gets a new resolver with a new snapshotted state.
|
||||
pub fn snapshotted(&self) -> Self {
|
||||
Self::new_with_maybe_snapshot(
|
||||
Self::new_inner(
|
||||
self.cache.clone(),
|
||||
self.api.clone(),
|
||||
self.no_npm,
|
||||
self.local_node_modules_path.clone(),
|
||||
Some(self.snapshot()),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -336,6 +329,19 @@ impl NpmPackageResolver {
|
|||
pub fn lock(&self, lockfile: &mut Lockfile) -> Result<(), AnyError> {
|
||||
self.inner.lock(lockfile)
|
||||
}
|
||||
|
||||
pub async fn inject_synthetic_types_node_package(
|
||||
&self,
|
||||
) -> Result<(), AnyError> {
|
||||
// add and ensure this isn't added to the lockfile
|
||||
self
|
||||
.inner
|
||||
.add_package_reqs(vec![NpmPackageReq::from_str("@types/node").unwrap()])
|
||||
.await?;
|
||||
self.inner.cache_packages().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl RequireNpmResolver for NpmPackageResolver {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue