FG
💻 Software🛠️ Developer ToolsMicrosoft

[BUG] npm install deletes an existing symlinked node_modules directory

Fresh5 days ago
Mar 14, 20260 views
Confidence Score76%
76%

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

Canonical Fix
Unverified Fix
New Fix – Awaiting Verification

Fix npm install to Preserve Symlinked node_modules Directory

Medium Risk

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. 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.

    javascript
    const 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. 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.

    javascript
    const 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. 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. 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

AC

Alex Chen

2450 rep

Tags

npmpackage-managernodejsrelease-7.xbugneeds-triage