Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] npm deleting contents of local directory #6427

Closed
2 tasks done
getify opened this issue May 5, 2023 · 2 comments
Closed
2 tasks done

[BUG] npm deleting contents of local directory #6427

getify opened this issue May 5, 2023 · 2 comments
Labels
Bug thing that needs fixing Needs Triage needs review for next steps Release 9.x work is associated with a specific npm 9 release

Comments

@getify
Copy link

getify commented May 5, 2023

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

Note: my issue is similar to #4863, but my situation is somewhat different (with similar symptoms), so I am filing this to document my case.

I have a package.json with the following contents:

{
	"name": "whatever",
	"version": "1.0.0",
	"dependencies": {
		"@local/modules": "file:./modules",
                // ...
	},
}

My directory structure is like this:

root
|______ package.json
|
|______ modules
|      |____________ a.js
|      |____________ b.js
|
|______ node_modules
       |_____________ @local
                     |___________ modules -> ../../modules

So I store my app's local modules (not publicly published in any way) in root/modules. But for convenience with require() / import, I make a symlink where root/node_modules/@local/modules --> root/modules.

This lets me do const a = require("@local/modules/a.js") in my code.

All this works fine. And with the "@local/modules": "file:./modules" line in my package.json, npm leaves this directory alone and doesn't empty it out when I'm installing/upgrading other dependency packages.


So then, for even more convenience in my code, I decide to add another symlink: root/node_modules/@ --> root/node_modules/@local/modules. That means I can now do const a = require("@/a.js"), which is so much nicer.

But now, whenever I do an npm install some-package, the CLI tool goes into @/ directory and completely empties it (but leaves it in place). Argh!

Luckily, I had backups of those local modules so I didn't lose them.


I really expected that since the files (a.js and b.js) are covered by a listing in my dependencies, then npm would leave them alone. But since it finds them twice, once as @/a.js and once as @local/modules/a.js, I guess it's not smart enough to correlate.

So I was thinking maybe npm needs me to also list my special @ symlink as a dependency similar to how I listed @local/modules with the file:.. protocol.

Unfortunately, npm chokes whenever I add a line to my dependencies like: "@": "file:./modules". It says that @ is invalid dependency name. WHAT!? WHY!?


Anyway, then I decided maybe I could remove the @ symlink right before installing a package dependency, then restore it right after. Seemed like a job for preinstall / postinstall.

But alas, those scripts don't get run when you do npm install something, only when you run npm install by itself.

So I'm stuck here. How do I get npm to leave my local files alone?

Expected Behavior

I want whatever listing I add to my package.json to tell npm to leave the contents of my local modules directory alone.

Steps To Reproduce

(see above)

Environment

  • npm: 9.6.6
  • Node.js: 16.20.0
  • OS Name: Debian (windows wsl2)
  • System Model Name: Windows Surface Laptop 5
  • npm config:
; "user" config from /tmp/.npmrc

package-lock = false
save = false
umask = 1

; node bin location = /usr/local/bin/node
; node version = v16.20.0
; npm local prefix = /tmp/project
; npm version = 9.6.6
; cwd = /tmp/project
; HOME = /tmp
@getify getify added Bug thing that needs fixing Needs Triage needs review for next steps Release 9.x work is associated with a specific npm 9 release labels May 5, 2023
@wraithgar
Copy link
Member

npm considers itself to be the only thing writing to node_modules. One of the (many) assumptions npm makes based off of that base assumption is that it can derive a package's name by its folder structure inside node_modules. This is why you get the warning about an invalid package name.

Altering the contents of what is in there manually is going to have unintended side effects like this. Having contents inside node_modules that are different than what npm expects is not something we can support.

The other root issue of deleting things from nested links is covered in the other issue.

@getify
Copy link
Author

getify commented May 5, 2023

If @ isn't a valid package name, then why does npm even traverse it as a directory (and delete its contents)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug thing that needs fixing Needs Triage needs review for next steps Release 9.x work is associated with a specific npm 9 release
Projects
None yet
Development

No branches or pull requests

2 participants