npm / node-semver

The semver parser for node (the one npm uses)
ISC License
5.05k stars 492 forks source link

[BUG] wrong results on semver.npmjs.com #729

Open phryneas opened 1 month ago

phryneas commented 1 month ago

Is there an existing issue for this?

Current Behavior

This is not a bug with the semver package, but with https://semver.npmjs.com/

I couldn't find any better place to report this, so I hope I'm right here or the maintainers know where I can report this correctly.

Currently, if you go to https://semver.npmjs.com/ and search for ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0, it misses all React 19 RCs in the results. image

Expected Behavior

Irritatingly, when removing ^18.0.0 from that list, it gives a result that seems correct

image

Steps To Reproduce

go to https://semver.npmjs.com/ and search for ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0

Environment

Firefox

wraithgar commented 1 month ago

This is a subtle one. npm itself includes the latest tag when choosing a version from a range to determine what version to install.

If today you were to set your dependencies like this:

npm pkg set dependencies.react="^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0"

And then ran npm install you would get 18.3.1 in your tree, because that is what is tagged as latest currently. If the latest version is in the acceptable range, it is always used.

$ npm view react dist-tags.latest
18.3.1

The website is showing you all the versions npm would consider given that range. I'm not sure this is the right thing to do, especially as there is no indication on the page that it is taking that into consideration, nor is it trying to tell you what npm would install. npm also includes other things like engines and os to determine what versions it can install, and this page doesn't take any of that into consideration.

We'll leave this open to track what to do here. As of now at least you know why it's doing this.

ljharb commented 1 month ago

Since the latest tag is mutable, i think the current behavior is ideal but perhaps it could use a sentence or two of prose explanation.

phryneas commented 1 month ago

In our case it would be a peerDependency - is it safe to assume that if the user would specify a React 19 RC as a direct dependency while installing our package, npm/semver would honor that and not install react@latest on top?

wraithgar commented 1 month ago

Yes I believe that's what would happen. The latest is picked in the absence of an extant version in the tree. If the extant version satisfies the semver range it is kept, regadless of the latest tag. To put it another way, this logic that looks for latest is only employed when there is not a version of the package already in the tree.

(This example assumes install-links is set to true)

~/D/s/p/sub $ npm pkg set peerDependencies.react="^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0"
~/D/s/p/sub $ cd ..
~/D/s/peerdeps $ npm i ./sub --install-links=true

added 4 packages, and audited 5 packages in 1s

found 0 vulnerabilities
~/D/s/peerdeps $ npm ls react
@gar/peer-deps-test@1.0.0 /Users/wraithgar/Development/scratch/peerdeps
└─┬ @gar/sub-dep-test@1.0.0
  └── react@18.3.1

~/D/s/peerdeps $ npm pkg set dependencies.react="^19.0.0-rc"
~/D/s/peerdeps $ npm i

removed 2 packages, changed 1 package, and audited 3 packages in 784ms

found 0 vulnerabilities
~/D/s/peerdeps $ npm ls react
@gar/peer-deps-test@1.0.0 /Users/wraithgar/Development/scratch/peerdeps
├─┬ @gar/sub-dep-test@1.0.0
│ └── react@19.0.0-rc-fb9a90fa48-20240614 deduped
└── react@19.0.0-rc-fb9a90fa48-20240614
phryneas commented 1 month ago

Okay, that helps a lot - thank you :)