Gulp Build System Part 1: Fundamentals

If in the past you have ever been intimidated or confused trying to set up a front-end build system you are not alone. A few years ago I had my first introduction to the process watching a video series on YouTube about Grunt. At the time I diligently followed the videos and within a few hours had my first working Grunt setup, well sort of. It functioned as advertised, but to be honest I had no real understanding of how all the Grunt syntax worked, or how all the parts fit together.

If like me you have been scratching your head trying to make sense of it all then keep reading. This post will help give you an overview and provide a scaffolding to help demystify some of these moving parts as well as looking at a simpler, faster replacement for Grunt.

What is a Build System

A build system is simply a collection of tasks (commonly called “task runners”) that automate repetitive work. Typical usage would include compiling preprocessed CSS and JavaScript, concatenation, minification, firing up a server for automatic browser reloading and creating a deployment build. Build systems usually work in tandem with other tools like package managers. While there are literally countless ways to configure your build system lets take a look at three of the most common components in a typical front-end workflow.

Components of a Modern Front-End Workflow
Components of a Modern Front-End Workflow

1. Package Managers

Package managers are tools that are used to automate the installation, upgrading, removal, and dependencies for the packages and libraries used in your dev environment. We will be using both Bower and NPM (Node Package Manager) in our upcoming workflow. If it seems redundant to use two package managers instead of just picking one or the other I completely appreciate where you are coming from. It took me quite a bit of research before I started to understand the subtle distinction between the two. While both manage dependencies, their intended target environments are different.

Package Manager Dependencies
Package Manager Dependencies

As you can see in the diagram above, Bower manages our front-end dependencies while NPM is used to manage dependencies within the Node.js environment. If this still seems a little confusing then look at it like this: Bower is used to manage libraries like jQuery, Backbone, or RequireJS that affect your actual project files. NPM on the other hand handles utility modules that work with node to assist in your build process.

This explanation is of course a gross oversimplification. Both Bower and NPM have many overlapping responsibilities and in some cases the line might be blurred. Though their might be some grey areas to deal with, in general, understanding the intent of both package managers will help clarify which dependencies go where.

2. Preprocessors

Preprocessors are critical to an efficient modern workflow by adding additional features and an optimized syntax that compiles into its native language. Some of the most popular preprocessors used for CSS, JavaScript and HTML include:

  • CSS: Sass, Less, Stylus
  • JavaScript: CoffeeScript, Typescript
  • HTML: HAML, Jade, Markdown, Slim

While most preprocessors can be used independent of build tools like Gulp or Grunt, pairing your preprocessors with your build tools gains you both efficiency and enhanced functionality. For example, watch tasks are frequently created to watch for file changes and then update the browser. We will look at this much more in detail in part three of this series.

3. Task Based Build Tools

Now lets get to the meat of it, Gulp and Grunt. Both run on Node, both are great tools, and both share a similar anatomy. Although we will be using Gulp in this series, Grunt follows the same overall structure. We will be getting into a few of the core differences between Grunt and Gulp in the next section, but for now lets take a look at the structure of a typical gulp file.

Structure of a Typical Gulp File
Structure of a Typical Gulp File

Starting at the top and moving down, the first step is to declare which modules will be required by Gulp. This is where we declare both gulp itself as well as all the dependencies we need for our build.

Following this we have our named tasks (name them whatever makes sense to you) which tell Gulp what you would like it to actually do. One optional task that is also frequently added is the ‘watch’ task. When you add this special task you specify certain files and folders that you want Gulp to watch. When Gulp detects a change, it will automatically run one of your named tasks.

Named tasks can be run by simply running “gulp [task-name]” into your terminal. Named tasks can do anything from compressing static images and copying files to creating a deployment build. To run a task named ‘scripts’ you would type:

There is one additional task that is usually used as well. It is called the ‘default’ task and it simplifies the process even more by running a series of tasks define in an array by simply using the command ‘gulp’. It’s important to note that these task are called asynchronously and all fire up at the same time. This default behavior can be overridden if you require a particular sequence of tasks to run. I will demonstrate how this can be accomplished when we start coding up our actual build.

Grunt Vs Gulp

So should you use Grunt or Gulp for your next project? It doesn’t really matter. Both do exactly the same thing, they just do it in different ways. However as you may have guessed I feel Gulp has a slight advantage over Grunt in several respects.

gulp-vs-grunt

  • Grunt relies on A LOT of configuration and a steeper learning curve. For me personally I find the JSON styled syntax overly verbose and hard to remember, especially when revisiting the code several months later.
  • Grunt can be slower. When Grunt runs a set of tasks it has to write the results of each task to a temp file before going to the next. This repetitive process can theoretically slow things down on a more complicated build. Gulp on the other hand uses streams which are readable, writable data that can be modified or piped (think Unix pipes) from one function to another. Because it does not have to write its results to a temp folder, and is executed asynchronously, it is able to take advantage of maximum concurrency.

While Grunt is still the big kid on the block, there seems to be a growing shift in momentum towards Gulp. I am seeing more and more developers endorsing Gulp. Even Google has switched to Gulp in their “Web Starter Kit”.

For me it boils down to ease of use. Gulp is much easier to learn, remember and ultimately maintain.

Please join me in the next section as we move away from theory and get deep into the code. We will build a practical example of a working build system as well as learn a few new tricks along the way.


Like to leave a comment on this video?

Comments have been automatically closed on this post but don't let that stop you. Head on over to this videos YouTube page and let your voice be heard!

2 comments

  1. Hi Joel, your posts are great!! Very clear and and understandable.
    They are a good help to start with gulp and front-end projects written in javascript.

Comments are closed.