Using Gulp With Craft

All Those Boring Tasks

Let me start by saying this: I really love to code!

Every time I begin transforming designs into live code, I get excited and full of energy. Everything feels new and different. But at a certain point, you get to a place where you have to complete tasks that you repeat over and over again for every project, and my enthusiasm lags. Installation of project files, image optimization, minification of CSS and javascript files—the necessary but tedious stuff. Make sure you don’t duplicate lines of code and that you removed unused files, make sure every CSS rule is prefixed…

And I just hate those tasks!

Nothing is more tedious than reading your CSS file for the tenth time to make sure you didn’t duplicate something. And if you’re like me, your egoistic mind will trick you into believing that you can’t make such an error, and you’ll wind up overlooking a number of duplicates.

A couple years ago, I had a long list of services that I used for these tasks. I spent hours copying and pasting code into online generators every time I changed a couple lines of code or added assets. And then had to refresh my browser after every change… come on! I can’t tell you how many times I thought, “If only we could hire somebody to do this for us.” Well today we can—task runners FTW!

What Are Task Runners?

In short, task runners are Javascript tools that help us automate all of those repetitive yet essential tasks. Next to your text editor or IDE, these are some of the most widely used and important tools for Web development work. Every time we save our work, the task runner analyzes, compiles, optimises and finally refreshes your browser—all in a split second. How awesome is that?!

Today we have a lot of task runners and most developers use one of them. These include Grunt, Cake, Broccoli, and our tool of choice: Gulp.

Desktops with open text editor and Gulp homepage

How Gulp Works

  1. We start by defining a task that we would like to accomplish.
  2. Within that task, a desired set of files are loaded into the Gulp stream to be processed.
  3. Once files are in the stream, one or more modifications can be made to the files. Because the streams are processed in memory, no file system writes to temporary directories between modifications are required.
  4. Send the new (possibly modified) files to a specified destination
Desktops with open text editor and Gulp homepage
Ryan Irelan has a great screencast that can get you started over at Mijingo

How We Use Gulp with Craft

This is not a definitive tutorial for using Gulp with Craft, because one company’s configuration is not always right for another’s. There are manyarticles and screencasts about Gulp configuration for Craft out there, and the beautiful thing about task runners is that you can make them work however you like.

In this article, I will share how we use Gulp and encourage you to incorporate these tools into your own workflow.

Our team uses Craft for content management, which handles all of our templating, so we don’t require a template engine. But if you’re working on a front-end prototype, you can compile static HTML using template engines such as Twig, Liquid, Haml, or Jade.

What’s next? We need to give our website some style!

CSS

So let’s start with the process that includes most steps—the CSS pipeline.

Most developers today use CSS preprocessors. These give us the ability to make our CSS maintainable by breaking it into small “component” files. In our development process we are using Sass with SCSS syntax, but you could also use Less or Stylus.

The primary use for this is to compile SCSS files into our main CSS file, but we can find some additional uses depending on how we compile files for development or production environment.

During development, we need to quickly debug our errors. This can be difficult when using preprocessors because we see our compiled code, not source files. To debug in places where CSS is rule written, we use sourcemaps. Source maps provide information about what SCSS file holds the rule and on which line it’s written.

What about vendor prefixes?

Autoprefixer solves any issues with prefixes by parsing our CSS files and adding vendor prefixes to CSS rules using the Can I Use database.

After we‘re done with development, we need to optimize our code for production. For that, we use a Gulp plugin based on CSSO – CSS Optimizer.

Javascript

To ensure that we use the same code style in our javascript files and that our javascript is equally bug-free, we use JSCS and JSHINT. You might use these already with your text editor, as most IDE and text editors are now configured to support them.

JSCS is a code style linter/formatter, so it checks if we have the right indentation, spacing inside brackets, and how many blank lines we use in specific cases. You can configure coding rules to your needs—read more about this here.

JSHINT is used tool very similar to JSCS, but it provides a little bit more detection in the functionality of your code. Some JSCS and JSHINT functionalities overlap, but to get the best result we suggest using them both.

Desktops with open text editor and Gulp homepage
We plan to replace JSCS and JSHint with ESLint in our build

In the future, we plan to replace this JSCS/JSHINT combination with ESLint. ESLint covers everything we need in one tool, but we simply haven’t found the time to set up our workflow yet. It’s also worth mentioning that one of the cons of ESLint is that it’s configuration docs are a bit confusing.

Image Optimisation

Online services for optimizing images have been around for quite some time now, so that’s nothing new. But how much time is lost optimizing every image manually and how many times you need to repeat that task? And how can we check for and remove images that we don’t use any more?

Using a Gulp plugin for formatting images like gulp-imagemin, we can optimize all of images that we use for our project using one simple command.

If you’re a Grunt user, you’ll notice that I said “one command” and might ask why don’t we create a task that “watches” for image files. Well... Gulp has a built-in “watch” function that watches over changes in the present file, but doesn’t check for new files. So we can’t automate a task so that it works when a new file is added. However, if you set a task for watching changes inside CSS and JS files, you can add the image optimization task as a Gulp task dependency and just re-run the ‘watch’ command.

SVG Sprites

Every website today uses some kind of system for displaying icons. Most development teams already take advantage of an SVG sprite system and we are no different.

So let me give you a short explanation of how SVG sprites work. We start by creating one big SVG image containing a number of small SVG images. We include this big SVG image file as part of our HTML file and then we call to one of the icons using SVG xlink:href attribute.

To produce that sprite, we use the Gulp SVG sprite plugin, which optimizes and concatenates SVG images as desired, but we still need to add that markup inside our HTML.

For this, we use gulp-inject. Gulp inject is used to add add a string in our markup, so basically it converts our concatenated SVG sprite to a string that later gets added where we want it placed in our HTML.

In the previous version of our project setup, we injected SVG to partial called icons.html that we later included at top of the body element in markup. But in the latest version, we are storing icons to browser local storage. You can learn more benefits of using local storage in this great article by Osvaldas Valutis.

Desktops with open text editor and Gulp homepage

Browsersync

So now we only need to refresh our browser when we make some changes in our markup. Let me introduce you to Browsersync.

This plugin reloads the browser when we make changes in our HTML or JS and it injects CSS every time you make changes in SCSS files. It works in sync with all activated browsers, and tracks interactions across a website. For example, if you’re filling out a form on your desktop browser, you can check this same behavior on your tablet or mobile devices at the same time.

EditorConfig

EditorConfig is not really used with Gulp but it’s still a very important part of our development setup. EditorConfig is a file that helps us define and maintain consistent coding styles between different editors and IDEs. So in short, it makes sure everybody in our team use the same indentations or charset.

Most text editors and IDEs have built-in native support for EditorConfig, but some of them (like my personal favorite Sublime Text) you’ll need to add a plugin.

Why We Prefer Gulp

Why choose Gulp over Grunt, or some newer tool like Webpack?

Ultimately, the choice is up to you. Every tool will have some pros and cons, but for us, Gulp hits the sweet spot.

We started with GruntJS as our first task runner and it was pretty great to use. But with GruntJS, you have a lot complicated configuration. Every step you make during one Gulp task, you need to write as a task. If you remember in my explanation about how Gulp works, I mentioned that everything is saved in a “stream” until we output it in a file. Unfortunately, Grunt requires a file for every step.

Desktops with open text editor and Gulp homepage
Webpack's Hot Module Replacement is a real revolution

What about Webpack?

Webpack is very powerful and efficient. It includes advanced features like Hot Module Replacement, which is a real revolution. It also has the ability to import CSS files from your JS and other features not seen in Gulp and Grunt. However, the learning curve is much steeper, and I’m not convinced that these functionalities benefit website developers enough to compensate for the amount of learning required.

That said, if you’re primarily in the business of Web app development, I would strongly recommend using Webpack.

What Else Can We Do With Gulp?

There are couple other steps in our development process that we didn’t build in our Gulp configuration, but we find them very interesting.

We created a bash script for downloading the newest version of Craft CMS and replacing Craft configuration files with ours. That is something we plan to move to Gulp so we don’t use too many tools in our process.

We’d also like to transfer our deployment/syncing process to Gulp from DeployHQ.

This way, we won’t have to set exclude files for every project on DeployHQ and we’ll reduce time for syncing databases.

Other, Not So Obvious Benefits of Using Gulp

As you can see, including Gulp in your workflow can save a ton of time on repeated tasks. But I want to highlight some other benefits that might not quite so obvious.

One, you don’t need to keep track of all the small, menial stuff. That helps your brain process more important questions, like “Do we use best practices when querying for data in Craft?” or “Do we need to make different components to make our code modular?”

A primary benefit for me is that I can maintain concentration, keeping my focus on the important tasks at hand, rather than having to think about optimizing a couple of images.

If Gulp is So Great, Why Doesn’t Everyone Use It?

Many developers are intimidated by Gulp and other preprocessors, as it may seem very hard and complicated, especially if you’re not familiar with javascript. But you don’t need to really understand javascript to work with Gulp, and it’s not really as hard as it seems. Here’s an excellent article to get your started with Gulp. Believe me, you’ll feel like a Gulp wizard in no time. That is how easy it is!

After that, you’ll wonder how you could have ever lived without it.