Running node/npm scripts sequentially on Windows

This is how I’ve traditionally been running node/npm scripts in my package.json file:

"scripts": {
"testRun": "node ./runtest.js && node ./runreports.js",

Running npm run testRun or yarn testRun will run the runtest.js script followed by the runreport.js script, but there’s a catch: the && part of this formulation is actually a Boolean logical AND. Which means that if the first script returns an error code, such as Exit code (1) then the results of that script will evaluate to false, and in that case the the Boolean AND ensures that the second script won’t run at all.

So I tried changing it from a Boolean AND to a Boolean OR, like so:

"scripts": {
"testRun": "node ./runtest.js || node ./runreports.js",

Now my second script runs when the first one errors, but it only runs if that’s the case. If the first script doesn’t return an error then the second one doesn’t run now; not much of an improvement!

Googling around, it seems that a semi-colon is the correct syntax for the second script to run irrespective of what the first one does, e.g:

"scripts”": {
"testRun": "node ./runtest.js; node ./runreports.js",

Great! Or it is if you’re running a unix-style OS such as Mac OS X or Linux. Unfortunately, I was using Windows due to my having committed terrible sins in a former life. Sadly, the semi-colon syntax just won’t work on Windows, because it’s, well…Windows. (Note: I was using the Git Bash shell on Windows 7. I understand that Windows 10 has a proper bash shell of some sort, so maybe the semi-colon syntax does work there.)

I thought about it some more and it occurred to me that because it’s Boolean logic problem, then there ought to be some kind of Boolean logic solution. Indeed, there was!

Now in boolean logic something OR true always results in true, e.g:

true OR true = true
true OR false = true
false OR true = true

Applying that logic to my package.json script, I came up with this:

"scripts": {
testRun: "(node ./runtest.js || true) && node ./runreports.js",

By wrapping the first script call with in some brackets and Boolean ORing it with a true, the result of that bracketed section must always be true. Now my runreports.js script will run no matter what the runtest.js script does.

Further Reading

https://github.com/npm/npm/issues/4040

(Includes a comment from me, offering the solution above. Strangely, nobody there has recognised my genius thus far, but it’s surely only a matter of time 😉 .)