Using Gulp in Your Web Design Workflow

April 20th, 2015

While you may be an expert in Photoshop or Sketch, there will be times when you need to execute your designs or prototypes in the browser. Writing out HTML can be easy enough, but when it comes to repetitve tasks like running your CSS preprocessor, optimizing images, or live reloading your browser when you make you changes, things can become tedious.

Enter Gulp. Gulp is a JavaScript task runner built on top of Node. While it can’t code your designs for you, with a few lines of code, you can automate a majority of your workflow.

Let’s walk through how to set up Gulp on your system and how to automate the most common tasks in the web design workflow. This article assumes that you are unfamiliar with the command line and are starting from scratch.

If you’re familiar with the process, you can download this as a project starter.

  1. Install Node
  2. Navigate To Your Project
  3. Install Gulp
  4. Gulpfile.js
  5. CSS: Compiling Sass, Adding Vendor Prefixes, and Concatenating and Minimizing Your CSS
  6. Images: Optimizing Image File Size
  7. JavaScript: Concatenating, and Minimizing Your JavaScript
  8. Live Browser Reload
  9. Learning More: Plugins, Modifying
  10. Project Starter
  11. Quench: The Gulp file generator

Install Node

Gulp runs on Node, a programming platform that uses JavaScript to easily build web and command line applications. Node makes it super simple to install: download the latest version from nodejs.org and install the downloaded package.

Now that you have Node installed, let’s work on getting Gulp up and running. Gulp is executed using the command line, and to use the command line you need to launch Terminal. You can find Terminal in your Utilities folder in the Applications folder, or you can launch it by using Spotlight (Cmd + Space).

Navigate to your project folder by using the cd command in terminal, like this:

cd ~/path/to/your/project

If you don’t know the path, type cd and then drag the folder onto the Terminal window and it will automatically fill in the path for you.

Install Gulp

Next, install Gulp globally. This allows you to run the gulp command from anywhere in the Terminal. You only need to do this once, so if you’ve completed this step, you can skip to installing Gulp locally.

npm install gulp -g

Since Gulp runs off of Node, we have to do a little Node setup. Running the following command creates a package.js file in your project directory that contains information about the Node packages we’re about to install. Once you’ve completed this process for one of your projects, you can reuse this package.js file in other projects and simply run npm install to set up Gulp.

npm init

We’ve installed Gulp globally, but for things to work, we also need to install Gulp into the project itself.

npm install gulp --save-dev

Introduction to Gulpfile.js

gulpfile.js is where we create the tasks Gulp executes. The basic structure involves referencing Gulp and any plugins we’re using, followed by the tasks we wish Gulp to perform. Like this:

// Reference Gulp
var gulp = require('gulp');

// Reference plugins
var sass = require('gulp-sass');
var imagemin = require('gulp-imagemin');

// Compile CSS
gulp.task('styles', function(){
	...
});

// Optimize Images
gulp.task('images', function(){
	...
});

At this point, all we need in gulpfile.js is a reference to Gulp itself:

// Reference Gulp
var gulp = require('gulp');

CSS: Compiling Sass, Adding Vendor Prefixes, and Concatenating and Minimizing Your CSS

First, we install the plugins we’ll use to prepare our CSS:

npm install gulp-util gulp-sass gulp-autoprefixer gulp-rename gulp-minify-css --save-dev

This installs the plugins into the node_modules directory in your project and adds the plugins to the package.json file we created eariler.

Next, set up gulpfile.js:

// CSS Plugins
var gutil = require('gulp-util');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var rename = require('gulp-rename');
var minifycss = require('gulp-minify-css');

// CSS Task
gulp.task('styles', function(){
  gulp.src(['src/styles/**/*.scss'])
    .pipe(sass())
    .on('error', gutil.log)
    .pipe(autoprefixer('last 2 versions'))
    .on('error', gutil.log)
    .pipe(gulp.dest('dist/styles/'))
    .pipe(rename({suffix: '.min'}))
    .pipe(minifycss())
    .pipe(gulp.dest('dist/styles/'))
});

The styles task looks for any .scss files in the src/styles directory of your project, preprocesses those files using Sass, automatically adds vendor prefixes supporting the latest two version of any browser, then saves two versions of the CSS in the dest/styles directory: an minified and an unminified version.

Now if you run the following command, Gulp will run the styles task and output the processed CSS:

gulp styles

Images: Optimizing Image File Size

Install the image plugins:

npm install gulp-cache gulp-imagemin --save-dev

Set up gulpfile.js:

// Image Plugins
var imagemin = require('gulp-imagemin');
var cache = require('gulp-cache');

// Image Task
gulp.task('images', function(){
  gulp.src('src/images/**/*')
    .pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true })))
    .pipe(gulp.dest('dist/images/'));
});

When running this command, Gulp will look for any images in the src/images directory of your project, compress them, and save them out to dist/images.

gulp images

JavaScript: Concatenating and Minimizing Your JavaScript

This should be familiar now. Install the JavaScript plugins:

npm install gulp-concat gulp-uglify --save-dev
// JavaScript Plugins
concat = require('gulp-concat');
uglify = require('gulp-uglify');

// JavaScript Task
gulp.task('scripts', function(){
  return gulp.src('src/scripts/**/*.js')
    .pipe(concat('main.js'))
    .on('error', gutil.log)
    .pipe(gulp.dest('dist/scripts/'))
    .pipe(rename({suffix: '.min'}))
    .pipe(uglify())
    .on('error', gutil.log)
    .pipe(gulp.dest('dist/scripts/'))
});

The JavaScript task looks for any JavaScript files in src/scripts, merges them together, and minimizes them into dest/scripts.

Live Browser Reload and Default Task

BrowserSync is an awesome Gulp plugin that makes browser testing on your local machine and across devices incredibly simple. It has a number of options, but by default it runs a server that’s accessible to any device on your local network, live reloads all devices anytime you change a file in your project, and will sync scroll and actions across devices.

To set it up:

npm install browser-sync --save-dev

Next, we’ll add a browser-sync task as well as modify our existing tasks to force a refresh anytime styles or scripts change.

Additionally, running gulp on the command line by itself will run the default Gulp task. To make things easier, we’ll set up the default task to run all of our previous tasks:

var gulp = require('gulp'),
  gutil = require('gulp-util'),
  sass = require('gulp-sass'),
  autoprefixer = require('gulp-autoprefixer'),
  browserSync = require('browser-sync'),
  imagemin = require('gulp-imagemin'),
  cache = require('gulp-cache'),
  rename = require('gulp-rename'),
  concat = require('gulp-concat'),
  minifycss = require('gulp-minify-css'),
  uglify = require('gulp-uglify');

gulp.task('browser-sync', function() {
  browserSync({
      server: {
          baseDir: "./"
      }
  });
});

gulp.task('styles', function(){
  gulp.src(['src/styles/**/*.scss'])
    .pipe(sass())
    .on('error', gutil.log)
    .pipe(autoprefixer('last 2 versions'))
    .on('error', gutil.log)
    .pipe(gulp.dest('dist/styles/'))
    .pipe(rename({suffix: '.min'}))
    .pipe(minifycss())
    .pipe(gulp.dest('dist/styles/'))
    .pipe(browserSync.reload({stream:true}))
});

gulp.task('images', function(){
  gulp.src('src/images/**/*')
    .pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true })))
    .pipe(gulp.dest('dist/images/'));
});

gulp.task('scripts', function(){
  return gulp.src('src/scripts/**/*.js')
    .pipe(concat('main.js'))
    .on('error', gutil.log)
    .pipe(gulp.dest('dist/scripts/'))
    .pipe(rename({suffix: '.min'}))
    .pipe(uglify())
    .on('error', gutil.log)
    .pipe(gulp.dest('dist/scripts/'))
    .pipe(browserSync.reload({stream:true}))
});

gulp.task('bs-reload', function () {
  browserSync.reload();
});

gulp.task('default', ['browser-sync'], function () {
  gulp.watch("src/styles/**/*.scss", ['styles']);
  gulp.watch("src/scripts/**/*.js", ['scripts']);
  gulp.watch("*.html", ['bs-reload']);
});

Learning More: Plugins and Modifying

Gulp has hundreds of plugins you can use to customize your own workflows. Additionally, Node itself has a number of packages that you can incorporate as well.

I’ve set up Gulp to best match my workflow, using a directory structure I’m happy with and using the tasks that I need to expedite my own process. I encourage you to dive in to Gulp to customize Gulp to your own needs.

Project Starter

While these Gulp tasks are particular to my own workflow, you might find them useful as a good starting point. I’ve set up a Git repository with my project starter for you to use and customize.

Good luck! Any questions?

Update:

UPDATE: Quench: The Gulp file generator

Inspired by the response to this article, I created a tool called Quench that makes getting started with Gulp even easier. The goal was to build something that requires minimal input and minimal effort to execute. Learn more about it in “Introducing Quench: The Gulp file generator.” or visit the site to get started.

3 Comments

Jerome

April 21, 2015 3:03 am

Nice work Matt! You may have a look at how I use Gulp in my workflow:
https://github.com/jeromelachaud/microFramework
You might find some useful things in there.

Matt

April 21, 2015 8:39 am

Looks great, Jerome! Love the split between dev/production.

Prosenjit

May 5, 2015 1:15 pm

Nice. Clean with minimum gulp plugins. Easy to understand.

Leave a Reply

Your email address will not be published. Required fields are marked *