Je me suis récemment penché sur ma méthode de travail et les moyens qui pouvaient être mis en oeuvre pour l'améliorer. Au cours de mes recherches j'ai pu découvrir cet outil qu'est Grunt.js.

Peu convaincu par son utilité au premier abord je ne peux plus m'en passer tant il a facilité la maintenance de mes projets et a accéléré mon travail. Comment ? C'est ce que je vous propose de découvrir.

Grunt.js, présentation

 

Grunt est un task runner (exécuteur de tâches) en ligne de commande écrit en javascript. Son rôle est d'automatiser toutes les tâches redondantes que nous sommes amenés à effectuer au quotidien (minification, vérifications diverses…). Il permet de réduire les risques d'erreurs qui sont inévitables lorsque nous effectuons manuellement des actions répétitives.

Grunt dispose d'une communauté active et bénéficie du développement de très nombreux plugins couvrant un large panel d'actions (linting,assistance dans le versionnage…).

Gagnez du temps dans vos créations graphiques !

+ 1,6 millions de ressources (photos, mockups, themes Wordpress etc.) premium à votre disposition pour livrer plus rapidement.

Est-ce vraiment nécessaire ?

Lors de la mise en ligne de projets, il est important d'optimiser au maximum vos fichiers afin de réduire le temps de chargement de vos applications / sites web. En ce qui concerne le CSS et le javascript, vous les concaténez en un seul fichier puis les compressez en utilisant des outils tels que CSS minifier ou JsCompress.

Prenons un exemple concret qui implique ce genre d'action. Vous regardez fièrement le nouveau site que vous venez de mettre en production et là c'est le drame, une page est cassée. Vous modifiez votre css, le testez, le minifiez et le remettez en ligne. Pas de chance, une autre page rencontre un problème similaire… vous êtes donc obligé de recommencer la manoeuvre.

Bien que légèrement exagérée, cette situation montre bien que toutes ces petites modifications très courtes prises individuellement s'avèrent être fastidieuses et chronophages lorsqu'elles sont enchainées.

C'est dans un cas comme celui-ci que Grunt excelle. Une fois votre modification enregistrée, il aura déjà effectué tout seul la concaténation et la compression de votre code. Et ce n'est qu'un exemple, on pourrait imaginer d'autres tâches qui auraient été lancées telles que la compilation via SASS.

Comment cela fonctionne ?

Son principe de fonctionnement est assez simple et repose sur deux fichiers qui viennent s'ajouter à votre arborescence : package.json et Gruntfile.js.

Certains sont peut être familiers du premier. Grunt utilise NPM le gestionnaire de package de Node.js. C'est grâce à ce fichier que les dépendances (modules) nécessaires à vos tâches seront installées dans votre environnement de travail .

Le second fichier sert à la configuration des tâches, à gérer leur ordre d'exécution et à charger les modules nécessaires à leur bon déroulement. 

Lorsque ces fichiers sont correctement paramétrés, il ne reste plus qu'à exécuter une commande dans le terminal pour laisser la magie opérer.

Mise en pratique

Pré-requis

Comme abordé ci-dessus, Grunt utilise NPM le gestionnaire de packages de Node.js. Vérifiez donc que celui-ci est bien disponible.

Installation

Pour installer grunt sur votre machine (qui va vous permettre d'accéder à la commande grunt) ouvrez un terminal et tapez ceci :

npm install -g grunt-cli

Voilà, c'est tout. Vous pouvez désormais utiliser grunt dans vos projets !

Exemple concret

Voyons à présent un petit exemple de l'utilisation de Grunt. Dans ce cas, nous allons nous contenter de lui demander de nous minifier le fichier exemple.js à chaque fois que nous le modifierons puis de nous transférer le résultat dans exemple.min.js. Nous conservons donc notre fichier de travail en parallèle.

Création de package.json

Rendez-vous dans votre dossier de travail, créez le fichier package.json puis éditez le en ajoutant les lignes suivantes :

{
  "name": "MonProjet",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.2",
    "grunt-contrib-uglify": "~0.2.2"
  }
}

Les deux premières informations parlent d'elles-mêmes, il s'agit du nom et de la version de votre projet. devDependencies va indiquer à NPM quels sont les modules qu'il devra télécharger. Dans notre cas, il devra récupérer grunt ainsi que uglify.

Dans un terminal, rendez vous dans votre dossier de travail puis lancez la commande suivante :

npm install

Une fois les opérations terminées, vous devriez avoir un dossier nommé node_modules

Note: si vous utilisez un gestionnaire de version tel que git, il est conseillé de ne pas inclure ce dossier. Les personnes qui cloneront votre dépôt n'auront qu'à lancer la même commande pour récupérer les dépendances (via package.json qui lui aura été inclus).

Création de Gruntfile.js

Dans votre dossier de travail, créez Gruntfile.js puis ajoutez les lignes suivantes :

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
      compress: {
        files : {
          "exemple.min.js" : ["exemple.js"]         }
      }
    }
  });
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.registerTask('goUgly', ['uglify:compress']);
};

Il y a trois grandes parties dans ces lignes.

La première, le initConfig qui permet de définir des tâches pour chaque module que vous souhaitez utiliser. Dans notre cas, nous définissons pour le module uglify une tâche nommée compress. Cette dernière va s'occuper du fichier exemple.js et le compresser dans exemple.min.js. 
Dans notre exemple nous donnons le nom exact du fichier source mais il est tout à fait possible d'appliquer une règle plus globale. Par exemple, js/*.js prendra en compte tous les fichiers d'extension .js dans le dossier js.

Deuxième partie, le chargement des modules précédemment récupérés par npm. Dans notre cas, nous demandons à Grunt de charger la dépendance grunt-contrib-uglify.

Enfin, nous créons une tâche goUgly qui éxécutera compress pour le module uglify.

Lancement !

Maintenant que nous avons mis en place notre tâche nous allons l'éxécuter. Pour cela, retournez dans votre terminal en vous plaçant toujours dans votre dossier de travail puis tapez la commande suivante :

grunt goUgly

Si tout s'est bien déroulé, vous devriez avoir une confirmation de la création de exemple.min.js.

Note: Nous avons intitulé notre tâche goUgly. Ce n'est pas indispensable si vous n'en avez qu'une seule. Dans ce cas, nommez la default et il vous suffira juste de taper :

grunt

Automatisation

A présent, faisons en sorte que cette tâche s'effectue toute seule dès qu'une modification sera apportée à notre exemple.js.

Pour cela, nous allons utiliser le module watch.

Installation du module

Dans votre terminal, tapez la commande suivante :

npm install grunt-contrib-watch --save-dev

Vous l'aurez compris, npm va télécharger le module et le ranger dans node_modules. Le paramètre –save-dev va quant à lui ajouter automatiquement une ligne dans package.json :

"grunt-contrib-watch": "~0.5.3"

Si vous ne tapez pas ce paramètre il vous faudra l'ajouter manuellement.

Création de la tâche

A présent, retournez dans Grunt.js et ajoutez ces lignes dans le initConfig :

watch: {
      files: ["exemple.js"],
      tasks: ['goUgly']  }

Files indique les fichiers à "écouter" et tasks, les tâches à effectuer lors d'un changement de ceux-ci.

Ajoutons le chargement du module watch :

grunt.loadNpmTasks('grunt-contrib-watch');

Et à présent, dans le terminal, tapez la commande :

grunt watch

Un message devrez vous indiquer que le script est en attente. Faites un test, modifiez exemple.js et sauvegardez. Le module watch a éxécuté goUgly et a généré votre fichier exemple.min.js  sans intervention de votre part !

Pour finir…

Durant cet article, je n'ai gratté que la surface des possibilités offertes par cet outil. Je n'ai bien évidemment pas connaissance de la totalité des plugins qui existent et il ne tient qu'à vous de les découvrir en fonctions de vos besoins.

Pour ma part, j'espère vous avoir fait découvrir de nouvelles choses et que vous prendrez autant de plaisir que moi à expérimenter les vastes possibilités de cet outil !