Description
Is there an existing issue for this?
- I have searched the existing issues
This issue exists in the latest npm version
- I am using the latest npm
Current Behavior
When installing an NPM package that contains an npm-shrinkwrap.json, the npm-shrinkwrap seems to be ignored and the latest dependency that adheres to the package.json semver range is installed instead.
This may be related to #4583, but in this case, we're trying to install a tarball (e.g., https://mysite.com/path/here/package-name.tgz
).
If we take a simple package.json:
{
"name": "npm-shrinkwrap-issue",
"version": "1.0.0",
"description": "",
"main": "index.js",
"author": "",
"dependencies": {
"react": "17.0.0"
}
}
Then, if we create an npm-shrinkwrap.json from this package (after npm install), it will explicitly list React at version 17.0.0 inside the npm-shrinkwrap.json (under packages and dependencies):
{
"name": "npm-shrinkwrap-issue",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "npm-shrinkwrap-issue",
"version": "1.0.0",
"dependencies": {
"react": "17.0.0"
}
},
"node_modules/react": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/react/-/react-17.0.0.tgz",
"integrity": "sha512-rG9bqS3LMuetoSUKHN8G3fMNuQOePKDThK6+2yXFWtoeTDLVNh/QCaxT+Jr+rNf4lwNXpx+atdn3Aa0oi8/6eQ==",
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
},
"engines": {
"node": ">=0.10.0"
}
}
// other packages
},
"dependencies": {
"react": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/react/-/react-17.0.0.tgz",
"integrity": "sha512-rG9bqS3LMuetoSUKHN8G3fMNuQOePKDThK6+2yXFWtoeTDLVNh/QCaxT+Jr+rNf4lwNXpx+atdn3Aa0oi8/6eQ==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
}
// other dependencies
}
}
A consuming package will install React@17.0.0 perfectly fine, as the package.json has "17.0.0" explicitly listed.
However, if we update React's version in package.json to "^17.0.0" without updating npm-shrinkwrap.json, the consuming package will install 17.0.2 instead. I'm simplifying the behavior, but this issue is amplified when we have transitive dependencies.
Expected Behavior
The expected behavior is when installing an NPM package with an npm-shrinkwrap.json, the versions of dependencies listed in the npm-shrinkwrap.json are respected. In the given example, React should be installed React at 17.0.0 instead of 17.0.2.
Based on npm-shrinkwrap and package-lock.json vs npm-shrinkwrap.json, is that npm-shrinkwrap.json is publishable so consuming packages can install dependencies based on that shrinkwrap. The registry states "If this field is undefined, the client must determine through other means if a shrinkwrap exists.", but I do not see a way to do this.
Am I understanding shrinkwrap correctly or using anything wrong?
Steps To Reproduce
See the README in making3/npm-shrinkwrap-issue:
Using NPM v8+:
- Clone this repository.
- Run
npm pack
. - In a separate directory, run
npm install /path/to/packed/npm-shrinkwrap-issue-1.0.0.tgz
. - Notice React is installed at version 17.0.2 (or later). (
grep "version" node_modules/react/package.json
)
Environment
- npm: 8.18.0
- Node.js: 18.7.0
- OS Name: macOS Catalina Version 10.15.7
- System Model Name: Macbook Pro
- npm config:
; "user" config from /Users/namehere/.npmrc
//localhost:4873/:_authToken = (protected)
cache = "/Users/namehere/.npm"
fetch-retry-maxtimeout = 10000
fetch-retry-mintimeout = 2000
strict-ssl = true
; node bin location = /Users/namehere/.nvm/versions/node/v18.7.0/bin/node
; node version = v18.7.0
; npm local prefix = /private/tmp/npm-shrinkwrap-issue
; npm version = 8.18.0
; cwd = /private/tmp/npm-shrinkwrap-issue
; HOME = /Users/namehere
; Run `npm config ls -l` to show all defaults.