Gulp for Web Designers — All You Want to Know

Have you ever wanted to automate boring tasks of web design and development? Let me introduce you to Gulp. Gulp is a streaming build system that will aims to make your workflow more productive and efficient. This is done by automating all those boring tasks such as minification and assets optimization you have to do by yourself. With Gulp, you can fully focus only on the parts of your work you truly love. In this article, you will learn everything you need to make Gulp work for you! So, are you ready to take your work to next level?

One of the reasons why I like to work with Gulp … What the heck! Why I love working with Gulp is its simplicity. In the simplest sense, the way you work with Gulp, or how you pipe task, is basically by saying “take this file, do this, also do this, and this, then put the result here.” Can it be as easy as it sounds? Yes it can. It can be even easier than that. In this guide, I will show you how to set Gulp tasks and implement this tool into your workflow. But before we start, I share with you a bit about Gulp so you will be able to understand it better.

Also, if you are still not convinced to give this interesting tool a shot, I will share with you a pile of benefits. Before you will reject the possibility of making Gulp part of your toolkit, stop for five minutes of your precious time. Then, take a look at least at the section featuring benefits of Gulp.

What is Gulp

It is a quite a while since JavaScript task runners entered the scene of front-end development. If you are familiar with this “area” of tools, you might already hear about another members. Broccoli, Grunt, Gulp or Mimosa to give you at least couple of examples. And, I doubt that the total number it will stay the same in close future. Rather the opposite. With time, task runners are gaining popularity so it is quite possible that newer and more polished tools will start to appear.

Anyway, let’s get back to the subject of this part … What is Gulp? Gulp is a JavaScript-based build system that is used by developers to automate dull and repetitive tasks. Some of tasks include minification of HTML, CSS and JavaScript files, copying of files from one place to another, optimizing image assets such as JPGs (JPEG), PNGs, SVGs, GIFs, compiling sass, less and other style-related files to CSS, concatenating files, watching files to automatically rerun the task when a file is changed, cleaning folders and much more. You can find the complete catalog of plugins here.

These are just a handful of tasks Gulp can do for you. Now you probably understand the name tools such as Gulp are often referred — “build tools” or “task runners”. The main purpose of using these tools is outsourcing tasks that you would otherwise have to execute.

Not All Task Runners Are the Same

Before moving any further with Gulp, I want to quickly mention that not all of these task runners or build tools (I prefer to call them task runners, you?) are the same. Let me give you a brief overview of other task runners mentioned above.

Grunt

Do you remember Grunt? This is currently the biggest competitor of Gulp. It also offers the biggest amount of plugins you can use. Gulp and Grunt are very similar. The biggest difference these two tools between tools is how you configure them. For example, Gulp configurations tend to be much shorter and simpler. On the other hand, the same cannot be said about Grunt. Also, if you take statistics into account, Gulp is often also faster in tests. The way you setup environment in Grunt is by defining all the tasks and options you want to use in a wrapper function.

On the first line of this function is another one called “initConfig”. This function starts with specifying the package file. Then, you define the tasks you want Grunt to perform and automate in JSON notation (like package). When you are done with that, you have to “load” the plugins. The last step if to register all the task tasks. With this, your work is pretty much done. Now, all you have to do is to run “grunt” in command line or “$ grunt” on the terminal.

Example of Gruntfile.js:

//wrapper function
module.exports = function(grunt) {
// Grunt configuration.
grunt.initConfig({
pkg: grunt.file.readJSON(‘package.json’),
uglify: {
// Compress or minify JavaScript files.
build: {
src: ‘src/js/main.js’,
dest: ‘dist/js/main.min.js’
}
},
sass: {
dist: {
options: {
//Compress or minify output CSS.
compress: true
},
files: {
// Destination file and source file.
‘dist/css/main.css’: ‘src/scss/main.scss’
}
}
},
watch: {
styles: {
// Define what files to watch
files: [‘src/scss/main.scss’],
// If watched file is changed, what task to run.
tasks: [‘sass’]
},
scripts: {
files: [‘src/js/main.js’],
tasks: [‘uglify’],
options: {
nospawn: true
}
}
}
});

// Load the plugins and tasks
grunt.loadNpmTasks(‘grunt-contrib-uglify’);
grunt.loadNpmTasks(‘grunt-contrib-sass’);
grunt.loadNpmTasks(‘grunt-contrib-watch’);

// register task(s).
grunt.registerTask(‘default’, [‘uglify’, ‘watch’]);
};

To run build tasks, type in command prompt window:

grunt

To run build tasks, type in terminal:

$ grunt

Broccoli

Another tool I mentioned was Broccoli. Unlike the previous two examples, this build tool focuses on another common build tool tasks you will probably know very well — asset compilation. One way in which is Broccoli different from Grunt is that when it runs, it will find out which files to watch and what to rebuild when a file changes. In other words, while Grunt will always rebuild the whole project from scratch, Broccoli will work only with files that were changed.

Another difference between Broccoli and other task runners is that it uses trees instead of files. You can imagine tree is a directory with files, sub-directories with files and so on. When it comes to configuration, Broccoli prefers similar code logic like Gulp.

Example of Brocfile.js:

//Load plugins you want to use.
var uglifyJavaScript = require('broccoli-uglify-js');
var compileSass = require('broccoli-sass');
var mergeTrees = require('broccoli-merge-trees');

// Specify Sass directory
var sassDir = 'src/scss';

// Specify how do you want Sass to be compiled
var styles = compileSass([sassDir], main.scss','main.css');


// Merge the compiled styles into one output directory.
module.exports = mergeTrees([styles, 'dist']);

To run build tasks, type in command prompt window:

broccoli build dist

To run build tasks, type in terminal:

$ broccoli build dist

Mimosa

The last task runner I mentioned was Mimosa. According to its website, Mimosa is a lightning fast build tool for modern web development. From what I saw, Mimosa configuration is quite simple. You have to specify only what modules you want to use and folders you want to watch. Then, when you run execute Mimosa (watch task), it will initiate watch task that will look for changes in the folders you specified. If you are using another plugins for compiling less or sass or minifying stylesheets and scripts it will compile everything and minify it.

Example of mimosa-config.js file:

exports.config = {
// What modules to use
modules: [
‘csslint’,
‘jshint’,
‘minify-js’,
‘minify-css’,
‘require’,
‘sass’,
],

// What directories to watch
watch: {
sourceDir: ‘src’,
compiledDir: ‘dist’,
javascriptDir: ‘js’
},

// Location of vendor scripts (relative to sourceDir)
vendor: {
javascripts: ‘js/vendor’,
}
};

To run build tasks, type in command prompt window:

mimosa build

To run build tasks, type in terminal:

$ mimosa build

Back to Gulp

That was a little overview and sneak peek into the most used task runners on the web design and development scene. Now, it is time to continue in our journey to learn Gulp. The first thing we will take a look at will be benefits of using Gulp.

What Are the Benefits of Gulp

The first and most appealing benefit of Gulp is how easy to use it is. Truth to be told, it can be a bit overwhelming at first. However, when you take a minute or two and go through the code, it’s really simple and easy to use. Next benefit, according to the website, is Gulp’s efficiency: “Using the power of node streams, gulp gives you fast builds that don’t write intermediary files to disk.” Next benefit featured is high quality standard. This is in reference to the catalog of plugins that are available to use in Gulp. In short, every plugin created must follow specific guidelines.

Otherwise, it will not be approved. One of the requirements is that plugin stay simple. What this means is that every plugin should do only one thing. It also shouldn’t do things that other plugins are responsible for. You can find more information in official guideline documentation. The last benefit is that Gulp is easy to learn. Well, yes it is easy to learn unless you will take its website as your starting point. If you want to learn about Gulp, third-party tutorial, like the one you are reading right now, is much better option to choose.

Getting Started

Before you can start implement this awesome tool into your project and start experimenting with it, there are some steps you have to do. Don’t worry, in this section, I will take you through the whole process.

Installing Node

The first and most important thing to do is to install Node on your computer. Without having this environment on your device you will not be able to proceed in this guide and make Gulp work. So fire up your browser and head over to Node.js website where you can download it and install on your computer. Luckily, this part of process is quite fast and painless. You will need few minutes.

Installing Gulp

When installation of Node is finished, you are able to work with npm (Node Package Manager). We are going to use this manager to install Gulp on your computer. If you are on Mac or Linux open your Terminal. For Windows users, it will be a command prompt window. Now, you have to run following command to install it as a globally available package (available across your OS).

In terminal:

$ npm install --global gulp-cli

In command prompt window:

npm install --global gulp-cli

Package.json and Dependencies

Okay, you successfully installed Node.js and Gulp on your computer. Next step is to navigate to the directory of your project and create a file called ‘package.json’. You can also open project directory in terminal or command prompt window and let npm create the skeleton file for you. Command for that is following:

In terminal:

$ npm init

In command prompt window:

npm init

When you run this command, npm will take you through short and simple setup process. You will be asked to specify the name of your project (spaces and uppercase letters are not allowed), its version, description, entry point, test command, git repository, keywords, author and license. The only items required for package.json file are name and version. You can skip the rest if you want.

Example of package.json file:

{
"name": "project-name",
"version": "0.0.1",
"description": "Example of package.json file.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Project Author",
"license": "ISC"
}

Once package.json file is created, you will have to install Gulp as a devDependency for your project. devDependencies are basically packages or plugins that will be downloaded by npm into “node_modules” folder in your project directory. You don’t have to care about this folder. npm will create it and manage its content by itself. One more thing … Every time you will install some devDependency, npm will automatically update the package.json file for you. To install Gulp as devDependency, run following command:

In terminal:

$ npm install --save-dev gulp

In command prompt window:

npm install --save-dev gulp

Updated package.json file:

{
"name": "project-name",
"version": "0.0.1",
"description": "Example of package.json file.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Project Author",
"license": "ISC",
"devDependencies": {
"gulp": "^3.9.1"
}
}

Next step is to create another file called “gulpfile.js”. This file has to be also placed in the project directory (root) just like package.json. Inside this file you have to load Gulp plugins by creating new variable called “gulp” with “require(‘gulp’)” as its value. Then, you will only have to create new task. Every task is a function that has one parameter — name of the task — and function that will contain instructions for that task.

Basic gulp.js file:

// Loading Gulp plugin
var gulp = require(‘gulp’);

// New gulp task
gulp.task(‘default’, function() {
// Code for setting the task
});

Adding New Tasks

Now, let’s install couple more plugins to show you how to create and setup tasks. In our project we will want to minify all HTML files, compile sass to CSS and minify JavaScript. To do so, we will need to install following devDependencies (plugins): gulp-htmlmin, gulp-sass, gulp-uglify. Let’s also include plugin for generating source maps: gulp-sourcemaps.

In terminal:

$ npm install --save-dev gulp-htmlmin gulp-sass gulp-uglify gulp-sourcemaps.

In command prompt window:

npm install --save-dev gulp-htmlmin gulp-sass gulp-uglify gulp-sourcemaps.

Updated package.json file:

{
"name": "project-name",
"version": "0.0.1",
"description": "Example of package.json file.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Project Author",
"license": "ISC",
"devDependencies": {
"gulp": "^3.9.1",
"gulp-htmlmin": "^1.3.0",
"gulp-sass": "^2.2.0",
"gulp-sourcemaps": "^1.6.0",
"gulp-uglify": "^1.5.3"
}
}

Quick note: Have you noticed that plugins in package.json are always sorted alphabetically?

Next, we have to add new plugins into gulpfile.js and create necessary tasks. Every plugin will require new variable to load it, just like Gulp. Then, we will create couple tasks for these plugins. We will also create a “watch” task to monitor files sass for changes. You can run every task with command “gulp taskName”. However, we will create additional task in the end of the file to automate all tasks. After that, the one and only command you will ever need will be “gulp” for Windows users or “$ gulp” for terminal.

Finished version of gulpfile.js:

// Loading Gulp plugin
var gulp = require(‘gulp’);
var htmlmin = require(‘gulp-htmlmin’);
var sass = require(‘gulp-sass’);
var sourcemaps = require(‘gulp-sourcemaps’);
var uglify = require(‘gulp-uglify’);

// Minify HTML files
gulp.task(‘minifyHTML’, function() {
// Specifying source folder and files
return gulp.src(‘src/*.html’)
// Running htmlmin plugin
.pipe(htmlmin({collapseWhitespace: true, removeComments: true}))
// Specifying destination folder where will be copied processed files
.pipe(gulp.dest(‘dist’))
});

// Compile sass to CSS
gulp.task(‘sass’, function() {
// Specifying source folder and file (I use one main file with @import)
return gulp.src(‘src/scss/main.scss’)
// Initiate sourcemaps plugin (if not used, skip this)
.pipe(sourcemaps.init())
// Running sass plugin – it will compress output code and log any errors
.pipe(sass({outputStyle: ‘compressed’}).on(‘error’, sass.logError))
// Finish work of sourcemaps plugin (again, if not used, skip this)
.pipe(sourcemaps.write(‘.’))
// Specifying destination folder where will be copied processed files
.pipe(gulp.dest(‘dist/css’));
});

// Minify JavaScript files
gulp.task(‘minifyJS’, function() {
// Specifying source folder and file
return gulp.src(‘src/js/main.js’)
// Running uglify plugin
.pipe(uglify())
// Specifying destination folder where will be copied processed files
.pipe(gulp.dest(‘dist/js’));
});

// Watch for changes
gulp.task(‘watch’, function(){
gulp.watch(‘src/scss/**/*.scss’, [‘sass’]);
});

// Automate tasks
gulp.task(‘default’, [‘minifyHTML’, ‘sass’, ‘minifyJS’], function() {});

What to Learn

Let’s say you want to master workflow with Gulp. How many things will you have to learn? Believe it or not, there are only four methods you will ever need when working with Gulp. These methods are following:

gulps.task(name, fn) — this will define new task; you have to pass in name and a function that will contain instructions for the task.

gulp.watch(glob, fn) — when a specific file will change, it will run specific task that matches

gulp.src(glob) — returns a readable stream — the source folder you want to process.

gulp.dest(folder) — for specifying the destination folder — place for saving processed files

The Perils of Gulp

The biggest issue this tool has to face is related to its novelty. So far, it didn’t manage to build a solid base of support. Although it adoption in accelerating and catalog of plugins is growing, there are things (or tasks) that are just not available yet. At this moment, there is more than two thousand plugins. This number is high, but compared to five thousand plugins available for Grunt there is still space to be filled. The same can be said about tutorials as well.

It is still not so easy to find a good tutorial to understand how to use this task runner and how to implement it into regular workflow. I firmly believe that this article will help change it. I also believe that, the community around Gulp will grow and help other people adoption this tool.

The second issue I often hear from fellow designers and web developers is that you need at least some JavaScript experience to be able to learn how to work with this task runner. Yes, this argument is legitimate. However, since we are dealing with JavaScript task runners, it is quite logical that you will probably need some knowledge of JavaScript. Despite of what I just said, I am not convinced that having a JavaScript knowledge is prerequisite for working with Gulp.

We should take into account that you have to define all tasks only once. Then, you don’t have to look at the gulpfile ever again. And, since every plugin comes with (at least) basic documentation and examples, even someone who knows only HTML and CSS can make Gulp work. However, with regard to current state of the web, I would highly recommend that anyone interested in web design and / or web development should take time to learn JavaScript. Good place to start will be JavaScript 101 series published on this blog. Then, you can take on more advanced topics such as JavaScript Design Patterns.

The question is if the potential learning learning curve is worth investing your time. When you think about the impact and benefits of implementing a task runner into your workflow, I think it is. Just consider how much time will you save for other, more interesting, things if you spend just one or two hours learning how to use Gulp.

Closing Thoughts on Gulp

The last thing I will leave you with is this. Be mindful about how you will write your configuration file. It is quite easy to go too far and overwhelm it by creating a chaotic mess. This can be in terms of how your tasks are defined or the code formatting in general. Remember that your code should be clean, easy to understand and maintainable. Before you write your first task, think about the requirements of your project. Question every task you want to create. Do you need minification? Do you need live reload?

The best way to achieve the most productive workflow with Gulp is by thinking about what are the necessary tasks you need. Remember, you can always add new task when necessary. Tools such as task runners are meant to your work easier and more productive. You should not spend hours configuring them.

Originally published on Alex Devero blog