Learning Gulp

Getting Started With The Front End Factory

Gulp is a JavaScript based automatic task runner. With it, you can compile sass, include & concat files, package JavaScript, upload files to servers and much more. You can, of course, do all that without Gulp, but it's a lot easier with it. In his gitbook, David Nowinsky described Gulp as a factory. I really like this description. Gulp, much like a factory, takes files and turns them into other files with very minimal effort. In this guide, we will learn the basics of gulp.js, how to avoid some common pitfalls, and build our own gulp system.

The Basics

Plugins

Plugins extend the functionality of Gulp. Gulp's philosophy is that plugins should only perform one action, this way it is easy to combine plugins to create complicated functionality easily. All approved plugins are listing on Gulp's plugin page. Gulp curates their plugins to ensure high quality. It's suggested you use the official Gulp plugin database so you do not use harmful or non-working plugins.

Streams

Gulp uses streams to link programs, or in this case plugins, together. This relieves your system of temporary files while providing blazing fast functionality. Going back to the factory analogy, they are the conveyor belts, moving from one program to the other.

Tasks

Tasks are how you control Gulp and are defined with gulp.task function. Tasks can do many things, including interacting with plugins and streams. You can link tasks together and create dependencies. If streams are the conveyor belt, then tasks are the assembly line.

Getting Started

Installation

Installation for macs are pretty simple, however there are a few dependencies you'll need. The first thing you'll need is node.js. After that, you'll need Node Package Manager, or NPM for short. NPM will handle your plugins for gulp and gulp itself, but it does many awesome things on its own. To install npm, open up your console and enter sudo curl -L https://npmjs.org/install.sh | sh. You'll be prompted for your password. Once you have NPM, run npm install gulp -g to install gulp globally.

Building Your Gulpfile

Now that you have a grasp on the basics and have everything installed, it's time to build you own gulp file! First, you have to figure out what you want your gulpfile to do. if I had to figure out my favorite task to auto has to be SCSS to CSS with an auto-prefixer. You should start off by searching the official Gulp plugin database for the correct plugins. However, I have two favorites that'll do the job just fine, gulp-scss and gulp-autoprefixer.

Once you have found the plugins, it's time to install them. To install, open the console and navigate to your project. Then enter npm install gulp-scss --save-dev. This will install gulp-scss and mark it as a dependency in your package.json file. This is important because instead of having to commit or send the large node_modules, the directory where your NPM plugins are stored, you can simply commit this file. Other developers can then install the required dependencies with npm install --dev.

Time to kick off some gulp development! First thing you need to include is the plugins you just installed:

var gulp = require('gulp');
var scss = require('gulp-scss');
var prefix = require('gulp-autoprefixer');

The dependencies are very important to include. If not included, gulp won't know what to do and will error out. After the dependencies are included, we can build our first task. Tasks have 4 elements that you need to know:

Name

The name is pretty self explanatory, I feel. It's what your task is called, and how it's called. Each task's name should be unique. A task named "default" will run on gulp command. Otherwise, gulp task-name will run your task.

Source

The source is the path to the file you'd like to run through gulp. It can be a direct file, such as "css/main.scss" or it can be multiple files like "css/*.css" or "css/**/*.scss". The former will get all files in the top level of the css directly while the latter will get every file, even "css/asburd/path/to/file.scss". it is also possible to have an array, to you can have multiple inputs.

Pipes

Pipes is like, well, a pipe. If you're experienced with the console, it probably rings a bell. Pipes is how gulp moves the input from one plugin to another.

Destination

The final pipe is the destination, more often than not. This is where you want the final file to be. It should be a path to a folder, and it will assume the source file name. You can use a plugin to change that, but it is not possible through gulp.dest as far as I know.

Below is an example of a gulpfile. It'll take a scss file, compile it to css and then use the auto-prefixer to insert browser prefixes. When it's done, it'll output a css file to "public/css".

var gulp = require('gulp');
var scss = require('gulp-scss');
var prefix = require('gulp-autoprefixer');

gulp.task('defualt', function(){
	return gulp.src('main.scss')
	.pipe(sass())
	.pipe(prefix())
	.pipe(gulp.dest('public/css'));
});

To run our gulp file, simply enter gulp.

Advanced Techniques

Now that you have the basics down pat, it's time for something more challenging...

Chaining

Chaining is pretty cool. It taking one task and calling another before running. In the example below, I am chaining "sass-to-css" to "prefix-css". Now, when I call "prefix-css", it will run "sass-to-css" beforehand.

var gulp = require('gulp');
var scss = require('gulp-scss');
var prefix = require('gulp-autoprefixer');

gulp.task('sass-to-css', function(){
	return gulp.src('main.scss')
	.pipe(sass())
	.pipe(gulp.dest('public/css'));
});
gulp.task('prefix-css', ['scss-to-css'], function(){
	return gulp.src('public/css/main.scss')
	.pipe(prefix())
	.pipe(gulp.dest('public/css'));
});

Watching

You can also set up gulp to only run when a file is changed.

var gulp = require('gulp');
var scss = require('gulp-scss');
var prefix = require('gulp-autoprefixer');

gulp.task('sass-to-css', function(){
	return gulp.src('main.scss')
	.pipe(sass())
	.pipe(gulp.dest('public/css'));
});
gulp.task('prefix-css', ['scss-to-css'], function(){
	return gulp.src('public/css/main.scss')
	.pipe(prefix())
	.pipe(gulp.dest('public/css'));
});

gulp.task("watch", function(){
	gulp.watch("main.scss", ["prefix-css"]);
});

When you run gulp watch, it will not end like a normal task. It will remain open, watching for changes to "main.scss". Once a change is saved, it will run "prefix-css".

Error Handling

Error handling is very important, especially when using watching. For a while, I had to watch my watch task to make sure an error didn't break it. Now, I have a dedicated error handle that sends an alert and even notifies me with sound. This is a pretty indepth topic, and has it's own post here.

Comments