Getting up and running with Gulp

Over the last 6 months, Gulp and Grunt have become a regular part my workflow. These tools are known as task runners, which help to maintain and automate much of the web development process.

For my last few projects, I've been using Gulp because clients have preferred it. I'm starting to like it a lot too. So, I found it useful to write an introduction to setting up a project with Gulp.

This post assumes that the reader has never used a task runner before, so it will walk through each step required to get started with Gulp.

What is a task runner?

Optimising and testing a website can be repetitive, time consuming and probably isn't the most fun part of the web development process. Task runners are used to improve the efficiency of this process. There are multiple tools out there to choose from such as Gulp, Grunt, Broccoli, and Brunch

Some of the common build tasks which can be automated include:

  • CSS Preprocessing
  • JavaScript linting
  • Testing
  • Image optimisation
  • Minification of JS and CSS files
  • Concatenating files
  • Reloading the browser

Working with Gulp

Gulp is built on Node.js. Both the Gulp source and the Gulp task file, where you define tasks, are written in JavaScript. The Gulp task file instructs the task manager on which development tasks to undertake, so it can watch for changes to the relevant files.

Step 1: install Node

As mentioned, Gulp is built on Node. So, the first step is to download Node.js from the website. If you're not sure whether you have node already, you can check by opening up terminal and running the node-v command.

$ node -v

If you have node installed already, you will see the version number displayed. If it returns something like 'command not found', you'll need to install Node. If you're currently installing node for the first time, run this command anyway to check that it has worked.

Step 2: install Gulp

Next in the terminal, we need to install Gulp globally using Node Package Manager (npm). Node Package Manager is used to install packages to projects.


$ npm install -g gulp

Let's see if this has worked by running the version command, like we did when we installed node.


$ gulp -v

This should return the version of gulp installed.

Step 3: Add Gulp to a project locally

In order to use Gulp in a project, it has to be installed locally.

In terminal, navigate to your project root folder, like below. From now on all the commands will be ran from the project’s root folder.


$ cd ~/sites/test-project

Next we need to create a package.json file in the project root with some project information like this:


{
  "name": "test-project",
  "version": "0.1.0",
  "description": "An introduction to Gulp",
  "homepage": "http://lottejackson.com/",
  "author": "@lottejackson",
  "devDependencies": {
  }
}

Or you can type npm init into terminal, which will create the file and ask you for each piece of information. The curly braces after devDependencies will soon contain all of the gulp modules.

Now we can add Gulp to the project. In terminal, add Gulp like below:


$ npm install gulp --save-dev

--save-dev automatically adds Gulp to the list of dependencies in the package.json file we just created. There should now be a new line in the package.json file saying "gulp": "^3.8.11".


{
  "name": "test-project",
  "version": "0.1.0",
  "description": "An introduction to Gulp",
  "homepage": "http://lottejackson.com/",
  "author": "@lottejackson",
  "devDependencies": {
      "gulp": "^3.8.11"
  }
}

The number refers to the version and may vary depending on when it was added, which is fine.

Step 4: Add a Gulp file

To finish installing Gulp, we need to add it to a Gulp file. We don't have one yet, so let's create it. It should be named gulpfile.js. This file tells the task manager which tasks to perform.

We also need to add Gulp to the gulpfile.


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

Step 5: Some Gulp methods to get you started

At this point, I think it's useful to learn about some methods that you are likely to use when writing Gulp tasks:

  • task: used for defining a task
  • pipe: takes in a text stream and sends it to a function
  • watch: run a function when a file changes
  • src: get a stream from a source file
  • dest: send the stream to a new folder

Tasks

On a Gulp project, the first thing you are likely to do is define a task using the gulp.task() function. This will take two attributes, which are the task's name and the function to run. Here is how the function would look.


gulp.task('hello', function() {
    alert("Hello, I am a gulp task!");
});

Streams

An important Gulp concept is streams. You could think of your files as passing through pipes, where several pipes join together. You join the output of one task into the input of another, allowing you to create larger systems out of several small tasks that each do one thing well.

Source

gulp.src() takes a string matching a file(or files), also known as a glob, and returns a stream that can be passed through pipes. You can target any number of files.

  • return gulp.src('js/scripts.js')
    Returns the exact file
  • return gulp.src('js/*.js')
    Returns all files ending in .js in the js directory
  • return gulp.src('js/**/*.js)
    Returns all files ending in .js in the js directory and it's child directories
  • return gulp.src('!js/scripts.js)
    Excludes js/scripts.js

Let's automate some common tasks using Gulp.

Step 6: Concatenate files with Gulp

We'll make our first task concatenation. First, we need to install the gulp-concat plugin using the following command:


$ npm install gulp-concat --save-dev

Just like we did before, check your package.json file and watch the new line appear under dependencies.


"gulp-concat": "^2.5.2"

Again, like we did earlier, add the gulp-concat plugin to your gulpfile.js


// Include gulp
var gulp = require('gulp');
// Include our plugins
var concat = require('gulp-concat');

Still within the gulpfile.js, here is how we instruct the task manager to concatenate the JS files.


gulp.task('scripts', function() {       //define the task
return gulp.src('js/*.js')              //return the stream from all .js files in the js folder
    .pipe(concat('global.js'))          //Concatenate the files
    .pipe(gulp.dest('build/js'));       //Send the stream to the new destination folder
});
// Default Task
gulp.task('default', ['scripts']);      //Tell the task manager to run the task

I've added notes to explain each step.

Our next task is to minify the JavaScript. In the same way as before, we will add the gulp plugin uglifiy to minify files and the plugin rename so that we can rename the file to global.min.js.


$ npm install gulp-uglify --save-dev

$ npm install gulp-rename --save-dev

Add them to the gulpfile.js.


// Include gulp
var gulp = require('gulp');
// Include our plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');

Now we can extend the above function because minifying JavaScript is part of the scripts task.


gulp.task('scripts', function() {      
return gulp.src('js/*.js')         
    .pipe(concat('global.js'))           
    .pipe(rename('global.min.js'))       // Change the file name to global.min.js
    .pipe(uglify())                      // Minify the scripts
    .pipe(gulp.dest('build/js'));       
});
// Default Task
gulp.task('default', ['scripts']);       //Tell the task manager to run the task

It's important to remember the final line, which is adding the task to our default tasks. This instructs Gulp to run the tasks every time you run Gulp.

Step 7: Compile and concatenate Sass files

If we decide to work with Sass in this project, we need to compile it to plain CSS. Let's install the gulp-sass plugin to handle it. See if you can add this module yourself, using the same method as before.

Hopefully you can now see it in your package.json file and you will have added the module to your gulpfile.js like below.


// Include gulp
var gulp = require('gulp');
// Include our plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sass = require('gulp-sass');

Let's create the task.


gulp.task('sass', function() {            //Define the task function
  gulp.src('scss/*.scss')                 //Return all scss files in scss folder
    .pipe(sass())                         //Compile
    .pipe(concat('styles.css'))           //Concatenate
    .pipe(gulp.dest('build/css/'));       //Send to build folder
});

As you can see, we have given this function the name sass and returned the scss files. They are concatenated and sent to the build folder.

Now we need to add this task to the list of default tasks, like we did earlier.


// Default Task
gulp.task('default', ['scripts', 'sass']);

Step 8: Run Gulp

Now we can run Gulp and see if it works! Let's switch back to command-line and type Gulp.


gulp

This will run all of the Gulp tasks. If we wanted to, we could just run one task.


gulp sass

Step 9: Watch for changes

This is great, but at the moment we have to re-run Gulp every time we change a file. The good news is Gulp can do this for us. We can use the watch method to automatically watch out for changes to our files and re-run tasks.


gulp.task('watch', function() {                // Watch Files For Changes
    gulp.watch('js/*.js', ['scripts']);        // Watch .js files
    gulp.watch('scss/*.scss', ['sass']);       // Watch .scss files
});

Finally,add this task to the list of default tasks.


// Default Task
gulp.task('default', ['scripts', 'sass', 'watch']);

Step 10: It's up to you

I will leave you with these three tasks, but there are many more possibilities. Another common task is to optimise images, which can be done using the gulp-imagemin and gulp-cache plugins. There are also plugins for automatically reloading the browser on file changes like Live Reload and Browserify. Many have their advantages and disadvantages, so I guess it's all about trying them out to see what works best for you.

Tags: