01 October 2015

I don’t say it often enough, although I did gush on @sebmck at jsconf2015), I :heart: Babel.

If, like me, you want to…

Babel all the things

…then this post is for you. Let’s Babelify our npm scripts.

If you haven’t used npm scripts for your build/development process yet, this just stands on the shoulders of giants like @linclark’s articles at the npm blog, @keithamus’s amazing article, and numerous examples from the repos of masters like tj. I’m still a noob at the commandline stuff, so if you have suggestions for improvement, please let me know!

  1. Get a package.json if you don’t already have one: npm init.
  2. Install Babel to your project: npm -i --save-dev babel.
  3. Create scripts in a /scripts folder.
  4. Wire it up to npm by editing your package.json file.
  "scripts": {
"myscript": "./scripts/myscript.js",

At the top of your script file, include the shebang #! /usr/bin/env babel-node. Now you can write your script in ESnext syntax. If you aren’t passing flags (-- style arguments), everything will just work from here.

Here’s an example that reads an .env file, spins up redis, then spins up a server.

Here’s the development.env file:


I can invoke this with npm start or npm start <environment>. The argument is passed through.

If you need more control over the execution, you can try using commanderjs.

I created a simple script to create a jwt token for my server based on the .env file specified as well as a user.

After adding this to your package.json scripts, you have to pass flags using --. However, node will intercept its flags first, so don’t repeat any flags listed in node --help (including --help).

For example, npm run jwt -- --help will output node’s help. But npm run jwt -- -h will output commanderjs’s help for our script. That’s the one flag you can’t control because it’s assumed by commanderjs. Here, I’ve used -E to avoid conflict with node’s -e --eval. Creating a token is as simple as npm run jwt -- -u <username>.

Lastly, I created a script to execute my tests and coverage. While it’s a bash one-liner, it’s pretty long and I didn’t want to maintain it in that form. It was hard to break up because of how I loaded the .env file (it was a bash script that exported each variable). It also didn’t manage redis.

"scripts": {
"test-cov": "(. ./test.env && babel-node node_modules/.bin/isparta cover --report text --report html node_modules/.bin/_mocha --compilers js:babel/register)",
"test": "(. ./test.env && _mocha --compilers js:babel/register --reporter spec)",

Was replaced with:

The only take-away here is that because of the execution context, you can’t just use the npm reference of a .bin file, you have to use the full path. Because this script can run on the CI server, and it already has redis, I made the redis commands conditional.


blog comments powered by Disqus