More on portable npm scripts

Following on from my earlier post on the topic of writing portable npm scripts, here’s a few more useful tips.

[UPDATE 2016/03/31: Bash for Windows was announced at Microsoft Build 2016. This exciting feature will allow running of Linux npm script builds with ease. See Scott Hanselman’s blog post]

[UPDATE: 2016/03/29:  The recently released Docker for Windows Beta might be a good alternative to using a VM. It user Hyper-V.]

[UPDATE: 2016/03/29:  This is a comprehensive article on using npm for build]

Copying files

Use the ncp module to copy files. This goes nicely with mkdirp and rimraf  mentioned before.

Setting environment variables

It’s common to have scripts with a command line of the form

This sets the environment variable NODE_ENV for the duration the command runs. In this case it is use to perform a production build with webpack.

Such syntax works fine in bash etc on Linux / OS X but fails on windows where npm scripts always use CMD. One solution is to use the cross-env npm module which uses a regx to find environment settings (and so is probably not fool-proof). Once installed you just prefix your command like so

Running an extra bash process

I use the Git for Windows bash shell for all my development CLI needs on Windows (It is also installed as part of the GitHub Desktop for Windows). This is a port of the mature MSYS / MinGW port of Linux build environments and works pretty well, though some of the commands are old versions.

On Windows, npm ignores the current shell from which you run it and doesn’t pass the shell on to the sub processes as you would expect. However, you can easily run bash as the main command in a npm script (it’s an extra process but that hardly matters). This works as bash sets the path which is then inherited by the cmd subshell in which npm runs your package.json scripts. As a result it’s easy enough to create portable scripts or convert linux based scripts to also run on Windows. You just need to wrap the command in bash -c "...." For example, the above env setting script can be recoded as follows

The only issue i found is the need to carefully quote ” characters. For example here’s a little script to prompt before deploying to GitHub pages (I’m showing the full package.json entry for clarity)

Using a Linux VM

I often use a Linux VM as part of my development. With Vagrent it’s easy to provision a headless VirtualBox (or other) VM that shares the host filespace and exposes a SSH terminal. Thus you can edit using Windows tools like VisualStudio Code yet run everything in the Linux VM. This lets you run local tests in the same VM as a CI or CD system (which will usually be Linux , unless you are using Azure). One easy configuration I’ve used is this Quality Infrastructure from the GPII project.

This entry was posted in development, web, Windows and tagged , , , , . Bookmark the permalink.
Skip to top


Leave a Reply

Your email address will not be published. Required fields are marked *