Entity view (Content)

Gulp Best Practices

By alafontaine
Dec. 9, 2015

Gulp (http://gulpjs.com/) has been my favorite task runner 1 for a while now and I wanted to share some of my personal practices I’ve grown to use consistently over time.

You can find templates I’ve worked on here on GitHub:

I’d suggest you have a look at the templates before or while reading this since most of the patterns I’m describing are exemplified there. These are in a work-in-progress state, but feel free to have a look and borrow some of the elements I’ve put together. 

Gulpfile.js at the root of your project

When starting a project or inheriting an existing one where you intend to setup Gulp, I find it best to always put the gulpfile.js at the root of the repo where it is one of the first files a newcomer to the project will see. This serves two purposes:

  1. Let the project participant know the project is using Gulp in some manner and they should take some time to make sure they know what is already available to them so that they can be faster getting up and running.
  2. Be a living documentation of actions you may have to take when you work on the project. By writing a task that does one or many different things in an automated way, it also insures that all team members will not miss a special use case or an uncommon switch was required when firing some command line base process or script.

You should also have your package.json and other project configuration files living at the same level as an extension of that thinking.

Gulp.config.js configuration file

By isolating project specific variables for base paths, assets folder paths or output paths to a separate gulp.config.js file, it's possible to keep the base gulpfile.js more generic while letting the users expand the task runner to handle extra cases for each task by adding new paths to inputs, or easily changing outputs to accommodate a new deployment tactic, etc.

Since we’re building our Gulp tasks on top of Node.js, I’ve found it comfortable for me to just export those configurations as a node module then returning a single config object.

Here’s a snippet of the general shape of it:

module.exports = function() {
  var config = {
    base: {
      app: ‘./docroot/‘,

  return config;

Then in your gulpfile.js you need to set your import like the following (please notice the execution of the required file to make sure the module code gets executed):

var config = require(‘./gulpfile.config’)();


List tasks by default

Make the default Gulp task list all the tasks you have in your gulpfile.js.

Just do it.

To simplify this, there’s a gulp plugin called gulp-task-listing.

gulp.task(‘default’, function() {
  return tasks.withFilters(null, ‘default’)();

This snippet of code, set as your default task, will list all your tasks, but the default one.

Define main and sub-tasks

Using the previous plugin, you can get your tasks listed under main and sub-tasks:

Main Tasks

Sub Tasks

This keeps your code organized, but also pushes you into breaking down complex tasks into smaller independent ones that you can orchestrate in the main task.

So in this example:

gulp.task(‘sass’, [‘sass-watch’]);

Then sass-watch relies on sass-compile:

gulp.task(‘sass-watch’, function() {
  gulp.watch(config.assets.sass, [‘sass-compile’]);

Also note the usage of our config object in the snippet above.

In Conslusion

This post doesn’t delve into specific things like preprocessing Sass, Javascript linting or file aggregation which I’ll leave for other tutorials to discuss at length. My goal was to give some guidelines on how to keep your Gulp setup tidy and make you feel at home with your Gulp setup the next time your start a new project. 

1 task runner: a system to document and automate a variety of things you may need to do in the context of a project. Normally includes file pre-processing (Sass, TypeScript, etc.)



Post Tags: