Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does "npm install" rewrite package-lock.json?

I just recently upgraded to npm@5. I now have a package-lock.json file with everything from package.json. I would expect that, when I run npm install that the dependency versions would be pulled from the lock file to determine what should be installed in my node_modules directory. What's strange is that it actually ends up modifying and rewriting my package-lock.json file.

For example, the lock file had typescript specified to be at version 2.1.6. Then, after the npm install command, the version was changed to 2.4.1. That seems to defeat the whole purpose of a lock file.

What am I missing? How do I get npm to actually respect my lock file?

like image 538
Viper Bailey Avatar asked Jul 10 '17 21:07

Viper Bailey


People also ask

Why does npm install update package lock json?

The purpose of package-lock. json is to describe the exact dependency tree that was used by npm to install needed packages and to guarantee a single representation of a dependency tree across deployments and continuous integration. A more detailed description of the file's usage can be found in npm documentation.

What causes package lock json to change?

The reason package-lock. json may change automatically when you run npm install is because NPM is updating the package-lock. json file to accurately reflect all the dependencies it has downloaded since it may have gotten more up-to-date versions of some of them. Once NPM updates the package-lock.

Does npm install create package lock json?

npm install is not deterministic, but it generates a package-lock. json.

How do I stop json from generating package lock?

Can I remove package lock JSON? delete both node-module and package-lock. json, then run npm install then npm start.


1 Answers

Update 3: As other answers point out as well, the npm ci command got introduced in npm 5.7.0 as additional way to achieve fast and reproducible builds in the CI context. See the documentation and npm blog for further information.


Update 2: The issue to update and clarify the documentation is GitHub issue #18103.


Update 1: The behaviour that was described below got fixed in npm 5.4.2: the currently intended behaviour is outlined in GitHub issue #17979.


Original answer: The behaviour of package-lock.json was changed in npm 5.1.0 as discussed in issue #16866. The behaviour that you observe is apparently intended by npm as of version 5.1.0.

That means that package.json can override package-lock.json whenever a newer version is found for a dependency in package.json. If you want to pin your dependencies effectively, you now must specify the versions without a prefix, e.g., you need to write them as 1.2.0 instead of ~1.2.0 or ^1.2.0. Then the combination of package.json and package-lock.json will yield reproducible builds. To be clear: package-lock.json alone no longer locks the root level dependencies!

Whether this design decision was good or not is arguable, there is an ongoing discussion resulting from this confusion on GitHub in issue #17979. (In my eyes it is a questionable decision; at least the name lock doesn't hold true any longer.)

One more side note: there is also a restriction for registries that don’t support immutable packages, such as when you pull packages directly from GitHub instead of npmjs.org. See this documentation of package locks for further explanation.

like image 161
jotaen Avatar answered Sep 24 '22 14:09

jotaen