Accueil / Blog / Métier / 2015 / Make your Gulp modular

Make your Gulp modular

Par Eric Brehault publié 05/01/2015, édité le 25/01/2016
Good structure practice to avoid a 500 lines long Gulpfile.js file.
Make your Gulp modular

The problem

Using Gulp (or Grunt) is now a very common practice in front-end development.

Gulp allows to automatise many tasks like minification, SASS or LESS comiplation, tests launching, auto-reload, etc.

As its usage is quite large, we generally ends up with a quite big gulpfile.js, starting with a bunch of "require()" to load the dependencies, then a long list of tasks which have been probably copy/pasted from an older project or from Stackoverflow and customized a little bit to fit the current project.

So basically it looks like that:

Le bureau de mon chef

That is not optimal, not easily maintainable, not modular, and not highly reusable.

The solution: modular tasks

After reading this excellent article about Gulp and Browserify, I decided to move to a modular approach for my Gulp tasks.

The principe is simple. The gulpfile.js in the project root is very light, it just does a require-dir on a subfolder named ./gulp/tasks:

var requireDir = require('require-dir');
requireDir('./gulp/tasks', { recurse: true });

In this subfolder, we have one file by task. Each of those files will make its own require() to load the dependencies the task needs and will only contain the tasjk code. Example:

var gulp = require('gulp');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var minify = require('gulp-minify-css');

gulp.task('sass', function() {
    gulp.src('./src/**/*.scss')
        .pipe(sass())
        .pipe(concat('style.css'))
        .pipe(minify())
        .pipe(gulp.dest('./build'));
});

That's already an improvement: we have replaced our fat unreadable file with a clean file tree.

Extract the configuration

We still have a problem: if I want to reuse one of those tasks in another project, I will have to change its code, because the destination folder will not be ./build but ./dist, or any detail like that.

So, we create a config.js file in the ./gulp folder that will handle all the configuration values expected by our tasks, and the task files will just require() this config file.

The task will now look like that:

var gulp = require('gulp');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var minify = require('gulp-minify-css');

var config = require('../config').sass;

gulp.task('sass', function() {
    gulp.src(config.src)
        .pipe(sass())
        .pipe(concat(config.outputName))
        .pipe(minify())
        .pipe(gulp.dest(config.dest));
});

And the config.js file will be:

var dest = "./build";
var src = './src';
var demoSrc = './demos';

module.exports = {
  sass: {
    src: [
      src + "/**/*.scss"
    ],
    outputName: 'moondash.css',
    dest: dest
  },
  othertask: {
    ...
  },
  ...
};

And here we go! Our tasks are modular and generic, the configuration is managed in a single place. That's clean now.

Mon bureau

ABONNEZ-VOUS À LA NEWSLETTER !
Voir aussi
How to setup Angular Universal How to setup Angular Universal 29/06/2017

Step by step explanation. All the pitfalls to avoid.

Comment mettre en place Angular Universal Comment mettre en place Angular Universal 29/06/2017

Toutes les étapes détaillées et expliquées. Les pièges à éviter.

SEO : indexing a JavaScript application SEO : indexing a JavaScript application 29/06/2017

How to produce a server-side rendered version of your web application.

SEO : indexer une application Javascript SEO : indexer une application Javascript 29/06/2017

Comment utiliser le code de votre application pour un rendu server-side.

Découverte de React Native Découverte de React Native 18/04/2016

Présentation de React Native, quelles sont ses possibilités et peut-on l'utiliser en prod ?