From be97170a193e8cecc5ce03ecd3c1d0add4a06bf7 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Wed, 25 Oct 2023 14:39:00 -0400 Subject: feat(unstable): ability to `npm install` then `deno run main.ts` (#20967) This PR adds a new unstable "bring your own node_modules" (BYONM) functionality currently behind a `--unstable-byonm` flag (`"unstable": ["byonm"]` in a deno.json). This enables users to run a separate install command (ex. `npm install`, `pnpm install`) then run `deno run main.ts` and Deno will respect the layout of the node_modules directory as setup by the separate install command. It also works with npm/yarn/pnpm workspaces. For this PR, the behaviour is opted into by specifying `--unstable-byonm`/`"unstable": ["byonm"]`, but in the future we may make this the default behaviour as outlined in https://github.com/denoland/deno/issues/18967#issuecomment-1761248941 This is an extremely rough initial implementation. Errors are terrible in this and the LSP requires frequent restarts. Improvements will be done in follow up PRs. --- cli/npm/managed/resolvers/local.rs | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) (limited to 'cli/npm/managed/resolvers') diff --git a/cli/npm/managed/resolvers/local.rs b/cli/npm/managed/resolvers/local.rs index 2d774518a..a4a8550f1 100644 --- a/cli/npm/managed/resolvers/local.rs +++ b/cli/npm/managed/resolvers/local.rs @@ -36,7 +36,6 @@ use deno_runtime::deno_core::futures; use deno_runtime::deno_fs; use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodeResolutionMode; -use deno_runtime::deno_node::PackageJson; use deno_semver::package::PackageNv; use serde::Deserialize; use serde::Serialize; @@ -181,23 +180,8 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver { } else { Cow::Owned(current_folder.join("node_modules")) }; - let sub_dir = join_package_name(&node_modules_folder, name); - if self.fs.is_dir_sync(&sub_dir) { - // if doing types resolution, only resolve the package if it specifies a types property - if mode.is_types() && !name.starts_with("@types/") { - let package_json = PackageJson::load_skip_read_permission( - &*self.fs, - sub_dir.join("package.json"), - )?; - if package_json.types.is_some() { - return Ok(sub_dir); - } - } else { - return Ok(sub_dir); - } - } - // if doing type resolution, check for the existence of a @types package + // attempt to resolve the types package first, then fallback to the regular package if mode.is_types() && !name.starts_with("@types/") { let sub_dir = join_package_name(&node_modules_folder, &types_package_name(name)); @@ -206,6 +190,11 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver { } } + let sub_dir = join_package_name(&node_modules_folder, name); + if self.fs.is_dir_sync(&sub_dir) { + return Ok(sub_dir); + } + if current_folder == self.root_node_modules_path { bail!( "could not find package '{}' from referrer '{}'.", -- cgit v1.2.3