Tasks automation in-depth using GulpJS

Tasks automation

Gulp is a powerful tool used for Tasks automation in web development. It has high functionality which allows you to efficiently complete multiple tasks like:

  • Setting up web servers
  • Reloading the browser whenever a file is changed
  • Working with preprocessors like LESS or SASS
  • Working with template engines like PUG (formerly Jade), HAML, Handlebars, etc.
  • Optimizing assets
  • Minifying
  • Validating code (linting)

Yes, there are other build tools in the market, but I choose Gulp because the configuration tends to be shorter, simpler and faster.

To move forward, I’m going to show you how to setup a workflow with Gulp. Keep in mind, documentation might change over time so please refer to the official documentation in the Gulp repository at:

  1. Install Gulp globally (Note: You need to have npm previously installed).
     $npm install --global gulp-cli 
  2. Create a gulpfile.js at the root of your project directory; in this case we are using the structure of a common Webapp.
          |- app/
          |- css/
          |- fonts/
          |- img/
          |- index.html
          |- js/
          |- scss/
          |- dist/
          |- gulp/
          |- bower.json/
          |- gulpfile.js
          |- node_modules/
          |- package.json
          
  3. Require Gulp at the beginning of your gulpfile.js. Node will look within Gulp’s package folder and assign it to the variable ‘gulp’.
     var gulp = require('gulp'); 
  4. Write the first Gulp task as follows (this is the basic syntax and whenever you want to run a task in Gulp, use “Default” as the name of the task):
        gulp.task('default', function() {
        // Tasks here
        });
        

Now that we have set up a workflow in Gulp, I will cover some common tasks like compressing, compiling, linting and reloading the browser whenever a change on the file is detected.

Check out this link for additional Gulp

BrowserSync

First, I will show you how to setup BrowserSync. It is a tool that provides live reloading every time a file changes. BrowserSync works by setting up a server or hooking up to an existing server and acting as a proxy.

  1. Install BrowserSync in your local project.
     $ npm install browser-sync --save-dev 
  2. Include it right after Gulp.
        var gulp = require('gulp'),
        browserSync = require('browser-sync');
        
  3. Create a task to start BrowserSync and point the baseDir to wherever our project is located:
          gulp.task('browserSync', function() {
            browserSync.init({
              server: {
                baseDir: 'app'
              },
            })
          })
        
  4. Create a function to reload whenever a change is triggered.
          // Reload after tasks finished
          function reload(event) {
            browserSync.reload();
          }
        

SASS

Now that we have BrowserSync setup, we need to include SASS in order to reload every time a .scss file changes.

  1. Install SASS.
     $ npm install gulp-sass --save-dev 
  2. Include it in our gulpfile.
          var gulp = require('gulp'),
          browserSync = require('browser-sync'),
          sass = require('gulp-sass);
        
  3. Create the SASS task, this will compile the .scss stylesheet into .css
        gulp.task('sass', function(){
        return gulp.src('source-files')
        .pipe(sass())
        .pipe(gulp.dest('destination'))
        });
        

Note: The node stream composition operator is called .pipe() – it reads data from the source and writes it to the destination without worrying about the flow. Essentially, .pipe() manages it for you.
Read more about streaming in Node .
Sometimes it is important to compile more than one .scss file into css at the same time. To accomplish this, we will use matching patterns; essentially, it is like a regular expression but specifically for files.

Patterns

Let’s rewrite our task to add a pattern:

    gulp.task('sass', function(){
      return gulp.src('app/scss/**/*.scss')
      .pipe(sass())
      .pipe(gulp.dest('app/css'))
    });
  

Now any .scss file that’s found within app/scss will be added into the SASS task and compiled into .css.
To this point, we have setup the ability to compile any SASS stylesheet into css with this simple task:

 $ gulp sass 

You will run this task manually whenever we make changes to our SASS stylesheet. To automate this task, you use a watcher. (Note: A watcher looks for changes in the files and executes the provided actions)

gulp.task('watch', function(){
gulp.watch('app/scss/**/*.scss', ['sass']);
})

If any changes are saved inside app/scss, the watcher will invoke the SASS task.

To this point, we have executed tasks that will save time and effort. Now, we must allow BrowserSync to reload the browser every time the SASS tasks run.

  1. We need to rewrite our SASS task to include BrowserSync
          gulp.task('sass', function() {
            return gulp.src('app/scss/**/*.scss')
              .pipe(sass())
              .pipe(gulp.dest('app/css'))
              .pipe(reload)
          });
        
  2. Next, we want to make the watch and BrowserSync work simultaneously. In order to do that we must add it as a second argument to the watch task:
          gulp.task('watch', ['browserSync', 'sass'], function (){
            gulp.watch('app/scss/**/*.scss', ['sass']);
          });
        

Note: If you add any changes to the .scss files you’ll see the browser reloads automatically.

MinifyJS

To Minify JS we will use uglify. For additional articles and resources, read more

  1. Install it in our local project.
     $ npm install --save-dev gulp-uglify 
  2. Require it in the gulpfile:
        var gulp        = require('gulp'),
        browserSync = require('browser-sync'),
        sass        = require('gulp-sass'),
        uglify      = require('gulp-uglify');
        
  3. Create a task to minify the files:
        gulp.task('minify-js', function () {
            gulp.src('app/js/*.js')
            .pipe(uglify())
            .pipe(gulp.dest('app/js'))
            .pipe(reload);
        });
        

Concatenate JS files

To concatenate JS files into a single one, we will use another npm package called gulp-concat.

For more information on gulp-concat, read

  1. Install it.
          $ npm install --save-dev gulp-concat
        
  2. Require it in the gulpfile:
        var gulp    = require('gulp'),
        browserSync = require('browser-sync'),
        sass        = require('gulp-sass'),
        uglify      = require('gulp-uglify'),
        concat      = require('gulp-concat');
        
  3. Create a task to concat files, this can also work with css files, so you can rewrite the task for that purpose too.
        gulp.task('concat', function () {
            gulp.src('app/js/*.js')
            .pipe(concat('all.js'))  // concat and name it "all.js"
            .pipe(gulp.dest('app/js'))
            .pipe(reload);
        });
        
  4. Combine all the tasks to run with the watcher, let’s modify our watch a bit.
        gulp.task('watch', ['browserSync', 'sass', 'minify-js', 'concat'], function (){
          gulp.watch('app/scss/**/*.scss', ['sass']);
          gulp.watch('app/js/*.js', ['minify-js']);
          gulp.watch('app/js/*.js ', ['concat']);
        });
        

Going forward, there are many tasks that can be added based on the above convention. Below is a list of additional tasks that can be added:

  • Linting code
  • Compiling coffeescript and others
  • Copying assets, fonts and images to a dist directory
  • Removing unnecessary files
  • Modularizing HTML with template engines
  • Image optimization
  • HTML compression
  • Push and pull translations to any service

Finally if you are not using gulp – give it a try! It will make your life easier.

Danny Goncalves

Senior software developer, focused on Frontend technologies.