Open Domiii opened 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: []
}
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'"
}
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.
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;
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.
Forking @elwinschmitz's solution, you can instead avoid npx
entirely:
"do:all-the-things": "npm-run-all do:a-thing do:another-thing",
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.
@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.
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.
Swapping out the npx ...
command for npm exec -- ...
also seems to work around this problem.
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.
Landed a fix for this: https://github.com/bcomnes/npm-run-all2/releases/tag/v6.0.4
After upgrading to
npm@7
, usingnpx npm-run-all ...
stops execution and asks the user to install somerun
package (not a thing! don't do it!).Example Command:
C:\Users\useruser\code\projectname>npx npm-run-all my:script
Log reveals that execution is broken:
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 usingnpx
, it will actually resolve tonpx-cli.js
which then tries to executenpx run ...
(instead ofnpm 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