Création d’automatismes avec Grunt.js

Le travail du développeur ou de l’intégrateur Web peut se révéler redondant lorsque nous sommes amenés à réitérer des opérations similaires régulièrement telles que :

  • le redimensionnement et compression de visuels
  • la compression des ressources Javascript et CSS (Feuilles de style)
  • les tests unitaires ou de régression, pour vérifier que notre travail continue à remplir ses promesses
  • le renommage de fichier
  • la génération de typographies depuis des documents SVG

La liste ne se limite bien évidemment pas à ces quelques points, mais ceux-ci peuvent s’avérer chronophages et/ou répétitifs. Pour automatiser ces tâches, rien de tel que Grunt qui est un Task Runner (comprenez : « Automate » en bon français). Au travers de cet assistant, vous pourrez définir des actions qui pourront être lancées sur :

Mise en place de Grunt (sous Mac)

Avant d’installer Grunt, il y a quelques pré-requis, à savoir l’installation de Node.js et de NPM. Si vous voulez suivre la procédure officielle … cliquez-ici.

Installation de Node.js & NPM

Node.js : Le javascript côté serveur

Dans le cas présent, Node.js vous permettra de programmer vos tâches & automatismes en Javascript.

NPM : Gestionnaire de dépendance de Node

NPM quant à lui vous permettra d’installer sur votre ordinateur des outils nécessitant Node.js, en l’occurrence il nous permettra d’installer Grunt.js et tous les modules que vous serez amenés à utiliser.

Installez Node.js en allant sur le site officiel, puis en cliquant sur Install. Puis suivez les instructions dans la fenêtre d’installation

Une fois ces installations effectuées, vous allez pouvoir installer Grunt.js

Installation de Grunt.js

Soyons, clair, la suite des évènements va se passer dans le terminal de Mac OS. N’ayez pas peur de cette interface, bien que son fonctionnement puisse vous sembler obscur, elle est cependant nécessaire pour pouvoir utiliser Grunt.js.

Ouvrez le terminal de Mac Os, puis saisissez (ou copiez collez) le code suivant :

sudo npm install -g grunt-cli

Ce code va vous permettre d’installer Grunt en utilisant le gestionnaire de dépendances NPM

Une fois que votre terminal est redevenu inerte, vous pouvez faire un test pour voir si Grunt est bien installé. Nous allons demander à Grunt, quel est son numéro de version. Si la commande nous retourne quelque chose comme grunt-cli v0.1.13, c’est que tout va bien.

grunt --version

Bravo, vous venez d’installer les fondamentaux de Grunt.js. Grunt est désormais accessible sur votre ordinateur.

Création d’un projet

À partir de maintenant nous allons essayer Grunt.js. Pour cela nous allons définir un projet.

Si vous avez votre terminal encore ouvert, fermez-le. Ouvrez-en un nouveau pour que l’on parte sur les mêmes bases. Par défaut le terminal vous positionne dans votre dossier personnel. On peut le repèrer au ~ dans le terminal. De là, vous pouvez aller sur votre bureau en tapant le code suivant :

cd Desktop

Au début de votre dernière ligne du terminal, vous devez avoir Desktop de lisible.

Nous allons créer un nouveau projet/dossier dans lequel nous allons travailler :

mkdir Project-Name
cd Project-Name

Au début de votre dernière ligne du terminal, vous devez avoir Project-Name de lisible, cela signifie que vous êtes dans le répertoire Project-Name, donc tout va pour le mieux.

Astuce : pour aller dans un répertoire sans avoir à saisir tout le nom du répertoire question, saisissez les premières lettres, puis appuyez sur Tabulation. Cela activera une auto-saisie du ou des répertoires commençant par ces lettres.

package.json

Nous allons créer un fichier qui va permettre de définir tous les modules que votre projet va utiliser (à commencer par le module Grunt, puisque nous sommes là pour ça)

touch package.json

Si depuis le Finder vous allez jeter un œil sur votre bureau, vous verrez un dossier Project-Name qui contiendra le fichier que nous venons de créer.

Dans le fichier package.json, copiez-collez-y le contenu suivant :

{
  "name": "Project-Name",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.5"
  }
}

Vous venez de définir que votre projet se nommait Project-Name, et qu’il allait avoir besoin de Grunt (le numéro à côté est le numéro de la version de grunt.js). Vous allez pouvoir installer Grunt dans votre projet:

npm install NOM-DU-MODULE

Vous devez absolument vous familiariser avec cette commande, puisqu’à chaque module vous allez devoir la lancer. À cette étape, vous devriez avoir un dossier node_modules dans le dossier merge-javascript. Dans ce dossier node_modules, vous pourriez y voir un dossier grunt.

Gruntfile.js

touch Gruntfile.js

Ce second fichier est très important : Gruntfile.js est le fichier dans lequel vous allez écrire vos instructions pour créer vos automatismes. Comme précisé préalablement, ce fichier sera écrit en Javascript. Dans un premier temps laissez le vide.

Pour aller plus loin

Les meilleurs plugins Grunt.

Dans le cadre de nos derniers projets nous avons eu besoin de tester de nombreux modules grunt. Voici une liste de ceux que l’on utilise et que l’on vous recommande :

Menu et listes des automatismes disponibles dans notre Grunt

Grunt-available-tasks

Grunt-available-tasks Un outil qui permet de lister un ensemble de tâches que vous aurez définies. Cela permet de générer un menu qui vous aidera à vous souvenir du nom de vos automatismes, mais aussi à vos collègues. Un petit descriptif peut accompagner les actions, ce qui est très utile lorsque vous travaillez à plusieurs, ou que vous revenez sur votre projet au bout d’un certain temps.

Assemblage de fichiers textes

Grunt-contrib-concat

Grunt-contrib-concat probablement le plus simple et le plus utile des modules trouvés. Il permet tout bêtement de fusionner des fichiers ensembles. Vous définissez une liste de fichiers, ou un (voire des) répertoire, et lors de l’exécution, les fichiers sont fusionnés en un seul, dont vous aurez préalablement défini le nom. Lire la documentation de Grunt-contrib-concat

Répartition des tâches sur des processus différents

Grunt-concurrent est un peu pointu, mais vous permettra de réduire vos temps d’exécution de vos tâches. Grunt-concurrent permet de dispatcher vos tâches sur les différents cœurs de votre processeur. Alors que de base toutes les tâches sont exécutées les unes après les autres, là vous profitez pleinement de votre/vos processeurs. Je vous conseille ce module si vous avez des tâches longues et non dépendantes les unes des autres. Nous nous en servons pour la génération de visuels : nous avons une application qui doit générer 3000 visuels dans 6 tailles différentes (soit 18 000 fichiers), puis optimiser leur taille., cela fait donc 36 000 opérations, l’utilisation de Grunt-concurrent, nous a permis de diviser par 3 les temps d’exécution. Lire la documentation de Grunt-concurrent

Téléchargement de liens

Grunt-curl

Grunt-curl équivaut à la commande WGET, vous donnez une url et vous pouvez définir un nom de fichier dans lequel enregistrer les données. C’est pratique et rapide pour statifier des pages générées en PHP ou dans un autre langage dynamique. Lire la documentation de Grunt-curl

Réduction et optimisation du code HTML

Grunt-contrib-htmlmin

Grunt-contrib-htmlmin permet simplement de minifier/compresser le contenu d’un fichier HTML. Pas besoin d’en dire plus … ça fait seulement ça …

Énumération des images d’un dossier et récupération de leurs caractéristiques

Grunt-image-size va générer un fichier JSON contenant toutes les informations de dimensions d’images listées ou présentes dans un répertoire. Voici un petit exemple de ce que vous pouvez obtenir (nom de fichier, dimensions, )

[
    {
        name : 'path/to/file'
        width : 100,
        height : 100
    },
    ...
]   

On pourrait reprocher de ne pas avoir de petites options complémentaires telles que poids, format, compression, données exif … Nous utilisons ce plugin pour récupérer les dimensions afin de connaitre dans nos application les dimensions des images avant leur chargement. Cela permet d’afficher à l’internaute les encombrements justes avant même de charger les images.

Optimisation des images

Grunt-contrib-imagemin est tout simplement l’outil indispensable pour la compression des images. Ce module Grunt exploite les outils les plus fréquents dont la fiabilité n’est plus à faire :

  • gifsicle — Compresse les images GIF
  • jpegtran — Compresse les images JPEG
  • optipng — Compresse les images PNG
  • pngquant — Compresse les images PNG
  • svgo — Compress les images SVG

Pour chaque outil de compression, il est possible de définir leur options pour affiner leur action. Si vous êtes un adepte de TinyPng, il y a un module pour vous : Grunt-tinypng.

Nettoyage du code Javascript

Grunt-jsbeautifier n’est pas indispensable, mais si vous voulez standardisez le formatage de vos fichiers Javascript, il s’avèrera précieux.

Optimisation et réduction des fichiers JSON

Grunt-jsonmin

Grunt-jsonmin est très simple et peut être facilement remplacer par une alternative PHP ou autre, mais comme nous nous en servons régulièrement, il me semblait important de le lister ici. Grunt-jsonmin comme son nom l’indique, permet de réduire au minimum la taille d’un ou de plusieurs fichiers JSON, sans le déteriorer bien évidemment. Lire la documentation de Grunt-jsonmin.

Rechercher/remplacer sur tout un ensemble de fichiers

Grunt-replace à un rôle très simple, mais particulièrement puissant et pratique. Il s’agit d’un rechercher/remplacer comme on en connait tous, mais sur une liste de fichiers préalablement définie. Ce module n’est pas forcément destructif, vous pouvez enregistrer les données transformées dans un autre fichier dont vous aurez défini le nom.

Vous vous doutez que je ne serais pas émoustillé par ce module s’il s’agissait d’un banal rechercher/remplacer de chaînes de caractères. Cet outil permet d’utiliser des expressions régulières, modifier des valeurs ou des clefs d’un fichier JSON. Il est aussi possible de remplacer une chaîne particulière par une valeur dynamique (une date par exemple). Lire la documentation de Grunt-replace.

Génération automatique de miniatures et de vignettes

Grunt-responsive-images permet de créer des miniatures de visuels. C’est pratique pour éviter la génération dynamique de ces dernières. Ce module utilise un des deux outils suivants :

Il est possible de définir les images réduites de plusieurs manières, et précisant la hauteur, la largeur, ou encore plus simplement un pourcentage de réduction. De nombreuses fonctions supplémentaires sont aussi fournies, principalement dans la nomination des images générées. D’autres modules Grunt font un travail équivalent, mais j’ai été séduit par la simplicité de celui-ci.

Compilation des fichiers SASS en CSS

Grunt-contrib-sass

Grunt-contrib-sass est très pratique dans la compilation de vos fichiers SASS en fichier CSS. Il existe un module équivalent si vous préférez travailler en LESS (Grunt-contrib-less). Il faut avouer que rien n’est plus pénible de coder qu’en CSS natif : les préprocesseurs CSS apportent tellement (fonctions, variables …).

Compression du code Javascript

Grunt-contrib-uglify

Grunt-contrib-uglify est l’un des modules les plus utilisés : là ou actuellement il existe peu de solutions dynamiques en PHP dans la compression des fichiers Javascript, ce module fait le travail parfaitement. Petit détail très pratique, il est possible de définir des noms de variables que vous ne souhaiteriez ne pas « compresser ». Lire la documentation de Grunt-contrib-uglify.

Exécution de tâches sur la modification d’un fichier

Grunt-watch est clairement incontournable. Ce module vous permet d’exécuter les tâches de votre choix lorsque vous modifiez un fichier d’une liste prédéfinie. Par exemple lorsque vous enregistrez un fichier Javascript, vous pouvez le compresser immédiatement. Vraiment très pratique.

Erwan Sabourin