Take a Gulp to make your depoyment faster

Try it…take a sip…

We’re a bit late on this post, on account on not really knowing to write about…We’ve done a lot of backend / Java style posts lately so we didn’t really want to write about that tech stack again. We racked our brains and came decided that we could write about something we don’t really talk a lot about…

We’re going to discuss build processes. Exciting, huh? Specifically, we’re going to talk about using Gulp to automate the build process for a Javascript frontend. Gulp allows one to set up a bunch of tasks that automate a particular step in the build process, it’s then possible to chain these steps together to form a build process, or alternatively, a test process for example.

Gulp tasks are defined by a gulpfile.js and can be run by typing gulp [task name] in the directory that the gulpfile lives in.

First Gulp needs to be installed. The best way to do this is to use npm. If you don’t have npm, well, shame on you! Head over here to get it sorted.

Once that is sorted, you’ll need yourself a basic project setup, use npm init  in the directory where you want to setup your project. Most of the options can be left at their defaults.

Once you’ve got the project setup you’ll need to install the necessary dependencies…We’re going to be using an ES6 gulpfile so that we can use cool things like the () => {} syntax. Mark Goodyear gives an excellent insight into setting gulp up to use ES6 here, rather than us duplicating it go and have a look. His post also covers how to install the Gulp dependency the ES6 way, so once again, we won’t be covering that here.

The following task simply copies the code from the source directory to the build directory. Very helpful. Notice that gulp is built on a streams model, which makes for convenient and readable code. Notice also that the gulp.src() call allows us to pass an array of values to copy.

gulp.task('copySrc', () => {
    gulp.src(['app/**/*.js'])
        .pipe(gulp.dest(/build));
});

You’ll also need the import gulp from ‘gulp’;   line at the top of your gulpfile.

To run this task, all we need to type is, gulp copySrc and it’ll do exactly what it says on the tin.

So that’s all well and good, but what if say, we wanted to lint our code too. Well, guess what? We simply add a lint task to our gulpfile:

gulp.task('lint', () => {
    return gulp.src(app/**/*.js')
        .pipe(eslint())
        .pipe(eslint.format());
        .pipe(eslint.failOnError());
});

We’re using ESLint instead of JSHint because we were writing our code in ES6. Although it’s possible to use JSHint with ES6 code you’ll find that you’ll be adding a lot of JSHint ignores in so we recommend using ESLint.

Note how we’ve used failOnError()  to kill the build process if we happen to find any errors!

Unfortunately, the task won’t work right out of the box…we need to do a few things first…

Add the dependency –

npm install gulp-eslint --save-dev

By adding the –save-dev  switch to the command npm will add the entry to the “dev dependencies” section of our package.json.

Import the dependency –

import eslint from 'gulp-eslint';

And, last but most definitely not least, add our .eslintrc file. This file needs to be in the root of the project directory and tells ESLint which rules to follow. Whilst you could hand roll your own, it’s much easier to go and ‘borrow’ one from here

So now we can copy our src AND lint our code, isn’t that cool? Well yeah, it sure is! There’s a bit of a problem here though…to lint our code we have to run gulp lint and then wait for our task to complete, then run gulp copySrc . It’s a bit, well, tedious really. Wouldn’t it be helpful if we could run the tasks back to back after each other.

Well, cast your minds back to what we said earlier viewers, Gulp can run multiple tasks by grouping them into another task. This is a nice easy one –

gulp.task('default', ['lint', 'copySrc']);

By adding these tasks as dependencies to the default Gulp task we can simply type gulp and Gulp will run the lint task and copySrc task.

Sweet! We’re done we hear you all cheer! Not quite. The problem with the default task that we’ve written above is that whilst it will run both the lint and copySrc tasks they will at the same time. This obviously creates a bit of an issue because we actually want the lint task to run and then, if successful run the copySrc task.

How do we achieve this? Well, Gulp tasks can have dependencies, so that they wait until the task that they are dependent on signals that it’s finish (this is usually done by the task returning a stream). So, if we update our copySrc task to be dependent on our lint task, it would look like this –

gulp.task('copySrc', ['lint'], () => {
    gulp.src(['app/**/*.js'])
        .pipe(gulp.dest(/build));
});

So, now every time our copySrc  task runs, it will run our lint task beforehand and wait for it to finish. We mustn’t forget to update our default task so that it doesn’t run the lint task…

gulp.task('default', ['copySrc']);

An interesting point to note is that if two tasks run as part of another task (think lint and copy) and are both dependent on the same task (think clean) then the task they are dependent on will only actually be run once. Helpful!

So, that’s about it! A quick into to Gulp and all it’s magic! Of course there is a whole host of other stuff that can be done, transpiling, module bundling…the list goes on…

Thanks for listening! We hope you’ve found this helpful or even possibly a little bit interesting! You’ve been great and we’ve been…

~23Squared