Yassine Belouad

Grunt, Gulp, quel outil pour automatiser vos tâches front-end ? (3/3)

Grunt, Gulp, le match !

Comme nous en avions précédemment discuté ici et ici, Grunt et Gulp sont deux outils fantastiques, bâtis autour de la plateforme Node.js, qui nous permettent d’automatiser les tâches fastidieuses mais essentielles du développement front-web. Si la finalité de ces deux outils est la même, comment se distinguent-ils ?

La configuration

Gulp est un outil qui est tourné vers le code plutôt que vers la configuration. Les tâches Grunt sont configurées dans un objet de configuration alors que les tâches Gulp sont plutôt configurées en utilisant un style de syntaxe à la Node.js.
Le style de configuration de chaque plugin Grunt peut varier d’un plugin à un autre alors que les options de configuration des plugins sous Gulp sont bien plus standardisées.
Sachez aussi que l’on peut facilement se retrouver avec de très gros fichiers de configuration Grunt cela étant dû en partie à cause des configurations un peu trop over-kill pour des tâches qui restent simples.

L’exemple ci-dessous nous permet de constater la différence entre Grunt et Gulp pour automatiser la compilation de fichiers LESS:

Gruntfile.js

grunt.initConfig({
  less: {
      options: {
        paths: ["app/styles/css"]
      },
      files: {
        "build/styles/result.css": "app/styles/source.less"
      }
  },

  watch: {
    styles: {
      files: ['app/styles/{,*/}*.less'],
      tasks: ['less']
    }
  }
});

grunt.registerTask('default', ['less', 'watch']);

Gulpfile.js

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

gulp.task('default', function() {
  gulp.run('less');
  gulp.watch('app/styles/**/*.less', function() {
    gulp.run('less');
  });
});

Selon votre style, vous préférerez le code plutôt que la configuration ou inversement.
Personnellement, je trouve que le style de syntaxe de Gulp est plus lisible que celui de Grunt.

Les performances

J’ai pu constaté sur différents projets que Gulp était deux fois plus rapides que Grunt dans la majeure partie des cas.
Cela est du au fait que Gulp utilise le système de streams qui lui permet de monter les flux de données en mémoire, ce qui limite grandement les lectures/ecritures dans les fichiers.

Ce n’est pas le cas de Grunt, il n’utilise pas de streams mais va plutôt mulitplier les accès aux fichiers et avoir recours à des fichiers temporaires pour écrire les contenus d’une étape à une autre, ce qui peut être particulièrement coûteux en terme de performance suivant la taille du projet.

La communauté

Gulp est encore jeune et de ce fait il dispose d’une petite communauté et je trouve que la documentation est très souvent insuffisante.
Avec pratiquement 2 ans d’existence, Grunt se pose comme référence dans le domaine des task runners, il dispose d’une solide communauté et d’un peu moins de 3000 plugins (contre 650 pour Gulp).
Mais attention toutefois à Gulp qui pourrait s’imposer dans le futur car de plus en plus de developpeurs l’ont adopté pour les différentes raisons que nous avons pu voir.

Conclusion

La finalité de ces deux outils est la même : automatiser les tâches récurrentes pour nous faire gagner du temps !

Il faudra garder un oeil sur les évolutions futures de Grunt. Il se murmure que dans ses prochaines versions il pourrait prendre en charge le piping et les streams, ce qui réduirait considérablement son retard par rapport à Gulp en terme de performances. De ce fait, la configuration des plugins serait minime puisque nous pourrions nous passer totalement des fichiers temporaires.

Si vous devez faire un choix, il faut se demander quel style vous correspond le mieux. Est-ce que je prèfere un outil basé sur de la configuration ou sur du code ? À chaque style son outil, choisissez Grunt si vous êtes plus à l’aise avec de la configuration plutôt qu’avec du code, sinon choisissez Gulp.

Si au final vous avez du mal à faire un choix sachez que les deux cohabitent parfaitement !

grunt_logo gulp_logo
Grunt Gulp
3000 plugins 650 plugins
Configuration Code
Fichiers temporaires Streams
Grande communauté Communauté naissante
Rapide comme l’éclair
Documentations perfectible

Grunt, Gulp, quel outil pour automatiser vos tâches front-end ? (2/3)

Gulp

Tout comme Grunt, Gulp est un outil d’automatisation JS (javascript task runner) basé sur la plateforme NodeJS qui va nous permettre d’améliorer notre workflow et d’optimiser nos applications web. Qui dit automatisation dit plus de temps pour se concentrer sur d’autres choses plus importantes comme produire du code de qualité ! Grâce à cet outil, nous allons pouvoir automatiser des tâches telles que la compression d’images, les tests unitaires ou encore la minification.

Depuis sa sortie, Gulp a suscité un grand intérêt auprès de la communauté des developpeurs front-end du fait de la simplicité de sa mise en place et de sa configuration qui lui permette d’être très facilement lisible et maintenable.

Installation

Puisque Gulp est basé sur NodeJS, ce dernier doit être installé sur votre poste avant d’installer Gulp.

Vous pourrez installer NodeJS sur votre machine sans trop de difficulté en vous rendant ici.

Une fois NodeJS installé, vous pourrez installer facilement Gulp en utilisant npm (Node Packet Manager).
Il faut lancer la commande suivante :

$ npm install -g gulp

Cette commande aura pour effet d’aller récupérer Gulp depuis le registre npm et de l’installer globalement dans votre système.
Pour installer gulp uniquement au niveau de votre projet, il ne faut pas mettre l’option -g dans la ligne de commande.

Configuration

À ce niveau, Gulp est installé sur votre système et est prêt à être utiliser dans nos projets.

Tout comme nous l’avions vu dans notre précédent article, il faut avoir mis à la racine de notre projet un fichier package.json dans lequel on va renseigner toutes nos dépendances de développement .

À présent, il faut installer Gulp en tant que dépendance du projet, ce qui permettra aux autres membres de la team, de partir du bon pied lorsqu’ils feront un « npm install » !
La commande à exécuter est la suivante :

$ npm install --save-dev gulp gulp-util

L’option « –save-dev » dans la ligne de commandes va permettre de mettre à jour les dépendances de développement dans le fichier package.json en ajoutant une référence à gulp et gulp util. Si vous omettez cette option, le fichier package.json ne sera pas mis à jour avec la dépendance en question et vous serez obligé de la rajouter manuellement.

Maintenant nous allons pouvoir installer tous les plugins qu’il nous faut pour automatiser l’éxécution des tâches !
Étant donné que les plugins de Gulp sont des modules de node, nous allons utiliser npm pour les installer.

$ npm install --save-dev gulp-less gulp-watch

La ligne de commande ci-dessus va installer le plugin pour compiler nos fichier LESS et va nous permettre de surveiller les fichiers que l’on modifie dans le but d’y associer un traitement particulier. De plus, une entrée sera automatiquement ajoutée au niveau de devDependencies dans le fichier package.json

{
  "devDependencies": {
    "gulp": "^3.7.0"
    "gulp-less": "^1.2.3",
    "gulp-watch": "^0.6.5"
  }
}

À l’heure actuelle, Gulp dispose d’un peu plus de 600 plugins. Certains feront sûrement votre bonheur, tels que :

Gulpfile.js

De la même façon que Grunt, toute la configuration de Gulp réside dans le fichier gulpfile.js situé à la racine du projet.
Nous allons donc commencer par dire à Gulp de quels plugins nous avons besoin pour executer les tâches :

var gulp  = require('gulp'),
    util  = require('gulp-util'),
    less  = require('gulp-less'),
    watch = require('gulp-watch');

Par la suite nous allons specifier quelles tâches nous allons exécuter. Dans notre cas nous allons faire 2 choses :

  • Une tâche « less » qui va compiler les fichiers LESS et placer le résultat à un endroit donné
  • Une tâche « default » qui va exécuter la tâche « less » puis surveiller toutes modifications des fichiers de type .less, si une modification survient la tâche « less » sera rejouée

Pour définir une tâche Gulp, on utilise la méthode task() suivante :

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

La méthode task() prend en entrée un nom sémantique « less » qui définit le nom de la tâche et ensuite une fonction anonyme qui contient le traitement en question.

Nous allons décomposer cette méthode ligne par ligne :

gulp.src('app/styles/**/*.less')

La méthode src() va nous permettre de spécifier le chemin vers les fichiers avec l’extension LESS et va les transformer en un stream qui sera diffusé aux plugins pour effectuer les traitements.

.pipe(less())

La méthode pipe() va utiliser le stream provenant de src() et le passer aux plugins référencés. Ici en l’occurrence, le plugin less recevra le stream de fichier pour les traiter.

.pipe(gulp.dest('build/styles'))

La méthode dest() va nous permettre de spécifier l’emplacement où l’on souhaite écrire le résultat du traitement. Les fichiers LESS compilés seront donc placés dans le dossier styles du build.

Pour exécuter cette tâche, il suffira de se placer à la racine du projet et de lancer la commande :

$ gulp less

Si nous ne spécifions pas de tâche dans la ligne de commande, la tâche « default » sera lancée.

gulp.task('default', function() {
  gulp.run('less');
  gulp.watch('app/styles/**/*.less', function() {
    gulp.run('less');
  });
});

La tâche « default » ci-dessus a pour but de lancer la tâche « less » (compilation de LESS pour avoir en sortie une feuille de style CSS) puis surveiller toutes modifications des fichiers LESS. Si une modification survient, la tâche « less » sera re-éxecutée. De cette façon, on n’a plus à se soucier de compiler les fichiers LESS à chaque fois qu’on les modifie !

Là est toute la puissance de Gulp, une syntaxe très séduisante, claire et facilement lisible et un gain de performance grâce à un système de stream qui évite d’écrire dans un dossier temporaire.
Il n’y a pas autant de plugins disponibles pour Gulp que pour Grunt, c’est un fait, mais la communauté n’en est pas moins active et grandissante, il ne serait pas étonnant que Gulp s’impose comme le prochain standard de l’automatisation JS des tâches, mais d’ici là quel outil choisir ?

La suite, dans notre prochain article consacré au match Grunt / Gulp.

Grunt, Gulp, quel outil pour automatiser vos tâches front-end ? (1/3)

Introduction

En tant que développeurs front-end, nous sommes amenés à réaliser nos projets web en ayant à l’esprit un certain nombre de bonnes pratiques telles que :

  •  La compression des feuilles de styles CSS et la minification des scripts Javascript pour qu’ils soient le plus léger possible en production
  •  L’optimisation des images en réduisant leur poids sans altérer leur qualité
  • Auto-générer des sprites d’images
  •  S’assurer que les scripts Javascript ne contiennent pas d’erreurs de syntaxe
  •  Retirer les alertes/console log en production
  •  etc …

Si  nous voulons avoir une webapp optimisée, nous devons réaliser absolument toutes ces tâches. Des tâches répétitives, quelque soit le projet, et fastidieuses car elles ne se limitent pas seulement aux 4 citées en exemple plus haut.

Automatiser ce genre de tâches est donc devenu quasi-vital dans le but, d’une part, de gagner un temps considérable à ne plus tout faire manuellement et d’autre part, d’être sûr de l’optimisation du code livré en production (minification, obfusquation etc…). Tout cela en moins de temps qu’il ne faut pour préparer votre café préféré !

Si votre quotidien est synonyme de tâches à répétition et que vous avez cherché à un moment donné à les automatiser, vous avez forcément entendu parler de Grunt ou encore de Gulp qui s’imposent comme des références en la matière d’outils d’automatisation Javascript.

Outils Javascript d’automatisation

Les outils js d’automatisation des tâches s’appuient sur Node.js, une plateforme software écrite en Javascript orientée serveur qui fut créé il y a quelques années. Elle utilise le moteur V8 de Google Chrome qui va analyser/exécuter ultra-rapidement du code js et qui fonctionne suivant un modèle non bloquant (programmation asynchrone). Node.js a ouvert la voie, entre autres, à de nouveaux outils d’automatisation tel que Grunt et c’est une vraie chance pour nous autres développeurs front-end que d’avoir à notre disposition ce genre d’outils pour :

  • déployer rapidement un serveur de développement
  • rafraîchir sa page lorsque l’on modifie un fichier
  • compiler les templates
  • bouchonner les données renvoyées par un web service,
  • supprimer tous les commentaires dans le code
  • minifier les feuilles de styles
  • obfusquer les scripts JS
  • etc…

Il n’y a pratiquement pas de limites à ce que l’on peut faire !

Grunt

Grunt est un outil basé sur des tâches exécutées en ligne de commande qui va grandement accélérer nos workflows classiques de développement en réduisant notre effort lors de la préparation des sources pour les mises en production.

Dans la plupart des cas, sachez que lorsque vous effectuez manuellement une tâche, son équivalent automatique existe sous forme de plugin Grunt comme par exemple la minification et la concaténation de scripts.

Grunt est également capable de gérer des tâches qui ne sont pas forcément liées à Javascript comme la compilation CSS depuis SASS ou LESS.

Enfin sachez qu’il dispose d’une incroyable communauté de développeurs et d’une énorme base de plugins mise à jour très régulièrement. Vous n’êtes donc pas seul à vous lancer dans l’aventure !

Installation

Comme évoqué précédemment, Grunt est basé sur Node.js. De ce fait il doit être installé sur votre machine pour que Grunt puisse fonctionner. L’installation de Grunt se fait via le npm (Node Packet Manager), il suffit d’ouvrir votre invité de commandes et d’exécuter cette instruction pour installer Grunt :

$ npm install -g grunt-cli

Package.json

Package.json est un fichier à créer à la racine de votre projet, il va vous permettre de tracker et d’installer toutes les dépendances liées au développement. Ainsi, tous les membres de votre team disposeront des toutes dernières versions des dépendances. Ce qui en fin de compte permet de garder un environnement de développement constamment synchronisé.

{
  "name": "Example",
  "description": "Un package de test",
  "version": "0.0.1",
  "private": "true",
  "author": "Prenom Nom ",
  "devDependencies": {
    "grunt": "^0.4.5"
  }
}
$ npm install

La commande ci-dessus va dire à npm d’aller récupérer toutes les dépendances qui sont listées dans devDependencies puis de les installer dans le dossier node_modules.
 Dans cet exemple, si la commande réussie, Grunt version 0.4.5 ou supérieure sera installée localement dans le projet.

Gruntfile.js

Comme le fichier package.json, le fichier Gruntfile.js doit être placé à la racine du projet. Il contient toute la configuration des tâches automatiques à exécuter lorsque l’on exécute grunt depuis l’invité de commandes.

module.exports = function(grunt) {

    /* 1. Toute la configuration. 
     * L'ordre n'a pas d'importance.
     */
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

   /* 2. La configuration du plugin cssmin pour la minification de css.
    * Une sous tâche build qui va minifier index.css dans style.css
    */
        cssmin: {
                   build: {
                             src: 'app/css/index.css',
                             dest:'build/css/style.css'
                          } 
                }
    });
    
    /* Chargement du plugin
     * 3. On dit à Grunt que l'on compte utiliser le plugin grunt-contrib-cssmin.
     */
    grunt.loadNpmTasks('grunt-contrib-cssmin');

    /* Déclaration des tâches
     * On dit à grunt ce qu'il faut faire lorsque l'on execute "grunt" dans l'invité de commandes.
     */
    grunt.registerTask('default', ['cssmin']);

};

À partir de maintenant il n’y a plus qu’à exécuter la ligne de commande suivante dans notre invité de commandes pour minifier notre feuille de style :

$ grunt

Et voila ! Notre feuille de style a été minifiée en une fraction de seconde. grunt-command-line
Imaginez maintenant toutes les tâches que l’on peut automatiser exactement avec la même simplicité! 
Pour vous en rendre compte, je vous invite à jeter un œil à l’impressionnant listing de plugins disponible pour Grunt. Pas moins de 3000 plugins pour faciliter notre quotidien.

Grunt est donc un outil très simple d’usage, qui consiste en un fichier de configuration js facilement lisible, dans lequel on paramètre les plugins que l’on souhaite utiliser pour automatiser nos tâches.
Sachez qu’il n’est pas le seul sur le marché… 
La suite, dans la deuxième partie de ce dossier qui sera consacrée au petit nouveau, Gulp !