John Cheesman

An Introduction to Gulp

Code

An overview of the Gulp build system with examples of common tasks.

Gulp is a streaming build system that enables you to quickly setup tasks for managing and processing front end assets. Its functionality comes from an exhaustive library of plugins, which are included as dependencies in your project and can be combined and configured to create complex build processes.

Document Structure

One of the advantages of using a build system like gulp is separating source assets from their production counterparts. In fact, as all of the gulp configuration is stored in your project, there is no need to commit any processed files. If another developer wanted to build the project all they need to do is install the dependencies and run gulp.

Here is an example document structure showing how source assets might be stored:

root/
|-- assets/
|   |-- images/
|   |-- js/
|   |-- scss/
|-- css/
|-- images/
|-- js/

Setup gulp

If you haven’t already, get node and gulp installed and install gulp in your project root. Create gulpfile.js in your project root as well.

Installing Plugins

All of the plugins you will need are available via NPM and should be installed from the terminal like this:

$ npm install [plugin-name] --save-dev

Adding --save-dev will add the plugin to the dependencies list in your package.json file, which means other developers can get all of the project dependencies by running npm install.

Common Tasks

Let’s take a look at some examples of common tasks and how they go together to create a simple build process.

Default Task

The default task is executed by running gulp from the terminal and can be used to run other tasks that make up the default process.

In gulpfile.js we need to include gulp using require() and assign it to a variable. Then we can define the default task, which for now will do nothing.

// Dependencies
var gulp = require('gulp');

// Default task
gulp.task('default', function() {});

Clean task

Before creating production files with gulp it’s a good idea to clear out the destination directories. This will ensure that no files are being overwritten or left from previous builds.

gulp-clean is the ideal plugin for this task, although gulp-rimraf is also recommended. Adding the read: false option speeds things up by preventing the contents of the source paths from being checked, which is fine if you don’t want to do anything with them after removal.

// Dependencies
var gulp  = require('gulp'),
    clean = require('gulp-clean');

// Clean task
gulp.task('clean', function() {
    gulp.src(['css', 'js', 'images'], {read: false})
        .pipe(clean());
});

// Default task
gulp.task('default', function() {});

Watch task

When developing with gulp you need to constantly be running the build script to see changes as you make them. Fortunately there is file watching functionality built into gulp, all you need to do is tell it which tasks to run for which files.

// Dependencies
var gulp  = require('gulp'),
    clean = require('gulp-clean');

// Clean task
gulp.task('clean', function() {
    gulp.src(['css', 'js', 'images'], {read: false})
        .pipe(clean());
});

// Watch task
gulp.task('watch', function() {
    gulp.watch(['assets/scss/**/*.scss'], ['styles']);

    gulp.watch(['assets/scripts/**/*.js'], ['scripts']);

    gulp.watch(['assets/images/**/*'], ['images']);
});

// Default task
gulp.task('default', function() {});

Now running gulp watch in the terminal will track the files and only run the task that is needed when something is updated.

Build task

To have greater control over the order tasks are run in I recommend using the run sequence plugin. You can then write a build task that will run all of the necessary tasks to build the project, excluding the watch task. Then pass an array listing the build and watch tasks to the default task, which will run these tasks as dependencies of the default task.

// Dependencies
var gulp        = require('gulp'),
    clean       = require('gulp-clean'),
    runSequence = require('run-sequence');

// Clean task
gulp.task('clean', function() {
    gulp.src(['css', 'js', 'images'], {read: false})
        .pipe(clean());
});

// Watch task
gulp.task('watch', function() {
    gulp.watch(['assets/scss/**/*.scss'], ['styles']);

    gulp.watch(['assets/scripts/**/*.js'], ['scripts']);

    gulp.watch(['assets/images/**/*'], ['images']);
});

// Build task
gulp.task('build', function() {
   runSequence('clean', 'scripts', 'styles', 'images');
});

// Default task
gulp.task('default', ['build', 'watch'], function() {});

Now you should be able to run gulp build to do a one off build of the project and gulp to build once and watch for changes to the source files.

More Reading

I’m going to follow up this overview with some recipes for regularly used tasks like scripts, styles and images but for now here’s some extra reading to help get you started: