HTML5, CSS3, jQuery, JSON, Responsive Design...

Running node/npm scripts sequentially on Windows

Michael Brown  May 5 2018 10:44:06 PM
Note: this same article also published on Medium yesterday.

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

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

So running npm run testRun or yarn testRun will run the runtest.js script followed by the runreport.js script…sometimes! The catch is that the && part of this formulation is actually a Boolean logical AND. Which means if the first script returns an error code, such as Exit code (1) it evaluates to false and so the second script won’t run at all.

So I tried changing it from a logical AND to a logical 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:

(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!)