denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
97.29k stars 5.36k forks source link

Enable BYONM by default for Deno 2 #23151

Closed bartlomieju closed 1 month ago

bartlomieju commented 7 months ago

For Deno 2 we want to enable BYONM (bring your own node modules) by default as we found that it greatly increases compatibility with multiple existing frameworks - eg. it makes frameworks like Solid or Next.js work OOTB in Deno.

Additional advantage is that it makes it much easier to explain dependency management in Deno, when running Node.js projects in Deno or migrating from Node.js to Deno. There will be 3 "modes":

  1. Deno-first - you can use jsr:/npm:/http:/https: specifiers, fully managed by Deno with autoinstallation. This is the current default.
  2. Node-first - this is the current --unstable-byonm mode - the npm dependencies are managed by a package manager (currently npm/yarn/pnpm). We will add proper support with deno add/deno install that will create a compatible node_modules/ directory structure. This is the most compatible way to run multiple popular frameworks
  3. Mixed/migration mode - you can run an existing Node.js project and start migrating it gradually to Deno, by mixing Node-first with Deno-first dependency management - eg. you can only migrate a "tools/" directory to be Deno first, by delimiting certain directory by putting deno.json file in that directory.

Mode 3 requires more work by providing helpful errors messages guiding towards proper solution.

Before we enable BYONM by default, we're gonna make it default when DENO_FUTURE=1 env var is present so that users can start using it immediately and provide feedback.

This change will allow us to limit some of internal complexity by removing one of the npm resolvers we have.

kuchta commented 7 months ago

I'm not sure if enabling multiple config files in the project is a good approch. I think it would be more natural to port one dependency than one source tree at the time if it's even feasible. Like if there is package.json present, manage stated dependencies there in node_modules and the rest in Deno way defaulting to resolve import specifiers in Node way so that the user could migrate one dependency at the time by deleting corresponding dependency from package.json and making needed source changes?

birkskyum commented 6 months ago

just an observation, but it seems like there is a push towards corepack compatibility in the node ecosystem, which might be worth having that in mind here.

Relevant links

karfau commented 6 months ago

What is the current status regardigng deno deploy and this feature? Can I only use this locally? Can I add a build script or use deployctl in some way that this would be "resolved before deploying"?

What I already tried:

I found a solution that works for me: In addition to the config above, I write the npm specifiers into the import map, as part of a script that runs after installing any dependency using pnpm (part of prepare script). This way I can use "bare specifiers" inside the code.

But I'm still curios if there is a better solution.

dsherret commented 1 month ago

I think we can close this one now.