From c6d1b0a1ccf45b7819b1e6f1efe8687b240f495a Mon Sep 17 00:00:00 2001 From: David Sherret Date: Wed, 4 Sep 2024 16:00:44 +0200 Subject: fix(byonm): resolve npm deps of jsr deps (#25399) This allows using npm deps of jsr deps without having to add them to the root package.json. Works by taking the package requirement and scanning the `node_modules/.deno` directory for the best matching package, so it relies on deno's node_modules structure. Additionally to make the transition from package.json to deno.json easier, Deno now: 1. Installs npm deps in a deno.json at the same time as installing npm deps from a package.json. 2. Uses the alias in the import map for `node_modules/` for better package.json compatiblity. --- cli/npm/managed/mod.rs | 27 ++++++++++---------- cli/npm/managed/resolvers/local.rs | 50 +++++++++++++++++++++++--------------- cli/npm/managed/resolvers/mod.rs | 7 +++--- 3 files changed, 49 insertions(+), 35 deletions(-) (limited to 'cli/npm/managed') diff --git a/cli/npm/managed/mod.rs b/cli/npm/managed/mod.rs index a0148c648..0be26b785 100644 --- a/cli/npm/managed/mod.rs +++ b/cli/npm/managed/mod.rs @@ -32,9 +32,9 @@ use resolution::AddPkgReqsResult; use crate::args::CliLockfile; use crate::args::LifecycleScriptsConfig; +use crate::args::NpmInstallDepsProvider; use crate::args::NpmProcessState; use crate::args::NpmProcessStateKind; -use crate::args::PackageJsonInstallDepsProvider; use crate::cache::FastInsecureHasher; use crate::http_util::HttpClientProvider; use crate::util::fs::canonicalize_path_maybe_not_exists_with_fs; @@ -45,6 +45,7 @@ use self::cache::NpmCache; use self::registry::CliNpmRegistryApi; use self::resolution::NpmResolution; use self::resolvers::create_npm_fs_resolver; +pub use self::resolvers::normalize_pkg_name_for_node_modules_deno_folder; use self::resolvers::NpmPackageFsResolver; use super::CliNpmResolver; @@ -71,7 +72,7 @@ pub struct CliNpmResolverManagedCreateOptions { pub text_only_progress_bar: crate::util::progress_bar::ProgressBar, pub maybe_node_modules_path: Option, pub npm_system_info: NpmSystemInfo, - pub package_json_deps_provider: Arc, + pub npm_install_deps_provider: Arc, pub npmrc: Arc, pub lifecycle_scripts: LifecycleScriptsConfig, } @@ -97,7 +98,7 @@ pub async fn create_managed_npm_resolver_for_lsp( npm_api, npm_cache, options.npmrc, - options.package_json_deps_provider, + options.npm_install_deps_provider, options.text_only_progress_bar, options.maybe_node_modules_path, options.npm_system_info, @@ -122,7 +123,7 @@ pub async fn create_managed_npm_resolver( npm_api, npm_cache, options.npmrc, - options.package_json_deps_provider, + options.npm_install_deps_provider, options.text_only_progress_bar, options.maybe_node_modules_path, options.npm_system_info, @@ -139,7 +140,7 @@ fn create_inner( npm_api: Arc, npm_cache: Arc, npm_rc: Arc, - package_json_deps_provider: Arc, + npm_install_deps_provider: Arc, text_only_progress_bar: crate::util::progress_bar::ProgressBar, node_modules_dir_path: Option, npm_system_info: NpmSystemInfo, @@ -161,7 +162,7 @@ fn create_inner( let fs_resolver = create_npm_fs_resolver( fs.clone(), npm_cache.clone(), - &package_json_deps_provider, + &npm_install_deps_provider, &text_only_progress_bar, resolution.clone(), tarball_cache.clone(), @@ -175,7 +176,7 @@ fn create_inner( maybe_lockfile, npm_api, npm_cache, - package_json_deps_provider, + npm_install_deps_provider, resolution, tarball_cache, text_only_progress_bar, @@ -261,7 +262,7 @@ pub struct ManagedCliNpmResolver { maybe_lockfile: Option>, npm_api: Arc, npm_cache: Arc, - package_json_deps_provider: Arc, + npm_install_deps_provider: Arc, resolution: Arc, tarball_cache: Arc, text_only_progress_bar: ProgressBar, @@ -286,7 +287,7 @@ impl ManagedCliNpmResolver { maybe_lockfile: Option>, npm_api: Arc, npm_cache: Arc, - package_json_deps_provider: Arc, + npm_install_deps_provider: Arc, resolution: Arc, tarball_cache: Arc, text_only_progress_bar: ProgressBar, @@ -299,7 +300,7 @@ impl ManagedCliNpmResolver { maybe_lockfile, npm_api, npm_cache, - package_json_deps_provider, + npm_install_deps_provider, text_only_progress_bar, resolution, tarball_cache, @@ -476,7 +477,7 @@ impl ManagedCliNpmResolver { if !self.top_level_install_flag.raise() { return Ok(false); // already did this } - let pkg_json_remote_pkgs = self.package_json_deps_provider.remote_pkgs(); + let pkg_json_remote_pkgs = self.npm_install_deps_provider.remote_pkgs(); if pkg_json_remote_pkgs.is_empty() { return Ok(false); } @@ -605,7 +606,7 @@ impl CliNpmResolver for ManagedCliNpmResolver { create_npm_fs_resolver( self.fs.clone(), self.npm_cache.clone(), - &self.package_json_deps_provider, + &self.npm_install_deps_provider, &self.text_only_progress_bar, npm_resolution.clone(), self.tarball_cache.clone(), @@ -616,7 +617,7 @@ impl CliNpmResolver for ManagedCliNpmResolver { self.maybe_lockfile.clone(), self.npm_api.clone(), self.npm_cache.clone(), - self.package_json_deps_provider.clone(), + self.npm_install_deps_provider.clone(), npm_resolution, self.tarball_cache.clone(), self.text_only_progress_bar.clone(), diff --git a/cli/npm/managed/resolvers/local.rs b/cli/npm/managed/resolvers/local.rs index 6ac83ee94..eb6f9de9b 100644 --- a/cli/npm/managed/resolvers/local.rs +++ b/cli/npm/managed/resolvers/local.rs @@ -41,7 +41,7 @@ use node_resolver::errors::ReferrerNotFoundError; use serde::Deserialize; use serde::Serialize; -use crate::args::PackageJsonInstallDepsProvider; +use crate::args::NpmInstallDepsProvider; use crate::cache::CACHE_PERM; use crate::npm::cache_dir::mixed_case_package_name_decode; use crate::npm::cache_dir::mixed_case_package_name_encode; @@ -65,7 +65,7 @@ use super::common::RegistryReadPermissionChecker; pub struct LocalNpmPackageResolver { cache: Arc, fs: Arc, - pkg_json_deps_provider: Arc, + npm_install_deps_provider: Arc, progress_bar: ProgressBar, resolution: Arc, tarball_cache: Arc, @@ -81,7 +81,7 @@ impl LocalNpmPackageResolver { pub fn new( cache: Arc, fs: Arc, - pkg_json_deps_provider: Arc, + npm_install_deps_provider: Arc, progress_bar: ProgressBar, resolution: Arc, tarball_cache: Arc, @@ -92,7 +92,7 @@ impl LocalNpmPackageResolver { Self { cache, fs: fs.clone(), - pkg_json_deps_provider, + npm_install_deps_provider, progress_bar, resolution, tarball_cache, @@ -248,7 +248,7 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver { sync_resolution_with_fs( &self.resolution.snapshot(), &self.cache, - &self.pkg_json_deps_provider, + &self.npm_install_deps_provider, &self.progress_bar, &self.tarball_cache, &self.root_node_modules_path, @@ -412,14 +412,16 @@ fn has_lifecycle_scripts( async fn sync_resolution_with_fs( snapshot: &NpmResolutionSnapshot, cache: &Arc, - pkg_json_deps_provider: &PackageJsonInstallDepsProvider, + npm_install_deps_provider: &NpmInstallDepsProvider, progress_bar: &ProgressBar, tarball_cache: &Arc, root_node_modules_dir_path: &Path, system_info: &NpmSystemInfo, lifecycle_scripts: &LifecycleScriptsConfig, ) -> Result<(), AnyError> { - if snapshot.is_empty() && pkg_json_deps_provider.workspace_pkgs().is_empty() { + if snapshot.is_empty() + && npm_install_deps_provider.workspace_pkgs().is_empty() + { return Ok(()); // don't create the directory } @@ -620,7 +622,7 @@ async fn sync_resolution_with_fs( // 4. Create symlinks for package json dependencies { - for remote in pkg_json_deps_provider.remote_pkgs() { + for remote in npm_install_deps_provider.remote_pkgs() { let remote_pkg = if let Ok(remote_pkg) = snapshot.resolve_pkg_from_pkg_req(&remote.req) { @@ -684,7 +686,7 @@ async fn sync_resolution_with_fs( } // 5. Create symlinks for the remaining top level packages in the node_modules folder. - // (These may be present if they are not in the package.json dependencies, such as ) + // (These may be present if they are not in the package.json dependencies) // Symlink node_modules/.deno//node_modules/ to // node_modules/ let mut ids = snapshot @@ -757,10 +759,10 @@ async fn sync_resolution_with_fs( // 8. Create symlinks for the workspace packages { - // todo(#24419): this is not exactly correct because it should + // todo(dsherret): this is not exactly correct because it should // install correctly for a workspace (potentially in sub directories), // but this is good enough for a first pass - for workspace in pkg_json_deps_provider.workspace_pkgs() { + for workspace in npm_install_deps_provider.workspace_pkgs() { symlink_package_dir( &workspace.target_dir, &root_node_modules_dir_path.join(&workspace.alias), @@ -985,21 +987,31 @@ impl SetupCache { } } +/// Normalizes a package name for use at `node_modules/.deno/@[_]` +pub fn normalize_pkg_name_for_node_modules_deno_folder(name: &str) -> Cow { + let name = if name.to_lowercase() == name { + Cow::Borrowed(name) + } else { + Cow::Owned(format!("_{}", mixed_case_package_name_encode(name))) + }; + if name.starts_with('@') { + name.replace('/', "+").into() + } else { + name + } +} + fn get_package_folder_id_folder_name( folder_id: &NpmPackageCacheFolderId, ) -> String { let copy_str = if folder_id.copy_index == 0 { - "".to_string() + Cow::Borrowed("") } else { - format!("_{}", folder_id.copy_index) + Cow::Owned(format!("_{}", folder_id.copy_index)) }; let nv = &folder_id.nv; - let name = if nv.name.to_lowercase() == nv.name { - Cow::Borrowed(&nv.name) - } else { - Cow::Owned(format!("_{}", mixed_case_package_name_encode(&nv.name))) - }; - format!("{}@{}{}", name, nv.version, copy_str).replace('/', "+") + let name = normalize_pkg_name_for_node_modules_deno_folder(&nv.name); + format!("{}@{}{}", name, nv.version, copy_str) } fn get_package_folder_id_from_folder_name( diff --git a/cli/npm/managed/resolvers/mod.rs b/cli/npm/managed/resolvers/mod.rs index 2dfc323e9..f5d9e4b05 100644 --- a/cli/npm/managed/resolvers/mod.rs +++ b/cli/npm/managed/resolvers/mod.rs @@ -11,10 +11,11 @@ use deno_npm::NpmSystemInfo; use deno_runtime::deno_fs::FileSystem; use crate::args::LifecycleScriptsConfig; -use crate::args::PackageJsonInstallDepsProvider; +use crate::args::NpmInstallDepsProvider; use crate::util::progress_bar::ProgressBar; pub use self::common::NpmPackageFsResolver; +pub use self::local::normalize_pkg_name_for_node_modules_deno_folder; use self::global::GlobalNpmPackageResolver; use self::local::LocalNpmPackageResolver; @@ -27,7 +28,7 @@ use super::resolution::NpmResolution; pub fn create_npm_fs_resolver( fs: Arc, npm_cache: Arc, - pkg_json_deps_provider: &Arc, + npm_install_deps_provider: &Arc, progress_bar: &ProgressBar, resolution: Arc, tarball_cache: Arc, @@ -39,7 +40,7 @@ pub fn create_npm_fs_resolver( Some(node_modules_folder) => Arc::new(LocalNpmPackageResolver::new( npm_cache, fs, - pkg_json_deps_provider.clone(), + npm_install_deps_provider.clone(), progress_bar.clone(), resolution, tarball_cache, -- cgit v1.2.3