Reputation: 2365
According to package-lock.json's documentation
It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.
I'm looking at a package-lock.json file which contains versions like:
"less": "^3.0.4",
"less-loader": "^4.1.0",
"license-webpack-plugin": "^1.3.1",
"lodash": "^4.17.4",
"memory-fs": "^0.4.1
in the requires
block of one of the dependencies.
While the child dependencies of the main project are "locked down" in that there is no version ambiguity, these transitive dependencies are not. But how is npm "able to generate identical trees, regardless of intermediate dependency updates" if any of the dependencies in the tree are subject to interpretation?
Upvotes: 3
Views: 807
Reputation: 2365
According to this thread, in npm@6 there was a change to how the package-lock.json represents dependency versions internally in that it records the originally requested ranged dependency, yet still locks down a specific version.
Previously, the package-lock did not record what version was originally requested by a dependency, only which version it resolved it to at the time of its creation.
Here's example: package-lock.json
// OLD npm format
// Notice that ajv.requires contains specific version for 'fast-json-stable-stringify'
// also notice that 'fast-json-stable-stringify' entry **mentions for the second time** specific version
{
...
"dependencies": {
...
"ajv": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz",
"integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==",
"dev": true,
"requires": {
"fast-deep-equal": "3.1.1",
"fast-json-stable-stringify": "2.1.0",
"json-schema-traverse": "0.4.1",
"uri-js": "4.2.2"
}
},
...
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true
},
...
}
...
}
And here's npm6 approach
// "new" npm format (as of npm@6)
// Notice that ajv.requires is not showing specific versions
// but instead shows same values as package.json contains
// However 'fast-json-stable-stringify' entry contains
// SPECIFIC version to have reproducible build
{
...
"dependencies": {
...
"ajv": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz",
"integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
...
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true
},
...
}
...
}
Upvotes: 2