How to install the latest SNAPSHOT version in npm? - npm

We have a private nexus repository and publishing all the npm modules there. We have Module A and Module B, B is dependent on A. Here I am getting an issue with installing the latest SNAPSHOT version. For example:
Module A has published versions like
'1.0.0-SNAPSHOT', '1.0.1-SNAPSHOT', and '1.0.0'
In Module B package.json, I added the dependency like
"Module A": "^1.0.0-SNAPSHOT"
As I mentioned "^" in the dependency, it should install the latest version (i.e, 1.0.1-SNAPSHOT), But I am not sure why it is installing '1.0.0' instead '1.0.1-SNAPSHOT.
Your help would be greatly appreciated. Thanks in Advance.

Avoid releasing and using snapshot dependencies. When you publish a release, it should not contain -SNAPSHOT. Referring to a proper release is mandatory in order to be sure you are testing/executing the right code without side effects due to regression problems. You need to know in every moment which version you are using, that is very important, so relying on latest versions of your modules might not be the best solution, it doesn't worth it either if you are precise with major, minor and patch bits in order to avoid breaking changes or unexpected behaviors.
If you really need to develop them together you can use npm link command instead.

Related

Is it possible to blacklist a NPM package version either in the project or on the machine config?

Given the news that npm 5.7.0 had some issues in production, I'm wondering if it's possible to blacklist a package version either in package.json or on the machine level perhaps in .npmrc or .yarnrc.
The behaviour I'm expecting is that upgrades are possible, so this is not a fixed semver version. SemVer has intentionally avoided defining version skipping in the spec because,
SemVer is meant to communicate what type of changes have occurred, not
'how much' change has occurred. If a user wants to know the details of
how much has changed, they should look at the changelog. A long
changelog tells them it's a big update.
But as a user I may know beforehand that I never want this version. For example, never use 5.7.0 but 5.7.1 is ok.
If you have package A that depends on B and B has a known bad version, you can define a version range with a hole in it. See last paragraph of https://docs.npmjs.com/misc/semver. I am not aware of any way to globally black-list such a version on your system however, so if you install A and it doesn't have a version hole on its dependency on B, you might have gotten the bad version, but in the example you state above, the offending version was pulled from publication as the news was released regarding the defect.
One thing you can do is purge your cache of any bad package versions to insure that they can't be used to resolve dependencies.

How to make npm use the lowest version that matches all requirements

We're using NodeJS for some projects and are faced with an issue that must have a simple solution (seeing as nobody else seems to have the problem).
In the packages.json there are a bunch of dependencies mentioned with a minimum version, each of which may have overlapping dependencies of their own. The default way a dependency is added is using the ^ operator which seems to mean 'compatible with' or 'same major version, but minor versions may differ'.
The way I understand npm to work is on npm install to take the highest minor version available that matches. Unfortunately 'compatible with' is not quite as enforced as you'd hope.
The situation this puts us in is that for instance on a developer machine version 1.1.0 is installed, but between development and publishing a new version 1.2.0, that has a bug, is introduced. On our build machine a fresh build is made which ends up using 1.2.0 and we've introduced a bug that wasn't there in development.
We tried changing the ^ operator to = for instance, but this gives us trouble when dependencies have subdependencies that aren't compatible with the requested version.
All in all I'm a bit confused, but this thing keeps biting us anytime something changes since the development machines don't do anything on npm install if the package is already there, but the build machine always gets fresh copies.
I know from NuGet that it always takes the lowest version that matches all combined requirements. Since this is always the same for a given set of dependencies, I much prefer this approach. Is there a way to make npm work like this too?
To answer my own question:
npm has introduced a new command npm ci which does something similar to npm install but enforces that the specific versions are used that were also used when a package was initially added by using the package-lock file.
See https://docs.npmjs.com/cli/ci for more information

Do I need both package-lock.json and package.json?

After updating my NPM to the latest version (from 3.X to 5.2.0) and running npm install on an existing project, I get an auto-created package-lock.json file.
I can tell package-lock.json gives me an exact dependency tree as opposed to package.json.
From that info alone, it seems like package.json is redundant and not needed anymore.
Are both of them necessary for NPM to work?
Is it safe or possible to use only the package-lock.json file?
The docs on package-lock.json (doc1, doc2) doesn't mention anything about that.
Edit:
After some more thinking about it, I came to the conclusion that if someone wants to use your project with an older version of NPM (before 5.x) it would still install all of the dependencies, but with less accurate versions (patch versions)
Do you need both package-lock.json and package.json? No.
Do you need the package.json? Yes.
Can you have a project with only the package-lock.json? No.
The package.json is used for more than dependencies - like defining project properties, description, author & license information, scripts, etc. The package-lock.json is solely used to lock dependencies to a specific version number.
package-lock.json: records the exact version of each installed package which allows you to re-install them. Future installs will be able to build an identical dependency tree.
package.json: records the minimum version you app needs. If you update the versions of a particular package, the change is not going to be reflected here.
If your question is if lock file should be committed to your source control - it should. It will be ignored under certain circumstance.
I found it bloating pull requests and commit history, so if you see it change, do a separate commit for it.

Install Prefer `devDependencies` Over Conflicting `dependencies`

I have a scenario where I want to develop/QA against a different version of the same package that is used on production. I'm trying to manage this in a single package.json file. However, when I add a package to dependencies and devDependencies with different versions, the npm install command prefers the version specified at dependencies. Is there a way to get it to prefer the version installed at devDependencies? Or is there perhaps a different/better way to manage this scenario?
npm link is the preferred solution to this problem.

How do you deal with people removing npm package versions?

Today I found that an npm package version, Babel 6.0.15, that my application relies on had been removed from npm.
This caused compilation failure on a new pc, and I had to go manually find the closest available version for it, and all the cascading version changes it affected on related packages.
What is the best of way of dealing with npm packages, now that I know they can go missing at any time?
Do you check your node_modules folder into source control?
Is there a rule on npm about what versions (major, minor, etc) may be removed by the creator, and which are more 'long term support' and must be retained?
How do you get npm locally to inform you when 'npm update' fails on a new pc, rather than silently failing?
After thinking about this for a while I wrote a blog post summarising what I think is best practice. Reproduced below:
Summary
Specify exact versions of all npm modules, e.g. “alt”: “0.17.8”
Commit your node_modules folder into source control
Don’t use DefinitelyTyped or any other external library Typescript definition tools
Why?
Some of these principles might be controversial, so here’s my reasoning:
Specify exact versions of all npm modules
Semver (semantic versioning) says that breaking changes should occur only if the major version changes. So you should be able to say just “alt”: “0.17”
But I’ve found in practice that even patch changes (bugfixes) can break your application – because libraries that rely on these library often expect some tiny behaviour in a particular version not to change. So in order for all your particular versions of particular libraries to work, they need to rely on exact versions of other libraries.
Commit your node_modules folder into source control
I first assumed that all versions of famous npm libraries would remain there indefinitely. But I then discovered that creators often remove old versions of their software from npm – which then breaks the cascading chain of exact version number dependencies you’ve configured for your app.
Yes, committing all your npm libraries will take up space in your repository, but they’re text files after all, not .DLLs, so they’ll get compressed really small. And the alternative is one day not being able to compile your app at all on a new computer because a library has been completely removed from npm.
Don’t use DefinitelyTyped or any other external library Typescript definition tools
It’s wonderful to be given compile errors for external tools you use. But I’ve found it’s not worth the effort because:
there’s no way to match the definition file version number and npm library version number, so you get definitions that are out of sync with the library you are using
they often have bugs
the type bugs you catch at compile time are probably going to occur in your own app, not in how you call external libraries
Instead of using .d.ts files for external libraries, just say:
declare module 'lodash'
{
let x: any;
export = x;
}
Or use the –allowJS flag in Typescript 1.8 onwards.