Skip to content

Commit 011a634

Browse files
authored
Implements optional peer dependencies (#6671)
* Implements optional peer dependencies * Implements the new peerDependenciesMeta field * Runs prettier * Updates the changelog * Fixes flow
1 parent 066f0c8 commit 011a634

File tree

8 files changed

+85
-1
lines changed

8 files changed

+85
-1
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ Please add one entry in this file for each change in Yarn's behavior. Use the sa
44

55
## Master
66

7+
- Implements a new `package.json` field: `peerDependenciesMeta`
8+
9+
[#6671](https://github.com/yarnpkg/yarn/pull/6671) - [**Maël Nison**](https://twitter.com/arcanis)
10+
11+
- Adds an `optional` settings to `peerDependenciesMeta` to silence missing peer dependency warnings
12+
13+
[#6671](https://github.com/yarnpkg/yarn/pull/6671) - [**Maël Nison**](https://twitter.com/arcanis)
14+
715
- Implements `yarn policies set-version [range]`. Check [the documentation]() for usage & tips.
816

917
[#6673](https://github.com/yarnpkg/yarn/pull/6673) - [**Maël Nison**](https://twitter.com/arcanis)
@@ -16,6 +24,10 @@ Please add one entry in this file for each change in Yarn's behavior. Use the sa
1624

1725
[#6683](https://github.com/yarnpkg/yarn/issues/6683) - [**Rowan Lonsdale**](https://github.com/hWorblehat)
1826

27+
- Fixes postinstall scripts for third-party packages when they were referencing a binary from their own dependencies
28+
29+
[#6712](https://github.com/yarnpkg/yarn/pull/6712) - [**Maël Nison**](https://twitter.com/arcanis)
30+
1931
## 1.12.3
2032

2133
**Important:** This release contains a cache bump. It will cause the very first install following the upgrade to take slightly more time, especially if you don't use the [Offline Mirror](https://yarnpkg.com/blog/2016/11/24/offline-mirror/) feature. After that everything will be back to normal.

__tests__/commands/install/integration.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,3 +1123,19 @@ test('install will not warn for missing peerDep when both shallower and deeper',
11231123
const warningMessage = messageParts.every(part => stdout.includes(part));
11241124
expect(warningMessage).toBe(false);
11251125
}));
1126+
1127+
test('install will warn for missing peer dependencies', () =>
1128+
runInstall({}, 'missing-peer-dep', (config, reporter, install, getStdout) => {
1129+
const stdout = getStdout();
1130+
const messageParts = reporter.lang('unmetPeer', 'undefined').split('undefined');
1131+
const warningMessage = messageParts.every(part => stdout.includes(part));
1132+
expect(warningMessage).toBe(true);
1133+
}));
1134+
1135+
test('install will not warn for missing optional peer dependencies', () =>
1136+
runInstall({}, 'missing-opt-peer-dep', (config, reporter, install, getStdout) => {
1137+
const stdout = getStdout();
1138+
const messageParts = reporter.lang('unmetPeer', 'undefined').split('undefined');
1139+
const warningMessage = messageParts.every(part => stdout.includes(part));
1140+
expect(warningMessage).toBe(false);
1141+
}));
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "foo",
3+
"version": "1.0.0",
4+
"peerDependencies": {
5+
"bar": "*"
6+
},
7+
"peerDependenciesMeta": {
8+
"bar": {
9+
"optional": true
10+
}
11+
}
12+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "missing-peer-dep",
3+
"dependencies": {
4+
"foo": "file:./foo"
5+
}
6+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "foo",
3+
"version": "1.0.0",
4+
"peerDependencies": {
5+
"bar": "*"
6+
}
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "missing-peer-dep",
3+
"dependencies": {
4+
"foo": "file:./foo"
5+
}
6+
}

src/package-linker.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,11 +595,15 @@ export default class PackageLinker {
595595
resolvePeerModules() {
596596
for (const pkg of this.resolver.getManifests()) {
597597
const peerDeps = pkg.peerDependencies;
598+
const peerDepsMeta = pkg.peerDependenciesMeta;
599+
598600
if (!peerDeps) {
599601
continue;
600602
}
603+
601604
const ref = pkg._reference;
602605
invariant(ref, 'Package reference is missing');
606+
603607
// TODO: We are taking the "shortest" ref tree but there may be multiple ref trees with the same length
604608
const refTree = ref.requests.map(req => req.parentNames).sort((arr1, arr2) => arr1.length - arr2.length)[0];
605609

@@ -618,6 +622,10 @@ export default class PackageLinker {
618622

619623
for (const peerDepName in peerDeps) {
620624
const range = peerDeps[peerDepName];
625+
const meta = peerDepsMeta && peerDepsMeta[peerDepName];
626+
627+
const isOptional = !!(meta && meta.optional);
628+
621629
const peerPkgs = this.resolver.getAllInfoForPackageName(peerDepName);
622630

623631
let peerError = 'unmetPeer';
@@ -649,7 +657,7 @@ export default class PackageLinker {
649657
resolvedPeerPkg.level,
650658
),
651659
);
652-
} else {
660+
} else if (!isOptional) {
653661
this.reporter.warn(
654662
this.reporter.lang(
655663
peerError,

src/types.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@ export type CLIFunction = (config: Config, reporter: Reporter, flags: Object, ar
1313
type _CLIFunctionReturn = boolean;
1414
export type CLIFunctionReturn = ?_CLIFunctionReturn | Promise<?_CLIFunctionReturn>;
1515

16+
export type DependencyMeta = {};
17+
18+
export type DependenciesMeta = {
19+
[name: string]: DependencyMeta,
20+
};
21+
22+
export type PeerDependencyMeta = {
23+
optional?: boolean,
24+
};
25+
26+
export type PeerDependenciesMeta = {
27+
[name: string]: PeerDependencyMeta,
28+
};
29+
1630
// dependency request pattern data structure that's used to request dependencies from a
1731
// PackageResolver
1832
export type DependencyRequestPattern = {
@@ -132,6 +146,9 @@ export type Manifest = {
132146
peerDependencies?: Dependencies,
133147
optionalDependencies?: Dependencies,
134148

149+
dependenciesMeta?: DependenciesMeta,
150+
peerDependenciesMeta?: PeerDependenciesMeta,
151+
135152
bundleDependencies?: Array<string>,
136153
bundledDependencies?: Array<string>,
137154

0 commit comments

Comments
 (0)