Gulp

Je découvrais il y a peu Grunt, et au fil de son utilisation, j'avais un peu du mal à m'y faire. J'ai pas mal galéré à faire cotoyer un watch avec un less, un jshint et un nodeunit de concert par exemple. Et même si Yeoman m'a beaucoup aidé, je fut bien content quand j'ai essayé la nouvelle recrue : Gulp.

Gulp fait la même chose que Grunt, mais différement. Grunt fonctionne à base de configuration. Vous êtes donc cantonné aux fonctionnalités que proposent les différents plugins.
Gulp, lui, est un classique script javascript avec une API spécifique. Vous préparez vos tâches en écrivant du javascript, ce qui vous laisse du coup toute la latitude possible pour faire ce que vous voulez.

Gulp fonctionne comme un gestionnaire de flux. On commence par déclarer une tâche et on lit un groupe de fichiers avec la méthode src(). Cette méthode retourne un objet de flux proposant la méthode pipe() permettant de chainer les traitements. Ainsi, si nous voulions lire les fichiers contenus dans le dossier css puis les faire compiler par less, puis enregistrer le résultat dans le dossier build/css, nous procéderions ainsi :

// fichier gulpfile.js
var gulp = require('gulp'),
    less = require('gulp-less');

gulp.task('css', function() {
    gulp.src('css/**/*.css')
        .pipe(less())
        .pipe(gulp.dest('./build/css'));
});

Lorsque je lancerais la commande :

$ gulp css

dans mon terminal, alors gulp créera un stream de données basé sur la liste de tous les fichiers correspondant au chemin donné, en l'occurence, tous les fichiers finissant par .css localisé dans le dossier css ou l'un des sous dossier. Ensuite, chacun des fichier lu est envoyé via pipe au plugin less. Celui-ci retournera le même objet mais modifié par ses soins. Il passe ensuite par le plugin gulp.dest dont le but est d'écrire le contenu de l'objet dans le système de fichier.

Là où, je pense, la différence en terme de compléxité va être flagrante avec Grunt, c'est lors de l'utilisation de watch. Ici, c'est très simple. Une fois vos tâches spécifiées, vous pouvez les passer à gulp.watch puis rassembler toutes ces tâches watch à une tâche globale. Exemple :

// fichier gulpfile.js
var gulp = require('gulp'),
    less = require('gulp-less'),
    uglify = require('gulp-uglify'),
    css_path = './css/**/*.css',
    js_path = './js/**/*.js';

gulp.task('css', function()
{
    gulp.src(css_path)
        .pipe(less())
        .pipe(gulp.dest('./build/css'));
});

gulp.task('js', function()
{
    gulp.src(js_path)
        .pipe(uglify())
        .pipe(gulp.dest('./build/js'));
});

gulp.task('watch-css', function()
{
    gulp.watch(css_path, ['css']);
});

gulp.task('watch-js', function()
{
    gulp.watch(js_path, ['js']);
});

gulp.task('default', ['js', 'css', 'watch-js', 'watch-css']);

Vous pouvez alors appeller gulp sans argument (la tâche default) :

$ gulp

Et vos fichiers js et css seront traités immédiatement, puis dès que des modifications y seront apportées.

Il existe déjà tout un tas de plugins prêt à être pipés ! Amusez vous bien !

Quand je vois tout ce qu'on peut faire avec Gulp, je me rend compte que j'aurais pu écrire mon framework yoshioka (la base du backoffice d'Overblog Kiwi) avec 10 fois moins de lignes de code. Mais c'était en 2011 et tout cela n'existait pas encore…

Hadrien

Hi, I'm a french Javascript Lead Developer, Web Architect from Toulouse, France. I've worked for 12 years for many projects with YUI, AngularJS, Aurelia.io and now React and React native.

Toulouse, France https://hadrien.eu