[BUG] npm install deletes an existing symlinked node_modules directory
Problem
Is there an existing issue for this? - [X] I have searched the existing issues Current Behavior If a package contains a node_modules that is symlinked then an npm install will issue the message npm WARN reify Removing non-directory .... and delete the node_modules directory. Expected Behavior A symlinked node_modules directory should be used as is and not recreated - many people symlink node_modules to a local filesystem so that it does not get synced to cloud storage (like Dropbox). I suspect that the npm code is just checking if any existing file object named node_modules is a directory and does not also check to see if the non-directory file object is actually a symlinked directory. Steps To Reproduce cd /tmp mkdir symlinked mkdir z cd z npm init -y ln -s /tmp/symlinked node_modules . npm install lodash Environment - OS: Ubuntu 20.04.1 - Node: 16.7 - npm: 7.21.0
Unverified for your environment
Select your OS to check compatibility.
1 Fix
Fix npm install to Preserve Symlinked node_modules Directory
The current implementation of npm does not differentiate between a regular directory and a symlinked directory when performing the install operation. As a result, if a symlinked node_modules directory is detected, npm mistakenly treats it as a non-directory and removes it, leading to data loss for users relying on symlinked directories for local development.
Awaiting Verification
Be the first to verify this fix
- 1
Modify npm's Directory Check Logic
Update the npm source code to include a check for symlinked directories before executing the removal of the node_modules directory. This can be done by using the fs.lstat method to check if the node_modules path is a symlink.
javascriptconst fs = require('fs'); const path = require('path'); const nodeModulesPath = path.join(process.cwd(), 'node_modules'); fs.lstat(nodeModulesPath, (err, stats) => { if (err) { // Handle error } else if (stats.isSymbolicLink()) { // Preserve symlinked directory } else { // Proceed with removal } }); - 2
Add Unit Tests for Symlink Handling
Create unit tests to ensure that the new logic correctly identifies and preserves symlinked node_modules directories. This will help prevent regressions in future releases.
javascriptconst assert = require('assert'); const fs = require('fs'); describe('npm symlink handling', function() { it('should preserve symlinked node_modules', function() { // Setup a symlink and test the behavior // Assert that the symlink is not removed }); }); - 3
Update Documentation
Revise the npm documentation to inform users about the new behavior regarding symlinked node_modules directories, including any potential caveats or usage recommendations.
- 4
Release a Patch Version
Once the changes have been implemented and tested, release a patch version of npm that includes the fix for the symlink handling issue. Ensure that the release notes clearly outline the changes made.
Validation
To confirm the fix worked, create a symlinked node_modules directory and run 'npm install' to ensure that the directory is preserved without any warnings or errors. Additionally, verify that the expected packages are installed correctly.
Sign in to verify this fix
Environment
Submitted by
Alex Chen
2450 rep