Getting To Know Gulp

If you have been developing websites in the past year or so you have probably heard the term gulp mentioned often. Like many other designers and developers, I too always strive to stay on top of the latest tools, standards, and more when it comes to building websites. It’s pretty much our job to do this, as the web and appsphere are constantly growing. Where does Gulp fall into this rant?

Well, Gulp is among a number of task runners available for designers and developers to use in virtually any type of project. Over the past few years, Gulp has gained a lot of popularity and stands out among the community. This article will discuss Gulp from the point of view of a beginner. If you are coming from an app like Codekit or Prepros then this will hopefully get you off the ground in no time.

What is Gulp

To understand what gulp is you first have to understand what a task runner is.

A task runner is a set of scripts that automate your workflow during development. By nature, it doesn’t do anything until you tell it to. As you code HTML or CSS, (tons of other languages can be used with Gulp) for example, a task runner can help you by doing things such as code minification or linting to make sure your code is up to spec. Task runners effectively save time and provide a hand with otherwise mundane tasks we used to have to do like refreshing your browser or checking to make sure your markup is valid.

Gulp is a JavaScript task runner built on top of Node.js that offers a streaming build system at its core. This system allows you to chain or pipe your code through a bunch of available plugins which alter and enhance your code as you do any type of build. It’s incredibly fast and with a little setup time you can save many headaches down the line.

Examples of what can Gulp do (with the addition of various plugins)

and that’s only scratching the surface. At this time, there are 1866 plugins to choose from on the gulp.js website and probably more open-sourced plugins on Github. You can pretty much bet that a number of plugins will continuously rise, thus making our lives as developers a little bit easier.

Transitioning from a GUI

When I first got into task-runners I used an app called Codekit which I still make use of for private projects. At its core, Codekit does what Gulp can do but provides you with a very attractive interface. The problem with Codekit is its ability to work within most teams. While it’s possible using a Codekit specific language, you still have to assume your team is all on Macintosh based computers which is limiting from the get go.

Gulp can work on any system with Node.js installed. It’s especially useful for teams based on how you set up a project. Dependencies and various settings are configured inside a file called package.json. This file tells Gulp and Node what the project depends on to get up and running. As long as your team has this info everyone should be able to make use of the same code and install the same dependencies. This is huge and why Gulp is so popular.

Basic Command Line Stuff

As with most task runners that don’t have a GUI, (graphical user interface) some prior knowledge/familiarization with the command line is definitely preferred before you dive deep with Gulp. Luckily, if you’re new to the command line, Gulp is fairly straight forward. Each package you install has instructions to go along with it that are pretty easy to understand. Gulp itself is a module you have to download using Node.

Installing gulp and making use of it is done in as little as 4 steps. Below I’ll walk you through the process of getting a project set up with Gulp for the first time. We’ll then install some plugins and give them a try. From there you can use the project code to install more dependencies or just get used to gulp itself. The more you use it the more you’re going to like it and depend on it in your upcoming projects. I promise!

Getting Started

Let’s set up a basic project using Gulp and a few more dependencies. I’m starting from scratch, but you should know there are awesome tools out there that provide automation for a lot of projects which can save loads of time. One that comes to mind that I use often is Yeoman. Once you get familiar with the command line and using Node, Gulp and more you should check it out.

1: Create a root project folder

My project starts with a simple folder I’ll call gulp-playground.

The contents of my project are as follows:


/gulp-playground
-/css
- /img
- /js
-- /dist
-- /dev
--- main.js
- /sass
index.html

2. Install Node.js

[responsive imageid=’1611′ size1=’0′ size2=’600′ size3=’1000′]
To get gulp and any other plugins to work correctly, we need to first install Node. This part is simple. Simply head to nodejs.org and download the package for your system. There is no need for the command line on this one.

3. Create a gulpfile

Next, we need to add a one more file to our project. Inside this file will be the necessary configurations for all the dependencies we want in our project. Name this file Gulpfile.js. Don’t worry about adding anything just yet. Our project now resembles this structure.


/gulp-playground
- /css
— /img
- /js
-- /dist
-- /dev
--- main.js
- /sass
index.html
Gulpfile.js

4. Command Line

With our initial files in place, we need to make use of the command line from this point forward. I’m on a mac so I typically use Terminal or iTerm2 : highly recommended.

Open your command line application of choice and change directories to your project. To do this easily on a mac type cd and then drag and drop your folder into iTerm2 like this. You can type the path of the file if you know it, but I find my method a little easier.

change directories gif

From here we are ready to initialize our project.

$ npm init

Type the code above on the command line then hit return. When you type this command some directions will appear to help guide you through the initial setup. What’s happening here is some Node.js magic that creates a new file called package.json. This file contains some data specific to the project. The package.json file makes it easy for teams as each team member will be able to know what dependencies and utilities are used because it’s all documented the package.json file.

Note that no dependencies actually exist inside the file. It’s typically only what dependencies and their version. Node makes use of npm which is short for Node Package Manager. Most of the time when setting up your project you’ll be typing npm to start things off. More on this in a bit.

The text that appears looks like this:


This utility will walk you through creating a package.json file.
It only covers the most common items and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterward to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (gulp-playground)
Configuration

The utility you see will guide you through some quick steps to create a package.json file. Below I’ve outlined each step as well as what to type.

  1. Name
    From here you can configure the wizard as you please. For the name, we will just use the default (gulp-playground). You can just hit return.

  2. Version
    If you are working on an improvement or newer version of something you can supply that info here. Again for our project we will just use the default of 1.0.0.

  3. Description
    This is pretty self-explanatory. If you want to give a short description about the project this is the time and place to do so. For this, I’ll enter ’A project made to better familiarize myself with gulp.’

  4. Entry Point
    The entry point is basically the default file to direct to in your project. For this, we’ll just use index.html. Type index.html and hit return.

  5. Test Command
    You can ignore this for now. Hit return.

  6. Git Repository
    If you want to use version control the option is here to include the direct repo link. For this tutorial, I’m not going to use a git repository. Just hit return again.

  7. Keywords
    Think of these as tags for your project if you decide to publish it on the web as an npm package. Again, just leave this blank as it doesn’t apply. Hit return.

  8. Author
    Enter your name and hit return again.

  9. License: (ISC)
    This doesn’t apply to this project so hit return again.

After all of that configuring you should end up with a block of json code like this:


About to write to /Users/username/Desktop/gulp-playground/package.json:

{
  "name": "gulp-playground",
  "version": "1.0.0",
  "description": "A project made to better familiarize myself with gulp.",
  "main": "index.html",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": “Your Name“,
  "license": "ISC"
}

Is this ok? (yes)

If everything looks ok just type yes and hit return. Once you do npm has successfully created a package.json file with the root of our project. The new structure appears as follows:


/gulp-playground
- /css
— /img
- /js
-- /dist
-- /dev
--- main.js
- /sass
index.html
Gulpfile.js
package.json

Obviously to view these files you’ll need to open them in a code editor of your choice.

Installing Gulp

At this point, we have our project all set up to begin installing dependencies. To install gulp, our first dependency, type the command below:

$ npm install --save-dev gulp

You may encounter an error regarding permissions. You can override this by typing sudo before the entire line.

$ sudo npm install --save-dev gulp

Some Explanation

You may find yourself typing sudo a lot on a mac. There is a recommended workaround to install packages in a safer manner, but that’s a topic for another time.

Using sudo prompts you to type in your password on a mac. You won’t see what you type when doing so, but whatever you do type your command line utility is recognizing.

npm install is a command used to install dependencies from resources on the web. npmjs.com houses a multitude of packages for you to make use of depending on the project at hand.

--save-dev is a unique command that saves your dependencies inside your project rather than on your global computer. If you want to save dependencies globally you just type this instead:

$ sudo npm install --global gulp

After you initialized the npm install command your project just grew a bit in size. There is now a new directory called node_modules. Inside are all the dependencies you are saving each time you install a new one. If you installed them globally they would appear on a system folder as opposed to inside your project.

Setting up the Gulpfile

Gulp is now installed. Now comes some initial setup inside the file calledGulpfile.js.

Open Gulpfile.js and enter the code below to get started.


var gulp = require('gulp');

gulp.task('default', function() {
  // place code for your default task here
});

Here we are using JavaScript and creating a variable in which we will use that points to gulp as a project dependency.

Below the first line is what is called a task. Tasks run as soon as you run the command $ gulp on the command line. You can configure however many tasks you want inside Gulpfile.js.

Right now if we ran the command $ gulp nothing would happen. To change that let add more dependencies.

Adding Multiple Dependencies

You can install dependencies one-by-one, but that’s painfully time-consuming and a bit inefficient. To install more than one at a time, simply add a space between each package name like the code below. Be sure to double check your spelling. Formatting matters tremendously on the command line.

$ sudo npm install --save-dev gulp-sass gulp-autoprefixer gulp-minify-css browser-sync gulp-concat gulp-uglify gulp-watch

In this block of code, we are installing 7 packages at once. They are being saved inside our project thanks to the --save-dev flag. Remember, we already have gulp installed so you won’t see it in this list.

You should see that the packages installed successfully. From here we need to configure each inside Gulpfile.js.

Rather than go through one by one I’ll just share my typical setup and explain an overview of how gulp is being used for each package. Here’s my current Gulpfile.js all configured:


var gulp = require('gulp'),
    sass = require('gulp-sass'),
    autoprefixer = require('gulp-autoprefixer'),
    minifycss = require('gulp-minify-css'),
    browserSync = require('browser-sync').create(),
    reload = browserSync.reload,
    concat = require('gulp-concat'),
    uglify = require('gulp-uglify'),
    watch = require('gulp-watch');

gulp.task('browser-sync', function() {
    browserSync.init({
        proxy: "localhost:8888/gulp-playground"
    });
});

gulp.task('sass', function () {
  gulp.src('sass/**/*.scss')
    .pipe(sass({
        outputStyle:'compressed',
    })
    .on('error', sass.logError))
    .pipe(autoprefixer({
        browsers: ['last 2 versions'],
        cascade: false
     }))
    .pipe(gulp.dest('./css'));
});


gulp.task('watch', function() {
    // Watch .scss files
    gulp.watch('sass/*.scss', ['sass']).on("change", browserSync.reload);
    gulp.watch('sass/**/*.scss', ['sass']).on("change", browserSync.reload);
    gulp.watch('js/*.js', ['js']).on("change", browserSync.reload);
});


var jsInput = {
    js: 'js/dev/**/*.js'
}

var jsOutput = 'js/dist/';


gulp.task('js', function(){
  return gulp.src(jsInput.js)
    .pipe(concat('app.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./js/dist/'))
});

gulp.task('default',['sass', 'browser-sync','watch', 'js']);

Overwhelmed? It can be daunting to see all this random code at once but I promise, the more you use gulp and see what other designers and developers are using it for, the more familiar the syntax and language will seem. For any packages, you want to install there is usually good documentation to accompany it. You’ll need to read each but again the more you use certain dependencies the more you won’t depend on the documentation.

1.Defining Variables
To start off, you need to define variables for each dependency you plan to use. This typically takes place at the top of most gulp files so anyone on your team can see what’s being used very quickly.

2. Tasks
I continue to define a few other variables down the page, but they are relative to a specific gulp task. For each package, you’ll notice some similarities.


gulp.task('some_name', function(){
  // task based code goes here
  .pipe(some_variable({
    setting: 'parameter'
  }))
}};

3. Piping
Nearly every task contains a .pipe() method. Think of pipes as literal pipes. You can connect multiple pipes together and stuff flows through them. Depending on the package or dependency, piping through them does different things. Take the sass task for instance.


gulp.task('sass', function () {
  gulp.src('sass/**/*.scss')
    .pipe(sass({
        outputStyle:'compressed',
    })
    .on('error', sass.logError))
    .pipe(autoprefixer({
        browsers: ['last 2 versions'],
        cascade: false
     }))
    .pipe(gulp.dest('./css'));
});

4. Telling Gulp where the source sass files are
I defined a variable called sass which points to the gulp-sass dependency we installed prior. From there we use a function to define how the package is configured. First we define a source for the sass files.

gulp.src('sass/**/*.scss')... 

The *‘s are known as wildcards and simply mean to target any file associated inside a directory or sub-directory. I’m targeting only files with the .scss suffix. The fact that I have /**/ in between my sass folder and the *.scss suffix means that we are targeting any folder within the sass folder as well as any file with a .scss suffix below that.

5. Compiling Sass
The gulp-sass plugin compiles sass into regular css code. You can define the way it compiles and more. Read more about it here.

6. Built-in Sass error handling
From there we use a neat utility that comes bundled with the package.

.on('error', sass.logError))

This utility is particularly useful if you manage to type some sass code wrong as it points out which file and line the error occurred at.

7. Auto-prefixing
Writing css for multiple browser support can be a huge pain in the ass. Luckily, we installed the gulp-autoprefixer package to help us do this automatically.


.pipe(autoprefixer({
  browsers: ['last 2 versions'],
  cascade: false
}))

Here we pipe through the variable autoprefixer which points to our dependency. Then inside the method we define some options specific to this package. You can read more about other options and parameters here.

8. Distributing Sass as CSS
Finally after all of the piping is complete our code is automatically compiled and delivered to our css directory.

Notes
To make the sass task work you first need to create a root file inside the sass directory. Let’s create one called style.scss for now. Inside it lets add a reset made famous by Eric Meyer. If you’re new to Sass don’t worry. I won’t be covering it in this post, but I will be in future posts so if you want to learn, be sure to subscribe to our newsletter.


/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, I, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
  display: block;
}
body {
  line-height: 1;
}
ol, ul {
  list-style: none;
}
blockquote, q {
  quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
}

Add the code above and save your progress. Next, navigate to your command line and run:

$ gulp

If all goes accordingly, check your css directory. You should see your sass code minified nicely inside a new file called style.css


Cool stuff right? Pro tip: To kill/quit gulp tasks type ^c.

What is the ‘default’ task?

Well, gulp by default uses the default task to execute when you type $ gulp in the command line. You can pass an array of gulp tasks inside the default task so that when you type $ gulp in the command line, all of your tasks execute at once.

If you want, you can execute them individually. Doing that can be done by typing something like:

$ gulp sass

This would only execute the gulp task titled sass.

Assets

Final Words

This post is meant to be a starting point for designers and developers who are new to the task-runner world or want to get away from native GUI based applications like Codekit. Those applications aren’t necessarily bad, but they are limiting in a few ways when it comes to working with teams or on open source websites and applications.

Gulp is incredibly powerful as well as customizable. You can use massive amounts of dependencies inside your projects to automate your workflow as well as customize it to your needs. With a little setup time (the only downside), your workflow can be completely automated. I invite you to try and make the switch today if you already haven’t. You’ll be glad you did.

Useful Links and Resources

  • This is very useful, as you I come from CodeKit too and I want to give a try to gulp. This post helps me to start whit it and develop a workflow that I can share with my coworkers.

    • Thanks for reading Mark. I love CodeKit no doubt but sometimes I need more control. Gulp is my remedy for that.