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
If a folder within node_modules
is deleted and npm install is run, npm will not mark any bin files as executable if the symlink to that file still exists in node_modules/.bin
This means that if node_modules
was only partially cleaned up, the re-install can land in a broken state. We're seeing this happen on CI environments with quirks in the caching / preserving of node_module folders.
Expected Behavior
A re-install should also re-update all bin files to have executable permissions.
Steps To Reproduce
- Using Node v16.13.1 (npm v8.1.2) on macOS or Ubuntu
- With the package.json
{
"name": "symlink-test",
"private": true,
"scripts": {
"start": "webpack"
},
"dependencies": {
"webpack": "^5.65.0"
}
}
- Run
npm install
- Run
npm start
and you will seeCLI for webpack must be installed.
(indicating that thewebpack
command successfully executed) - Run
ls -l node_modules/webpack/bin/webpack.js
and see the permissions-rwxr-xr-x
- Run
rm -rf ./node_modules/webpack/
- Run
npm install
- Run
npm start
and you will seesh: path/to/node_modules/.bin/webpack: Permission denied
- Run
ls -l node_modules/webpack/bin/webpack.js
and see the permissions-rw-r--r--
Previous NPM versions
Following the above steps in npm 6 or npm 7 will not throw the error, and using ls -l node_modules/webpack/bin/webpack.js
will always show the permissions -rwxr-xr-x
, even on this partial install state.
Environment
- npm: v8.1.2
- Node: v16.13.1
- OS: macOS 11.6
- platform: Macbook Pro
- npm config:
; "user" config from /Users/liambigelow/.npmrc
//npm.pkg.github.com/:_authToken = (protected)
//registry.npmjs.org/:_authToken = (protected)
; node bin location = /Users/liambigelow/.nvm/versions/node/v16.13.1/bin/node
; cwd = /Users/liambigelow/tmp/symtest3
; HOME = /Users/liambigelow
; Run `npm config ls -l` to show all defaults.
NOTE: This behavior was initially observed on Ubuntu images running inside Docker. I am reproducing it on a Macbook Pro.