Is npm install package#latest stable or does it also include alpha/beta version? - npm

I just want some confirmation as I've always been using #latest for a while with my packages and want to know if I'm really installing a stable version or can possibly install a alpha/beta version of the package.
I'm pretty sure this is meant for stable versions as they tell you to install#latest for npm (unless it's special syntax like npm start).
The more I think about it, the more paranoid I get, any confirmation would be greatly appreciated. :)

Using npm install <pkg>#latest is equivalent to using npm install <pkg> by itself or listing * as the dependency version in package.json. npm documents this here:
npm install will use the latest tag by default.
So in practical terms, latest is semantically equivalent to stable.
However, if a prerelease version of a package is published to npm without specifying a prerelease tag such as --beta or --rc, that version becomes the latest by default:
By default, npm publish will tag your package with the latest tag.
As a result, it's possible to mess up and publish a prerelease version that will be installed by default. This happened to Bootstrap in late 2015.
This article from early 2016 by Mike Bostock explains how even specifying alpha or beta as part of the version number won't prevent npm from making that version the latest.
So unfortunately if you want to be certain that you get only stable versions, you need to monitor this manually or trust the package developers to always specify a prerelease tag for non-stable versions.
You can also view the tags assigned for a package like this:
$ npm view express dist-tags
{ latest: '4.16.2', rc: '4.0.0-rc4' }

Related

npm publish : update a version without changing the latest [duplicate]

I can't seem to find information about how npm works with branches within a repository.
Suppose an npm package is currently versioned at: 1.0.5
A major change requires a version change from 1.0.5 => 2.0.0
Some users continue using 1.x.x to avoid breaking changes.
If a bug is discovered in 1.0.5 it needs to be fixed for the 1.x.x users requiring version change from 1.0.5 => 1.0.6
In effect, this is branching. I'd make a git branch for 1.x.x users and continue using git's master branch for 2.x.x
But how does this fit in with npm? Should I publish an older npm version 1.0.6? In that case doesn't 1.0.6 become the latest while actually 2.0.0 should be the default when doing npm install.
I can't find branch related information for npm. I'm sure the above is a common situation but I just can't find any info. Please can someone point me in the right direction.
You are on the right track - you want to publish package#1.0.6 without updating the latest tag. You can do this by supplying a --tag <tagname> argument to npm publish --
cd project
git checkout old-branch
grep version package.json
"version": "1.0.5",
[make changes]
git commit
npm version patch
grep version package.json
"version": "1.0.6",
npm publish --tag old-version
As long as you supply a --tag <tagname> argument to npm publish, the latest tag will not be updated, and people using npm install <package> or npm install <package>#latest will still get the 2.x version.
Note that the tagname has to share a namespace with version numbers, so it's best to choose a tagname that doesn't look like a semver version; avoid '1.0.6' or 'v1.0.6'.
Source: https://docs.npmjs.com/cli/publish
and: https://docs.npmjs.com/getting-started/using-tags

Bug in NPM version - blacklist the patch version

Say we publish an NPM package that ends up having a bug say it is version 1.0.056.
is there a way to tell NPM to blacklist it, meaning if users have this in package.json:
^1.0.05
that it would endeavor to only install 1.0.057 or 1.0.055?
The idea is when you patch the bug, if it doesn't impact any of the exposed API, then not much reason to make a big semver change? Or maybe on the other hand an important bugfix should call for a minor version change?
Obviously NPM doesn't encourage people to delete packages, we want immutability, but unless a user explicitly requests that version, I want NPM to avoid installing it at all costs?
npm deprecate covers a historical version when you discover problem later:
npm deprecate <pkg>[#<version>] <message>
This command will update the npm registry entry for a package, providing a deprecation warning to all who attempt to install it.
If it was only just published (72 hours) then there is also:
npm unpublish [<#scope>/]<pkg>[#<version>]
This removes a package version from the registry, deleting its entry and removing the tarball.
https://www.npmjs.com/policies/unpublish
https://docs.npmjs.com/cli/unpublish

Gulp version 4. Why is it not the 'latest' version?

I am working on a project which has gulp as a dependency. I am looking at updating it to gulp 4. A quick look at the output of npm show gulp#latest shows
...
dist-tags:
latest: 3.9.1 next: 4.0.0
...
I wonder why the gulp team have left latest: 3.9.1 and choose next: 4.0.0, i.e. npm install gulp installs 3.9.1 while to get 4.0.0 one has to ask for npm install gulp#next. Why is the default version still 3.9.1? Is version 4.0.0 still not fully supported or something? I have not found anything regarding this on the gulp website.
From the npm dist-tag docs:
By default, the latest tag is used by npm to identify the current
version of a package, and npm install (without any # or
# specifier) installs the latest tag. Typically, projects only
use the latest tag for stable release versions, and use other tags for
unstable versions such as prereleases.
The next tag is used by some projects to identify the upcoming
version.
By default, other than latest, no tag has any special significance to
npm itself.
In this case latest is 3.x.x and next is 4.x.x As it is following semver, it means that there are backwards incompatible changes. If you check gulpjs.com, the link to the documentation brings you to the 3.x.x docs. It's the authorative version at the moment as set by the gulp maintainers.

NPM always install latest prerelease version

I'm currently setting up pre-releases (under the dev tag) for a new npm package of mine.
In my staging environment, I want npm to always install the latest pre-release version of the 2.0.0 version. Therefore, I specified "<packagename>": ">=2.0.0-dev.0" in the package.json, but npm somehow always installs the 2.0.0-dev.20180806T153307Z.3eaa718.HEAD, even if I do a clean install with removed package-lock.json.
According to the semver-checker my constraint matches the pre-releases published to npm.
I finally found the problem. Because there was no previous non-dev release published to npm for this package, npm always installed the pre-release version connected to the latest tag (see the image above in the question). The solution is to simply publish a fake release under an older version, e.g. 1.9.9. Now, a clean npm install works like expected.

How to generate NPM release candidate version

Say I want to generate a pre-release NPM version.
Originally I have this:
"version": "0.0.1"
I tried:
npm version prepatch
npm version prepatch
npm version preminor
npm version preminor
that gave me this:
v0.0.2-0
v0.0.3-0
v0.1.0-0
v0.2.0-0
Those don't look useful to me, because they always bump up the actual version number, meaning npm version patch and npm version prepatch don't seem to be making much difference.
So my question is - is there an official way to generate an alpha/beta version with npm at the command line?
npm version minor-alpha
npm version minor-beta
npm version minor-rc
something like that?
UPDATE
As of npm 6.3.0-next.0 you can now use --preid when tagging pre-releases with version.
npm version prerelease --preid=next
NPM Link: https://docs.npmjs.com/cli/version
Original answer
Sadly (and a little bit ironic) npm does not fully support all the features of semver!
What you need is a feature called pre-id, found in the semver spec #9. I have submitted a PR to npm to fix it but it was rejected. https://github.com/npm/npm/pull/13794
preids basically allow you to specify an id for a prerelease, for example:
1.0.0-alpha or 1.0.0-alpha.1
Forrest rejected this proposal in a comment writing this:
After some further consideration, and discussion within the team, I've decided that this isn't a change the CLI team is going to land. Working with prerelease versions is tricky, and this feature is enough of an edge case that I think it increases, rather than decreases, the number of opportunities for prerelease versions to be a footgun.
My concern about footguns is connected to the decision, in semver#^4, to make prerelease versions fall outside the range matching for ~ and ^. Were semver's behavior to change, it might make more sense to have a way to opt into (and then increment within) a given prerelease identifier. After watching the travails of the React community in using prerelease versions with peerDependencies and other interrelated suites of packages, it's pretty clear that the current behavior of semver with respect to prerelease versions is of pretty limited usefulness. That means there's a substantial possibility that that behavior may change.
As it stands, though, I think users who want to use prerelease versions are better off using third-party tools like npmversion, or build scripts that use npm version "x.y.z-prealpha.2" (or whatever suits your use case) instead. Thanks for your time, and my apologies for the delay!
As he recommends, to get this working you should be using a tool that does support full semver versioning. I presonally recommend semver package, found in the npm documentation itself here https://docs.npmjs.com/misc/semver
You can use:
npm version prerelease --preid=rc
Result:
v1.0.0-rc.0
Looks like:
npm version prerelease
is basically what I am looking for, but this doesn't add alpha/beta/rc to the version, it just does this x.y.z-n.
npm version prerelease will generate 0.0.0-x version