Publishing versions of a compatibility-library that are specific to ranges of a peer-dependency

(ELLIOTTCABLE) #1

I thought I understood peerDependencies — but apparently I don’t.

  1. I have a compatibility-library, @elliottcable/bs-uchar.
  2. There are, effectively, two concurrent versions of that compat-lib. Let’s call them 0.4.0 and 0.6.0.
  3. Each of those versions works with a very specific, mutually-exclusive subrange of an upstream project — bs-uchar@0.4.0 only works with bs-platform@ ^4.0.0 || ^5.0.0; while bs-uchar@0.6.0 only works with bs-platform@^6.0.0
  4. My consumers are other libraries, using bs-platform. They shouldn’t care about the version of bs-uchar; it should silently upgrade to v0.6.0 if/when they upgrade their dependency on bs-platform to v6.0.0.
  5. Downstream consurmers of those libraries shouldn’t ever hear of, or care about, bs-uchar — it exists to smooth over a missing component of bs-platform.

tl;dr The end-goal is to tell my consumers to depend on bs-uchar@*, and have npm resolve the version correctly according to what version of bs-platform is installed.

Did I communicate all of that well? I can’t, for the life of me, figure out how to make this happen. I tried publishing bs-uchar with a peer dependency on bs-platform, expressing very lenient ranges — with the v6-shim-version peerDepending on "bs-platform": ">=6.0.0", and the v4-shim-version peerDepending on "bs-platform": "^4.0.0 || ^5.0.0". Unfortunately, when I npm install 'bs-uchar@*' in a downstream project, I still get whatever the “latest” version of the compatibility-shim is; not the version that’s … actually compatible.

I tried the same thing with explicit dependencies, but that was worse — that meant downstream consumers got an extra copy of bs-platform (which in this case is especially egregious; it Very Much Does Not play well with incorrect versions of itself scattered thru the dependency-tree.)

Help is very appreciated!

0 Likes

(John Gee) #2

I do not think peerDependencies work the way you hope. They specify what other packages need to be installed for your package to work. They do not specify what version of your package should be installed to work with its peerDependency. Or to put it another way, the peerDependencies are checked to see if everything will work after the install but do not affect the install itself.

A way to solve it might be to write a new version of bs-uchar which detects the version of bs-platform at runtime and modifies its behaviour accordingly.

Otherwise, instructions in your README on what versions are compatible is a low tech approach!

0 Likes

(ELLIOTTCABLE) #3

I was afraid of that, re: README.

So it’s not possible to have a package specified with a lenient version-range, and then have npm deduce the highest satisfying version of a depended-upon package? That seems like pretty basic dependency-resolution functionality, which I’m sure npm must have; I imagine I’m communicating something poorly — or simply doing something wrong, here.

0 Likes