Skip to content

Allow prerelease versions when checking peer deps#3361

Merged
bestander merged 2 commits into
yarnpkg:masterfrom
ide:peer-dep-semver
May 12, 2017
Merged

Allow prerelease versions when checking peer deps#3361
bestander merged 2 commits into
yarnpkg:masterfrom
ide:peer-dep-semver

Conversation

@ide

@ide ide commented May 10, 2017

Copy link
Copy Markdown
Contributor

Summary
Uses lower-level APIs in node-semver to allow prerelease versions when checking peer deps. This honors the intent of library authors e.g. when they write a React component that asks for "react": ">=15.0.0" they're saying OK to react@16.0.0 (partly because the React team specifically has said that if you don't have any warnings in version N, then version N+1 should work for you). By extension and modulo bugs, react@16.0.0-alpha works too if the user explicitly installs it.

Fixes #2760

Test plan
Added unit tests for the new semver utility.

Tested in a real project that uses React 16.0.0-alpha.11 and verified I didn't get any peer dep warnings that usually appear from libraries that ask for "react": ">=15.0.0". Downgraded React to 0.14.0 (too low) and saw peer dep warnings come back as expected.

@ide ide force-pushed the peer-dep-semver branch from 699d00c to c91594d Compare May 10, 2017 06:59
Uses lower-level APIs in node-semver to allow prerelease versions when checking peer deps. This honors the intent of library authors e.g. when they write a React component that asks for `"react": ">=15.0.0"` they're saying OK with `react@16.0.0` (partly because the React team specifically has said that if you don't have any warnings in version N, then version N+1 should work for you). By extension and modulo bugs, `react@16.0.0-alpha` works too (if the user explicitly installs it).

Test Plan: Added unit tests for the new semver utility.

Tested in a real project that uses React 16.0.0-alpha.11 and verified I didn't get any peer dep warnings that usually appear from libraries that ask for `"react": ">=15.0.0"`. Downgraded React to 0.14.0 (too low) and saw peer dep warnings come back as expected.
@ide ide force-pushed the peer-dep-semver branch from c91594d to 77e8f26 Compare May 10, 2017 07:00
@bestander

Copy link
Copy Markdown
Member

Thanks, @ide.
Would you fix the lint error please?

@ide ide force-pushed the peer-dep-semver branch from 8acec29 to 40e3387 Compare May 12, 2017 12:32
node-semver converts ~ and ^ ranges into pairs of >= and < ranges but the upper bounds don't properly exclude prerelease versions. For example, "^1.0.0" is converted to ">=1.0.0 <2.0.0", which includes "2.0.0-pre" since prerelease versions are lower than their non-prerelease counterparts. As a practical workaround we make upper-bound ranges exclude prereleases and convert "<2.0.0" to "<2.0.0-0", for example.

Added unit tests as well.
@bestander bestander merged commit 6e54578 into yarnpkg:master May 12, 2017
@ide ide deleted the peer-dep-semver branch May 29, 2017 17:48
@SimenB

SimenB commented Jun 26, 2017

Copy link
Copy Markdown
Contributor

Can this be made to work with engine as well? Haven't actually tested with a pre-release of yarn, but from what I can tell it's separate logic.

export function testEngine(name: string, range: string, versions: Versions, looseSemver: boolean): boolean {
const actual = versions[name];
if (!actual) {
return false;
}
if (!semver.valid(actual, looseSemver)) {
return false;
}
if (semver.satisfies(actual, range, looseSemver)) {
return true;
}
if (name === 'node' && semver.gt(actual, '1.0.0', looseSemver)) {
// WARNING: this is a massive hack and is super gross but necessary for compatibility
// some modules have the `engines.node` field set to a caret version below semver major v1
// eg. ^0.12.0. this is problematic as we enforce engines checks and node is now on version >=1
// to allow this pattern we transform the node version to fake ones in the minor range 10-13
const major = semver.major(actual, looseSemver);
const fakes = [`0.10.${major}`, `0.11.${major}`, `0.12.${major}`, `0.13.${major}`];
for (const actualFake of fakes) {
if (semver.satisfies(actualFake, range, looseSemver)) {
return true;
}
}
}
// incompatible version
return false;
}

$ node --version
v8.2.0-rc.1
$ yarn
yarn install v0.24.6
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
error ansi-styles@3.0.0: The engine "node" is incompatible with this module. Expected version ">=4".
error Found incompatible module
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

EDIT: Workaround: YARN_IGNORE_ENGINES=true yarn (it was a lerna repo, so just --ignore-engines didn't work)

@bestander

Copy link
Copy Markdown
Member

@SimenB I think it is a good idea, would you send a PR?

ramonclaudio added a commit to ramonclaudio/bun-fork that referenced this pull request Apr 18, 2026
Prerelease versions like `56.0.0-canary-20260212-4f61309` incorrectly
trigger "incorrect peer dependency" warnings when checked against ranges
like `>=14.0.4` or `*`. The strict semver `pre_matched` gate in
`List.satisfiesPre` requires comparators to share the same
major.minor.patch with a prerelease tag, which fails for ranges without
prerelease comparators.

Yarn v1 fixed the same issue in 2017 (yarnpkg/yarn#3361) via
`satisfiesWithPrereleases`. node-semver exposes
`{ includePrerelease: true }` as a built-in option. npm/rfcs#397 has
been open since 2021 proposing similar semantics.

Add `satisfiesIncludePrerelease` methods to `List` and `Group` in
`SemverQuery.zig` that skip the `pre_matched` gate, then call from
`resolutionSatisfiesDependency` which is exclusively used for peer
dependency validation. Strict semver resolution path stays strict.

Fixes oven-sh#29444
Relates to oven-sh#26076, oven-sh#15711
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants