mysticatea / npm-run-all

A CLI tool to run multiple npm-scripts in parallel or sequential.
MIT License
5.72k stars 240 forks source link

Broken with npm@7 when using npx ("Need to install the following packages: run") #209

Open Domiii opened 3 years ago

Domiii commented 3 years ago

After upgrading to npm@7, using npx npm-run-all ... stops execution and asks the user to install some run package (not a thing! don't do it!).

Example Command:

C:\Users\useruser\code\projectname>npx npm-run-all my:script

Need to install the following packages: run Ok to proceed?

Log reveals that execution is broken:

0 verbose cli 'C:\Users\useruser\AppData\Local\Volta\tools\image\node\16.0.0\node_modules\npm\bin\npm-cli.js', 0 verbose cli 'exec', 0 verbose cli '--', 0 verbose cli 'run', 0 verbose cli 'my:script'

Node@{15,16}, NPM@7 (via Volta) OS: Windows 10

Analysis

This happens because run-task.js determines npmPath from the execution of itself. However, in the latest version, if using npx, it will actually resolve to npx-cli.js which then tries to execute npx run ... (instead of npm run ...).

Workaround

Don't use npx. If (like in my case), the binaries did not get linked properly, use this instead:

node node_modules/npm-run-all/bin/npm-run-all -p script1 script2

For a shortcut, you can add the following to your package.json -> scripts:

"nra": "node node_modules/npm-run-all/bin/npm-run-all"

and then:

npm run nra -- -p script1 script2

codejedi365 commented 3 years ago

I have the same issue on Mac OS Big Sur as well. If you accidently say yes to install run then it continues to try to consider each script name as a file module and as expected it can't find it.

$ npx npm-run-all --parallel "test:*"
# should run test:unit and test:lint scripts

instead,

Starting: test:v2
internal/modules/cjs/loader.js:883
  throw err;
  ^

Error: Cannot find module 'Error: Cannot find module '/Users/username/project/test:unit'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:880:15)
    at Function.Module._load (internal/modules/cjs/loader.js:725:27)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}
elwinschmitz commented 3 years ago

The workaround that worked for me was to include an explicit reference to npm with --npm-path npm:

So my package.json looks like:

"scripts": {
  "do:all-the-things": "npx npm-run-all --npm-path npm do:a-thing do:another-thing",
  "do:a-thing": "echo 'thing'",
  "do:another-thing": "echo 'thing'"
}
Maxim-Mazurok commented 3 years ago

The same issue, when running npx -y ts-node --project ./helpers/tsconfig.json "./helpers/spell-check.ts" and using NodeAPI in spell-check.ts.

Using const options: { npmPath: "npm" } helped, thanks @elwinschmitz !

Spent 1.5 hours debugging on Teams call... For some reason, it didn't ask for run to be installed. Maybe, because I was running npx with -y flag? Or because my colleague accepted installation? Not sure, but the symptoms were pretty hard to debug. It said:

Watching C:\ws4\UMP\LicencingService\ClientApp and all sub-directories not excluded by your .gitignore. Will not monitor dotfiles.
Found & ignored ./DAT\npm\node_modules ; is listed in .gitignore
Found & ignored ./node_modules ; is listed in .gitignore

Starting: cspell

and the process never ended.

ejose19 commented 2 years ago

This should be handled by the library here: https://github.com/mysticatea/npm-run-all/blob/bf91f94ce597aa61da37d2e4208ce8c48bc86673/lib/run-task.js#L157

something like:

// Required due to changes in npm@7+
let defaultNpmPath = process.env.npm_execpath;
if (defaultNpmPath && defaultNpmPath.endsWith('npx-cli.js')) {
  defaultNpmPath.replace(/npx-cli\.js$/, 'npm-cli.js');
}
const npmPath = options.npmPath || defaultNpmPath;
mlandisbqs commented 2 years ago

I use npx run-s blah1 blah2 ... all the time from the cli (actually with an even shorter alias) and this hasn't worked since we upgraded node to 16.13.1 a couple of weeks ago. The @Domiii workaround is helpful but does not work once you stray deeper under the package.json directory of the current project (something npx handles).

Edit: @elwinschmitz solution is working for me. Thanks.

JBallin commented 2 years ago

Forking @elwinschmitz's solution, you can instead avoid npx entirely:

"do:all-the-things": "npm-run-all do:a-thing do:another-thing",
mlandisbqs commented 2 years ago

My use case relies on npx... I'm using npm like traditional "make" where I might want to run multiple targets from the cli, sequentially. example:

npx run-s --npm-path clean build install run

^-- where I might not want to have a dedicated package script for every permutation of targets

The alias is now working like this:

alias npr='npx run-s --npm-path npm'

(..although run-s occasionally loses a symlink after cleaning the node_modules and running npm install)

My team uses npm directly instead of relying on tools like grunt, etc. So the package.json already has a pretty comprehensive set of scripts that are responsible for building and running the code.

kanoshin commented 2 years ago

@koba04 this might become a severe security vulnerability if someone figures out the way to put malicious code to the run npm package. Despite run is not updated for 7 years it has 50k+ downloads a week, probably the majority is because people don't pay attention and agree to install it or use npm in non-interactive environments (like Docker) where npx installs required packages automatically.

benjamincburns commented 2 years ago

This cropped up for me in the trufflesuite/truffle monorepo because we were running lerna bootstrap as npx lerna bootstrap to avoid the chicken/egg problem of needing to install lerna as a local dependency before you can bootstrap.

We're a yarn-only project, and switching that command to yarn exec lerna bootstrap worked around this issue.

benjamincburns commented 2 years ago

Swapping out the npx ... command for npm exec -- ... also seems to work around this problem.

bcomnes commented 1 year ago

I'm open to landing a patch to the maintenance fork I have if anyone has a clue how to best fix: https://github.com/bcomnes/npm-run-all2/issues/93#issuecomment-1304280790

I might take a stab myself soon but figured I would put the offer out there in the meantime.

bcomnes commented 1 year ago

Landed a fix for this: https://github.com/bcomnes/npm-run-all2/releases/tag/v6.0.4