6

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:

  • util-lib
  • shared-ui --> util-lib (peer-dep)
  • web-app --> shared-lib & util-lib

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

  • When util-lib has a change, it would have version like 4.0.6-1b596d6.0
  • shared-ui has a peer dep version like ^4.0.0
  • Web-App is then changed to "@keth-dev/lerna-demo-util-lib": "4.0.6-1b596d6.0" (see changes

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/lerna-demo-web-app@4.0.5
npm ERR! Found: @keth-dev/lerna-demo-util-lib@4.0.6-1b596d6.0
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/lerna-demo-shared-ui@4.0.4
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

kk-dev11
  • 2,654
  • 5
  • 37
  • 48

1 Answers1

3

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 bar@1.1.0-pre.1 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

Bert.e
  • 107
  • 2
  • 13