“NPM Scripts vs. Gulp” Round 2, feat. gulp-shelter

2015 was the year I switched from Gulp to “NPM as a build tool”, then gave Gulp4 a try, then started to learn Make, and finally found myself with four different build tools shuffled among my own projects. I wish 2016 will be the year I relieve myself from the burden of choosing the right build tool, and stop rummaging through config files to remember how to effing build! Oh, hello gulp-shelter!

The “NPM as a build tool” revolution

The guide “How to use NPM as a build tool” was a big sensation when it appeared online, and for good reasons. Developers realized that, with just Node installed, they had a very capable build tool available, and that it resulted in significantly shorter build scripts.

Now all it takes to get started and build this project, is simply to…

$ npm install
$ npm run build

Moreover, many Gulp packages wrap other low-level packages (this is the case for gulp-uglify vs. uglify-js, for instance). The increased number of dependencies isn’t the only problem: wrappers also won’t always be up-to-date with latest releases of low-level packages. They sometimes lag behind in terms of features, stability or performances.

The day I wrote my first build+deploy script in a package.json felt really good. I was experimenting with Browserify, Surge.sh and Travis, and I was able to quickly setup continuous-deployment for a small Single Page Application. I even managed to learn a bit of bash magic!
The day I had to revisit these NPM scripts didn’t feel quite as good, though :-(

Maintaining and growing NPM scripts

One day or another, you’ll find yourself with a line in your package.json that looks worse than this:

"browserify": "browserify src/project.js --standalone project --noparse node_modules/dep1/dist/dep1.js node_modules/dep2/dist/dep2.js --dg --debug | exorcist dist/project.js.map > dist/project.js",

How are your teammates and future-self supposed to make any sense of these arguments and cryptic flags? Comments and multi-line strings would certainly help a great deal, but they aren’t available in poor JSON :(

Reusing NPM scripts and not repeating yourself

The only way to make your NPM scripts reusable and DRY is to use config variables.

The syntax is so verbose and ambiguous… that a sure way to save yourself and your team a lot of time is to avoid them altogether!

Learning Bash syntax

The language used in NPM scripts is Bash, which is a rich and powerful language, with a syntax far from JS. Learning another language can surely be personally appealing for a developer. But unless you’re comfortable with being the only one who knows how “the code goes to the cloud”, you’re also making it a pre-requisite for your teammates and contributors. And that doesn’t make them more productive: it simply gets in the way.

Now, learning a bit of Bash should not put anyone off entirely. But learning the difference between (), {}, (()), [] and [[]] will.

Introducing Gulp-Shelter!

This is how I’ll write my build scripts, starting this year.

Gulp-shelter preserves the conciseness of CLI tools, and solves the readability, maintainability, reusability and learnability issues of NPM scripts. It does so by moving your tasks from a JSON file to a JS file, where developers are free to use comments, variables, multi-line strings, templates and a syntax they’re already familiar with.

Tasks are also more discoverable and still don’t require any global packages, thanks to these two NPM scripts:

"scripts": {
"gulp": "gulp",
"help": "gulp --tasks"
},

Now the list of tasks can be discovered by running:

$ npm run help

> project.js@1.0.0 help /home/myself/workspace/project.js
> gulp --tasks
[22:56:47] Tasks for ~/workspace/project.js/gulpfile.js
[22:56:47] ├── build Generate project lib and source-map
[22:56:47] ├── deploy Run by Travis to deploy on Surge
[22:56:47] └── serve Open index.html and live-reload on changes

And any individual task can be run with:

$ npm run gulp -- <task name>

Gulp-shelter is just one npm install away for Node v4+ users, so go try it and let me know once you’ve done something useful with it : )

Do you share our interest in using JS to create simple tools that help creative people out there? Drop us an email: jobs@prototypo.io

My parents were the Pierre & Marie Curie of SEO: you can google me with my first-name.

My parents were the Pierre & Marie Curie of SEO: you can google me with my first-name.