You probably have something like:
"typescript":"~2.1.6"
in your package.json
which npm updates to the latest minor version, in your case being 2.4.1
Edit: Question from OP
But that doesn't explain why "npm install" would change the lock file. Isn't the lock file meant to create a reproducible build? If so, regardless of the semver value, it should still use the same 2.1.6 version.
Answer:
This is intended to lock down your full dependency tree. Let's say
typescript v2.4.1
requireswidget ~v1.0.0
. When you npm install it grabswidget v1.0.0
. Later on your fellow developer (or CI build) does an npm install and getstypescript v2.4.1
butwidget
has been updated towidget v1.0.1
. Now your node module are out of sync. This is whatpackage-lock.json
prevents.Or more generally:
As an example, consider
package A:
{ "name": "A", "version": "0.1.0", "dependencies": { "B": "<0.1.0" } }
package B:
{ "name": "B", "version": "0.0.1", "dependencies": { "C": "<0.1.0" } }
and package C:
{ "name": "C", "version": "0.0.1" }
If these are the only versions of A, B, and C available in the registry, then a normal npm install A will install:
[email protected] -- [email protected] -- [email protected]
However, if [email protected] is published, then a fresh npm install A will install:
[email protected] -- [email protected] -- [email protected] assuming the new version did not modify B's dependencies. Of course, the new version of B could include a new version of C and any number of new dependencies. If such changes are undesirable, the author of A could specify a dependency on [email protected]. However, if A's author and B's author are not the same person, there's no way for A's author to say that he or she does not want to pull in newly published versions of C when B hasn't changed at all.
OP Question 2: So let me see if I understand correctly. What you're saying is that the lock file specifies the versions of the secondary dependencies, but still relies on the fuzzy matching of package.json to determine the top-level dependencies. Is that accurate?
Answer: No. package-lock locks the entire package tree, including the root packages described in
package.json
. Iftypescript
is locked at2.4.1
in yourpackage-lock.json
, it should remain that way until it is changed. And lets say tomorrowtypescript
releases version2.4.2
. If I checkout your branch and runnpm install
, npm will respect the lockfile and install2.4.1
.
More on package-lock.json
:
package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.
This file is intended to be committed into source repositories, and serves various purposes:
Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies.
Provide a facility for users to "time-travel" to previous states of node_modules without having to commit the directory itself.
To facilitate greater visibility of tree changes through readable source control diffs.
And optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages.