Skip to content

Commit 632557a

Browse files
jrylanruyadorno
authored andcommitted
RFC: No auto-install for peerDependencies marked as optional
PR-URL: #224 Credit: @jrylan Close: #224 Reviewed-by: @ruyadorno
1 parent b210e5d commit 632557a

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# No auto-install for peerDependencies marked as optional
2+
3+
## Summary
4+
5+
Avoid automatically installing `peerDependencies` marked as optional using
6+
`peerDependenciesMeta` and `{ "optional": true }`.
7+
8+
## Motivation
9+
10+
Package authors want to specify supported version ranges of
11+
`peerDependencies`. They also want to set some peers as optional with
12+
`peerDependenciesMeta` and `{ "optional": true }` to avoid automatically
13+
installing them when an end-user installs their package.
14+
15+
As an example, let's take a database ORM package. The ORM package could support
16+
upwards of a dozen different databases and require an end-user to install the
17+
database adapter(s) needed for their project. These database adapters could be
18+
huge and could have `peerDependencies`, `postinstall` scripts, and other
19+
requirements.
20+
21+
It could significantly bloat a project's install time and dependency tree to
22+
pull in tons of packages that an end-developer would never use.
23+
24+
## Detailed Explanation
25+
26+
- When a peer dependency is marked as `{ "optional": true }` using
27+
`peerDependenciesMeta`, it should not install automatically.
28+
29+
- `peerDependencies` without a `peerDependenciesMeta` value of
30+
`{ "optional": true }` should still install automatically.
31+
32+
### Example `package.json`
33+
34+
```json
35+
{
36+
"peerDependencies": {
37+
"react": "^17.0.0"
38+
},
39+
"peerDependenciesMeta": {
40+
"react": {
41+
"optional": true
42+
}
43+
}
44+
}
45+
```
46+
47+
## Rationale and Alternatives
48+
49+
Allows package authors to define their supported peer dependency SemVer ranges,
50+
but maintain control over which peers should be auto-installed.
51+
52+
### Option A: Use `{ "autoinstall": false }` instead
53+
54+
Proposal [0025-install-peer-deps][0025-install-peer-deps] by @isaacs.
55+
56+
Providing `{ "autoinstall": false }` in `peerDependenciesMeta` currently has no
57+
effect -- all `peerDependencies` are still installed. If support for
58+
`{ "autoinstall": false }` was implemented, it would provide the same effect
59+
this proposal is requesting.
60+
61+
The only downside with this approach is that the community has already adopted
62+
`{ "optional": true }`. As of npm v6 `{ "optional": true }` is understood as the
63+
way to avoid npm warnings over optional `peerDependencies`.
64+
65+
### Option B: Continue installing all `peerDependencies`
66+
67+
This makes package authoring much more difficult for tools such as ORMs and even
68+
things like shared code quality configuration files. An author could have a
69+
shared ESLint config that optionally peer depends on TypeScript if a project
70+
needs it.
71+
72+
If all `peerDependencies` install automatically regardless of configuration,
73+
package authors would need to release fragmented packages for each peer the
74+
author intended to be optional.
75+
76+
Imagine the extra effort related to managing all aspects of maintaining both
77+
`eslint-config-foo-base` and `eslint-config-foo-typescript`.
78+
79+
It's less than ideal and complicates publishing, to name a few issues:
80+
81+
- Creates lots of noise about which bug tracking issues are where for each
82+
package.
83+
84+
- Opens up the possibility of version mismatching when a user would need to
85+
install both `eslint-config-foo-base` and `eslint-config-foo-typescript`.
86+
87+
- Easy for package authors publishing manually to slip up and forget to publish
88+
all packages.
89+
90+
## Implementation
91+
92+
- The easiest option is to filter out optional `peerDependencies` before
93+
auto-installing in `@npmcli/arborist`.
94+
95+
- Let `@npmcli/arborist` issue warnings and errors for mismatched/unsupported
96+
`peerDependencies` the same as it does now in npm v7.
97+
98+
For example, specifying `{ "react": "^17.0.0" }` defined in `dependencies`
99+
and then installing a package with an exact peer dependency of
100+
`{ "react": "14.0.0" }`, should result in the same exact warnings/errors
101+
regardless of `react` being marked as optional in `peerDependenciesMeta`.
102+
103+
## Prior Art
104+
105+
- [0025-install-peer-deps][0025-install-peer-deps] by @isaacs proposes using
106+
`peerDependenciesMeta` paired with `{ "autoInstall": false }` to achieve the
107+
same effect. Instead, this proposal omits the need for a new field and
108+
leverages the already well-known and used `{ "optional": true }`.
109+
110+
[0025-install-peer-deps]: https://github.com/npm/rfcs/blob/latest/accepted/0025-install-peer-deps.md

0 commit comments

Comments
 (0)