kk-dev11
kk-dev11

Reputation: 2674

NPM Install pre-release versions for peer dependency

We have a mono-repository using lerna. On every pull request, we would like to create a pre-release version and publish it.

Demo Project for better understanding => react-lerna-demo

Package structure:

Normal releases works just fine. But pre-release has the following problem.

This worked before npm v7. But now it throws an error:

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: @keth-dev/[email protected]
npm ERR! Found: @keth-dev/[email protected]
npm ERR! node_modules/@keth-dev/lerna-demo-util-lib
npm ERR!   @keth-dev/lerna-demo-util-lib@"4.0.6-1b596d6.0" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer @keth-dev/lerna-demo-util-lib@"^4.0.0" from @keth-dev/[email protected]
npm ERR! node_modules/@keth-dev/lerna-demo-shared-ui
npm ERR!   @keth-dev/lerna-demo-shared-ui@"4.0.4" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --no-strict-peer-deps, --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

Build details => https://github.com/keth-dev/react-lerna-demo/runs/5545142338?check_suite_focus=true

Are there any solutions to support dynamic pre-release versions without legacy-peer-deps flag?

semver package provides an option includePrerelease to suppress the strict version match.

If a version has a prerelease tag (for example, 1.2.3-alpha.3) then it will only be allowed to satisfy comparator sets if at least one comparator with the same [major, minor, patch] tuple also has a prerelease tag.

Is there a way to pass this flag while installing using npm?

semver experiment

Upvotes: 7

Views: 1605

Answers (1)

Bert.e
Bert.e

Reputation: 137

My 2 cents here... (might not be an ideal solution)

In order to support dynamic pre-releases that are referenced in peer-dependencies of another dependency without using --legacy-peer-deps, I ended up using the overrides property of package.json.

Here is what the official doc says about overrides:

If you need to make specific changes to dependencies of your dependencies, for example replacing the version of a dependency with a known security issue, replacing an existing dependency with a fork, or making sure that the same version of a package is used everywhere, then you may add an override.

Overrides provide a way to replace a package in your dependency tree with another version, or another package entirely. These changes can be scoped as specific or as vague as desired.

For instance,

{
    "dependencies": {
        "foo": "1.O.0", // has a peer-dependency to bar@^1.0.0
        "bar": "1.1.0-pre.1" // would normaly fail as [email protected] is not part of bar@^1.0.0 according to NPM implementation of semver
    },
    "overrides": {
        "bar": "$bar" // the override is defined as a reference to the dependency
    }
}

Again, that might not be the ideal solution but it works.

However keep in mind that having the override disables the peer dependency validity checks for the bar package completely.

I plan on adapting my tooling in order to prevent overrides during a release build for instance.

Any comment on why I should not do this is welcomed.

Note that there has been discussions last year about this exact issue in the NPM RFC but nothing came out of it: https://github.com/npm/rfcs/pull/397

Upvotes: 6

Related Questions