L’utilitaire Gulp est un automatisateur de tâche (un task runner) concurent de Grunt basé sur NodeJS. Comme son homologue, il va vous permettre d’automatiser différentes tâches répétitives lors des étapes du développement.
Installation
Étant basé sur NodeJS, Gulp s’installe via npm
:
npm install -g gulp
Pour tester l’installation de Gulp :
gulp -v
Sans être root
Placez vous dans votre répertoire personnel, puis lancez l’installation de gulp en local avec la commande npm install gulp
. NPM aura créé un dossier node_modules avec un dossier gulp dedans.
Puis dans votre .bashrc, ajouter un alias :
alias gulp="~/node_modules/gulp/bin/gulp.js"
Puis testez avec la commande gulp -v
Gulpfile : Bonjour Gulp
Pour configurer les différentes tâches, on utilise un fichier gulpfile.js
que l’on place à la racine de son projet.
Commençons par créer une tâche hello.
// gulpfile.js
var gulp = require('gulp');
// Création d'un tache 'hello'
gulp.task('hello', function(){
console.log("Bonjour Gulp !");
});
Pour exécuter cette tache :
gulp hello
On obtient :
[16:10:45] Using gulpfile ~/Test/Gulp/gulpfile.js [16:10:45] Starting ‘hello’… Bonjour Gulp! [16:10:45] Finished ‘hello’ after 83 μs
Principes
De base, Gulp est fournit brut avec un nombre très limité de
fonctionnalités. La commande npm
vous permettra d’en ajouter pour
répondre à vous besoins.
Parmis les fonctionnalités de base on trouve :
- L’ouverture d’un flux de fichier (
gulp.src(GLOB)
) - L’envoi de ce flux dans un plugin de traitement (
pipe()
) - L’envoi d’un flux dans une destination (
gulp.dest()
)
Source : Glob
Le Glob est un ensemble (qui peut être vide) de fichier exprimé sour la forme d’un tableau d’emplacements. Ces emplacements peuvent utiliser des wildcard au format Node Globs (comparable à celle que l’on trouve dans les fichiers .gitignore
):
fichier.js // un fichier précis
*.js // Tous les fichiers JS directement dans l'emplacement
**/*.js // Tous les fichiers JS récursivement
!**/*.min.js // SAUF les fichiers .min.js
Pipe
La méthode pipe(FOO)
permet d’envoyer le flux de données dans un traitement, les traitements (plugins) étant chaînés, on peut faire intervenir plusieurs pipe()
à la suite :
// Gulpfile.js
var gulp = require('gulp');
// Principe du pipe
gulp.task('simple-demo', function(){
gulp.src('style/sass/*.scss')
.pipe(plugin1())
.pipe(plugin2())
.pipe(pluginX())
// ... etc
.pipe(gulp.dest('style/css/'));
});
Plus compliqué (factorisation des traitements) : Making reusable pipelines in a Gulp build.
Exemple : Compilation SASS
Petit exemple avec le plugins Gulp SASS qui permet de compiler le contenu des fichiers SASS en CSS.
npm install gulp-sass
Puis dans le Gulpfile.js
:
// Gulpfile.js
var gulp = require('gulp'),
sass = require('gulp-sass');
// ...
gulp.task('sass', function(){
console.log("Compilation SASS");
// On lit les fichiers .scss du dossier style/sass
gulp.src('style/sass/*.scss')
// On les envois dans le plugin SASS
.pipe(sass())
// Puis le résultat est envoyé dans le dossier style/css
.pipe(gulp.dest('style/css/'));
});
Pour tester créez un fichier toto.scss
dans le dossier style/sass
avec ce contenu :
$color: pink;
body {
background-color: $color;
}
Enfin, lancer la tache en tapant :
gulp sass
Dépendances
Une tâche peut avoir des dépendances, dans notre exemple, on peut dire que la compilation ne peut être faite qu’après avoir éxécuté la tache hello, cela je définit dans la déclaration de la tache :
// Gulpfile.js
// ...
gulp.task('sass', ['hello'], function(){
// etc...
});
Watch
Gulp sait surveiller les modifications sur les fichiers et lancer des tâches suite à ces changements avec la méthode gulp.watch(GLOB, TASKS])
:
// Gulpfile.js
// ...
gulp.task('sass:watch', function(){
gulp.watch('style/sass/*.scss', ['sass']);
});
On lance ensuite la surveillance avec la commande gulp sass:watch
. Dès qu’une modification interviens sur un fichier surveiller, Gulp lance la (ou les) tâches couplées.
Appel système
// gulfile.js
var gulp = require('gulp'),
exec = require('child_process').exec
;
gulp.task('ls', function(){
console.log("Liste des fichiers");
exec('ls -la', function(err, stdout, stderr){
if(err){
console.log('Erreur', stderr);
}
console.log(stdout);
});
});
Attention, cette éxécution est asynchrone :
// gulfile.js
var gulp = require('gulp'),
exec = require('child_process').exec
;
gulp.task('ls', function(){
console.log("Liste des fichiers");
exec('sleep 2; ls -la;', function(err, stdout, stderr){
if(err){
console.log('Erreur', stderr);
}
console.log(stdout);
});
});
//
gulp.task('demo', ['ls'], function(){
console.log("Je fais mon boulot");
});
Si l’on veut forcer la synchronisation :
// gulfile.js
var gulp = require('gulp'),
exec = require('child_process').exec
;
gulp.task('ls', function(cb){
console.log("Liste des fichiers");
exec('sleep 2; ls -la', function(err, stdout, stderr){
if(err){
console.log('Erreur', stderr);
return cb(err);
}
console.log(stdout);
cb();
});
});
gulp.task('demo', ['ls'], function(){
console.log("Je fais mon boulot");
});