Node JS on Windows can be a challenge. TBQH Windows can be a challenge. I ran into a sticky problem the other day and thought I would share the solution.

Lets say we’re running a Gulp task to build a Jekyll site. Part of Gulp’s philosophyy is that plugins are a means of last resort, and you should just write straight Node/JS. We can use node’s built in child_process module to run commands just like we were typing them in to the terminal:

var cp = require('child_process');
// later
cp('jekyll', ['build'], {stdio: 'inherit'});
// cool shit happens

This is pretty cool. I was pretty pleased with myself when I was building a Jekyll site (and my Sass) using Gulp. Like all of the cool kids, I wanted to show off my coolness to the folks at work (we use Jekyll for prototyping a lot). Unfortunately when I tried it on my Windows machine in the office, I got this bullshit:

    throw er; // Unhandled 'error' event
Error: spawn ENOENT
    at errnoException (child_process.js:988:11)
    at Process.ChildProcess._handle.onexit (child_process.js:779:34)
HAHAHAHAHA You suck at your job. Why don't you tell your girlfriend to call me when she wants to see a real programmer

Yes. My PC is a dick. I hacked around the problem (by using child_process.exec seen as you ask), but why didn’t it work? Well This week I found out the answer…

Turns out this ENOENT error means that it can’t execute the command. eg. Jekyll doesn’t resolve to an executable file. When we run jekyll from the Command Prompt, it looks for an actual executable and doesn’t find one, but does find a jekyll.bat file and helpfully resolves to that for you.

Node’s child_process doesn’t do that, so you need to do something like this:

cp('jekyll.bat', ['build'], {stdio: 'inherit'});

Hooray! it worked. Oh noees but now it doesn’t work on not-Windows. Sad face. I want portable code dammit! We need it to write jekyll on non-windows systems, and jekyll.bat in windows land. If only there was a way to conditionally set a variable value in Javascript with some kind of ternary operator…

var cp = require('child_process');
// make a variable based ont he system
var jekyll = process.platform === "win32" ? "jekyll.bat" : "jekyll";
// Use that sukka
cp(jekyll, ['build'], {stdio: 'inherit'});
// cool shit happens E V E R Y W H E R E

The resulting Gulpfile as a Gist


Thanks to SpikeMeister off of Stack Overflow (@bighuggies on twitter?) for answering this question