yarnpkg / berry

📦🐈 Active development trunk for Yarn ⚒
https://yarnpkg.com
BSD 2-Clause "Simplified" License
7.37k stars 1.1k forks source link

[Feature] Automatically install peerDependencies into a separate dependencies key #6292

Open IMalyugin opened 4 months ago

IMalyugin commented 4 months ago

Describe the user story

As a mini-framework developer, i would like to let users only install the desired packages without bloating package.json dependencies with countless transitive and peer dependencies. For example, if I install @scope/redux, I would get @reduxjs/toolkit, react-redux, @scope/redux-tools (listed as peerDependencies) added to special sections of package.json.

Describe the solution you'd like

What if peer dependencies could be more than just a "recommendation". Instead would actually install the dependencies, adding them to a separate section within package.json.

To do this, we would need two new sections, that would be generated during install: peerManagedDependencies & peerManagedDevDependencies

During install yarn should:

  1. Add package to peerManagedDependencies or host package, if (all of the following): 1.1. package is listed in peerDependencies of direct dependency; 1.2. package it is not listed in direct dependencies of host package;

  2. Add package to peerManagedDevDependencies of host package if (all of the following): 1.1. package is listed in peerDependencies of direct devDependency; 1.2. package it is not listed in direct devDependencies of host package;

  3. Install peerManagedDependencies of dependencies tree just like dependencies (along with binaries);

  4. Install peerManagedDevDependencies of dependencies tree just like devDependencies (along with binaries);

  5. Remove package from peerManagedDependencies if it is manually installed in dependencies;

  6. Remove package from peerManagedDevDependencies if it is manually installed in peerDependencies;

Having the given strategy adopted by the community, would allow for clean dependencies/devDependencies sections, only installing what is necessary, while still not introducing any implicit transitive dependencies (aka all the peerDependencies would actually be explicit). This is especially important lately as a lot of maintainers are changing their package structure from single-package to granular monorepositories.

Having a clean peerManaged*Dependencies populated directly in package.json during install prior to publication would remove extra complexity of traveling over packages collecting peerDependencies. And would allow an easy integration for IDe's (processing peerManaged*Dependencies exactly like normal dependencies);

Describe the drawbacks of your solution

This feature requests adds a non standard core behaviour that is not supported by alternative package managers, like npm, although basically peerDependencies are supposed to be manually applied to provide similar result, also some instruments would have to support peerManaged*Dependencies.

Advanced resolution schema would add complexity to yarn installation process.

The question of should peerManaged*Dependencies be cascaded to host package is kind of a cornerstone. So far answer is no, since all the shared packages can still add transitive dependencies in peerDependencies section.

Describe alternatives you've considered

Microsoft once made a package to "extend" package.json: https://github.com/microsoft/package-inherit But inheritance is tricky and limited, it would make dependency management a lot more complicated. On top of that, adding such a behaviour from outside out package manager would require multiple postinstall -> install cycles to lock the proper versions.

I also made countless approaches at hacking transitive binaries via path resolutions as well as provide type hinting for transitive dependencies. The only clear way for now is to just bloat package.json or implement similar plugin on top of double post install hook.