Getting Starting With Gulp

Recently I decided to move away from my admittedly minimalistic use of Grunt to Gulp and now I can’t seem to start a project without it. In this guide I will show you how to get started with your own magnificent journey with Gulp.

So what is this gulp thing all about?

Gulp refers to itself as:

The streaming build system

Basically it can be used to handle all those mundane little tasks that we do need to run/perform, but often skip due to aforementioned mundaneness. Below is only a few tasks that Gulp is able to run, but it should provide enough of an overview to get you excited:

  • Minify CSS and JS files.
  • Concatenate files.
  • Compile LESS, SASS, CoffeeScript, etc.
  • Optimize images.
  • Lint JS files.
  • And even livereload.

So how is this different from grunt?

It’s true that the functionality between Grunt and Gulp is the same, but I find Gulp much easier to use. Due to its way of handling files via streams the code is a lot cleaner and easier to understand. Let me show you:

Grunt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
module.exports = function(grunt) {
  // Project configuration.
  grunt.initConfig({
    css: {
      combine: {
        files: {
          'style.min.css': ['style.css']
        }
      }
    }
  });

  // Load task.
  grunt.loadNpmTasks('grunt-contrib-cssmin');

  // Default task.
  grunt.registerTask('default', ['css']);
};

Gulp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
var gulp = require('gulp');
var minify = require('gulp-minify-css');

gulp.task('css', function() {
  return gulp.src('style.css')
    .pipe(minify())
    .pipe(gulp.dest('dist/'));
});

gulp.task('default', ['css'], function() {});

The above code shows how you would minify your CSS with both Grunt and Gulp. As you can see the Gulp syntax is cleaner, easier to understand, and a couple of lines shorter (This might not seem like much, but believe me this saving adds up the more complicated your build script).

Enough Talking! Show me how it is done!

Ok ok ok…Jeez. Impatient reader!

Before we continue make sure you have NodeJS installed. The procedure is beyond the scope of this tutorial, but you can visit the NodeJS website for a guide.

The first thing is to get Gulp installed. Luckily the modern interwebs and extremely creative and talented people make this easy. Just run the following command in terminal:

npm install -g gulp

Now in a new directory enter the following command:

echo "{}" >> package.json

Followed by this:

npm install gulp --save-dev

Gulp by itself is not too useful so we have to install a couple of plugins which we will use to minify our CSS and JS, autoprefix our CSS, and optimize any images we might have. (If this seems like to much effort, don’t worry, there is a link to the source at the bottom of the post.)

npm install --save-dev gulp-autoprefixer gulp-imagemin gulp-uglify gulp-minify-css gulp-rename gulp-clean

We need to load all the plugins we installed earlier. Add the following to the Gulp file:

1
2
3
4
5
6
7
8
// Load in Gulp and the additional plugins
var gulp = require('gulp'),
    autoprefixer = require('gulp-autoprefixer'),
    minifycss = require('gulp-minify-css'),
    rename = require('gulp-rename'),
    uglify = require('gulp-uglify'),
    imagemin = require('gulp-imagemin'),
    clean = require('gulp-clean');

Before we continue, let’s evaluate and lay out exactly what we need done. Firstly, we require a task that will autoprefix and minify our CSS. Secondly, we also require a task that will minify our JS. And lastly, we need a task that will optimise any images we might have. Below is the code for all the tasks described above:

CSS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
gulp.task('css', function() {
  // Specify the source of the CSS files.
  return gulp.src('src/css/style.css')
    // Autoprefix the CSS covering the last 10 versions of all browsers.
    .pipe(autoprefixer('last 10 versions'))
    // Rename the files to add the ".min" suffix.
    .pipe(rename({suffix: '.min'}))
    // Minify the renamed CSS files.
    .pipe(minifycss())
    // Set the output of the minified files.
    .pipe(gulp.dest('dist/css'));
});

JS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
gulp.task('js', function() {
  // Specify the source directory for the JS files.
  // Notice that we specified a regular expression in the directory.
  // This specific one will scan all sub-directories and get all files
  // with the ".js" extension.
  return gulp.src('src/js/**/*.js')
    // Rename the files to add the ".min" suffix.
    .pipe(rename({suffix: '.min'}))
    // Uglify the JS files.
    .pipe(uglify())
    // Specify the final directory for the minified JS files.
    .pipe(gulp.dest('dist/js'));
});

Images

1
2
3
4
5
6
gulp.task('images', function() {
  // Specify the source of the images.
  return gulp.src('src/img/**/*')
    .pipe(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))
    .pipe(gulp.dest('dist/img'));
});

Running the above tasks is as easy as:

// CSS tasks
gulp css

// JS tasks
gulp js

// Image tasks
gulp images

What if files are removed? How do we keep our destination directories clean? Again, there is a way with Gulp. Let me show you the light:

1
2
3
4
5
6
gulp.task('clean', function() {
  // Specify the directories to clean.
  return gulp.src(['dist/css', 'dist/js', 'dist/img'], {read: false})
    // Clean them.
    .pipe(clean());
});

Default Task

Running all those tasks every time you make changes will minimise your productivity. What if there was a way to run all the required tasks with one command? Well, the great people at Gulp have you covered. Add the following to gulpfile.js.

1
2
3
4
5
6
7
// The second parameter is an array of tasks to complete before
// executing the content of the function. In this case we are
// running the clean function before doing anything else.
gulp.task('default', ['clean'], function() {
    // Run all the other commands.
    gulp.start('css', 'js', 'images');
});

Now running all the tasks we have created is as easy as:

gulp

But I still have to run a command every time I change a file…

Don’t worry. I was getting to that. Gulp has built in features to watch files and run specified commands if it does pick up a change. Add the following to gulpfile.js:

npm install --save-dev gulp-livereload

Now change the section where we load the Gulp plugins to the following:

1
2
3
4
5
6
7
8
9
// Load in Gulp and the additional plugins
var gulp = require('gulp'),
    autoprefixer = require('gulp-autoprefixer'),
    minifycss = require('gulp-minify-css'),
    rename = require('gulp-rename'),
    uglify = require('gulp-uglify'),
    imagemin = require('gulp-imagemin'),
    clean = require('gulp-clean'),
    livereload = require('gulp-livereload');

And finally, add the following at the end of the watch function created above:

1
2
3
gulp.watch('dist/**').on('change', function(file) {
  server.changed(file.path);
});

Once you have set your browser’s livereload plugin to connect after running the watch task it will now automatically refresh the page.

Conclusion

By now you should already have an idea about how easy and powerful Gulp is. I did however only scratch the surface with this guide. I suggest you check out the Gulp website and the plugins directory to see what else it can do.

Source

As promised, I created a little GitHub repo for this tutorial so you can download the source from there.

comments powered by Disqus