Spreading Gulp tasks into multiple files

My Gulpfile was too damn big. To make a change, I had to scroll for miles, often passing the line I needed to edit or losing track of where I was.

To solve this, I started by searching Google for articles and examples written by people who have solved this before. I was most inspired by this simple gist.

I separated my tasks into modules — files containing no more than three tasks and their dependencies. Furthermore, I organized frequently used tasks into folders, and defined those tasks in my main gulpfile.js.

Let me break it down.


My original gulpfile.js looked like this. It was long, overwhelming, and ultimately hard to change, causing me to lose time. After moving tasks into their own files, my gulpfile.js looks like this:

// gulpfile.js
var gulp        = require('gulp');
var runSequence = require('run-sequence');
var requireDir = require('require-dir');
// Require all tasks.
requireDir('./gulp/tasks', { recurse: true });
// Commonly used tasks defined here.
gulp.task('default', function() {
runSequence(
'clean',
[
'jade',
'sass',
'scripts',
'images',
'favicon'
],
'watch',
'connect'
);
});
gulp.task('build', function() {
runSequence(
'clean',
[
'build-images',
'build-scripts',
'build-css'
],
'build-html',
'connect’
);
});

The key here is the require-dir Node package.

npm install --save-dev require-dir

It allows us to include all of our gulp tasks, organized however we’d like, in one single line. The resulting gulpfile is significantly smaller and easier to understand. By defining the main or most commonly useful tasks it answers the question, “What can I do with this project’s Gulp implementation?”

Should anyone need to edit the “child” tasks, they are located at an easy to remember location:

gulp/tasks/PARENT_TASK_NAME/CHILD_TASK_NAME.js

A directory structure utilizing this technique might look something like this:

build/
gulp/
tasks/
base/
clean.js
connect.js
open.js
watch.js
build/
build-css.js
build-html.js
build-images.js
build-scripts.js
default/
assets.js
jade.js
sass.js
scripts.js
error-handler.js
paths.js
images/
node_modules/
site/
gulpfile.js
package.json

Heres an example task, “jade,” that compiles all of my jade pages, flattens the path, and finally puts the files in the build folder.

// jade.js
var gulp    = require(‘gulp’);
var flatten = require(‘gulp-flatten’);
var connect = require(‘gulp-connect’);
var jade = require(‘gulp-jade’);
var path    = require(‘../../paths.js’);
var error = require(‘../../error-handler.js’);
gulp.task(‘jade’, function() {
return gulp.src( path.to.jade.pages)
.pipe(jade())
.on(‘error’, error.handler)
.pipe(flatten())
.pipe(gulp.dest( path.to.jade.destination))
.pipe(connect.reload( );
});

Each other task follows this pattern, only including the Node packages and modules needed for the task(s), and nothing more.

These snippets are from jade-sass-seed, a boilerplate for small, simple websites that don’t require a JavaScript framework.

If you found this useful, let me know. If you have suggestions or questions submit an issue.