isaacs / rimraf

A `rm -rf` util for nodejs
ISC License
5.66k stars 252 forks source link

Rimraf binary attempts to load surprising path #272

Closed cefn closed 1 year ago

cefn commented 1 year ago

During local install of a package folder having rimraf as a dev dependency, rimraf is attempting to access a path which really can't sensibly exist where it's looking for it. One folder above the node_modules/.bin/rimraf file is the node_modules folder which can't be expected to contain rimraf's package.json.

You can see the relative folder structure revealed in this vscode screenshot.

image

The result is the following fatal error when trying to invoke rimraf from a package.json script target...

Error: Cannot find module '../package.json'
Require stack:
- XXX/node_modules/.bin/rimraf
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:931:15)
    at Function.Module._load (internal/modules/cjs/loader.js:774:27)
    at Module.require (internal/modules/cjs/loader.js:1003:19)
    at require (internal/modules/cjs/helpers.js:107:18)
    at Object.<anonymous> (/XXX/node_modules/.bin/rimraf:5:24)
    at Module._compile (internal/modules/cjs/loader.js:1114:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1143:10)
    at Module.load (internal/modules/cjs/loader.js:979:32)
    at Function.Module._load (internal/modules/cjs/loader.js:819:12)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:75:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'XXX/node_modules/.bin/rimraf'
  ]
}
npm ERR! code ELIFECYCLE
isaacs commented 1 year ago

How did you install this? node_modules/.bin/rimraf should be a symlink to the module at node_modules/rimraf/dist/cjs/src/bin.js, and you'll find there is indeed a package.json at node_modules/rimraf/dist/cjs/package.json.

What does ls -laF node_modules/.bin/rimraf report?

isaacs commented 1 year ago

Oh, I see, you're just viewing the file in VSCode. Yes, that's normal.

Node loads symlinks based on their realpath location, so it'll load from the actual module path, not the symlink path. It should work at runtime just fine. (If it doesn't, or if node_modules/.bin/rimraf isn't actually a symlink, then yes, something is very broken.)

cefn commented 1 year ago

I encountered it twice when installing from a package in a monorepo from a clean start (a package which is logically-self-contained with no resolutions elsewhere in the repo).

Eventually found a third git clean and a different install sequence seemed to cause it to go away and it wasn't replicated in CI (where the repo as a whole - its top-level packages and contained packages - get a lerna bootstrap from the beginning).

Because rimraf is called in the package.json "prepare" target as part of the build perhaps something wasn't yet finalised about the installed filesystem when that target runs. If I find the sequence to recreate it again I'll capture the file metadata you describe and report back.

Thanks for taking the time.