Tutoriel pour apprendre à utiliser l'outil JavaScript Grunt - Présentation de l'API

Nourdine FALOLA (Soat)

Dans le précédent tutoriel, je vous présentais Grunt dans son ensemble, ses liens avec la plateforme Node.js, son paramétrage et comment s'articule un projet web avec Grunt.

Avant d'aller plus loin et d'entrer dans le cœur du sujet - la création, la configuration et l'exécution des tâches Grunt -, faisons un tour d'horizon de l'API Grunt.

Commentez

- Titre : Tutoriel pour apprendre à utiliser l'outil JavaScript Grunt - Présentation de l'API

- Auteur : Nourdine FALOLA (Soat)

- Parution : 3 février 2017

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2016 Nourdine FALOLA. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Gruntfile.js : piqûre de rappel

- II. L'API Grunt

- III. grunt.config

- III-A. Initialiser les données

- III-A-1. grunt.config.init

- III-B. Requérir une donnée

- III-B-1. grunt.config.requires

- III-C. Accéder aux données : accesseurs

- III-C-1. grunt.config.getRaw

- III-C-2. grunt.config.process

- III-C-3. grunt.config.get

- III-C-4. grunt.config.set

- III-C-5. grunt.config

- III-C-6. grunt.config.escape

- III-C-7. grunt.config.merge

- IV. grunt.task

- IV-A. Créer des tâches

- IV-A-1. grunt.task.registerTask

- IV-A-2. grunt.task.registerMultiTask

- IV-A-3. grunt.task.requires

- IV-A-4. grunt.task.exists

- IV-A-5. grunt.task.renameTask

- IV-B. Charger des tâches externes

- IV-B-1. grunt.task.loadTasks

- IV-B-2. grunt.task.loadNpmTasks

- IV-C. Mettre les tâches en file d'attente

- IV-C-1. grunt.task.run

- IV-C-2. grunt.task.clearQueue

- IV-C-3. grunt.task.normalizeMultiTaskFiles

- V. grunt.file

- V-A. Lecture et écriture

- V-A-1. grunt.file.read / grunt.file.readJSON / grunt.file.readYAML

- V-A-2. grunt.file.write

- V-A-3. grunt.file.copy

- V-A-4. grunt.file.delete

- V-B. Répertoires

- V-B-1. grunt.file.mkdir

- V-C. Types de fichiers

- V-C-1. grunt.file.exists / grunt.file.isLink / grunt.file.isDir / grunt.file.isFile

- V-D. Chemins

- V-D-1. grunt.file.isPathAbsolute

- V-D-2. grunt.file.arePathsEquivalent

- V-D-3. grunt.file.doesPathContain

- V-D-4. grunt.file.setBase

- VI. grunt.fail

- VI-A. grunt.fail.warn

- VI-B. grunt.fail.fatal

- VII. Dans les tâches

- VII-A. Dans toutes les tâches

- VII-A-1. this.async

- VII-A-2. this.requires

- VII-A-3. this.requiresConfig

- VII-A-4. this.name

- VII-A-5. this.nameArgs

- VII-A-6. this.args

- VII-A-7. this.flags

- VII-A-8. this.errorCount

- VII-A-9. this.options

- VII-B. Dans les multitâches

- VII-B-1. this.target

- VII-B-2. this.files

- VII-B-3. this.filesSrc

- VII-B-4. this.data

- VIII. Et après ?

- IX. Remerciements

I - Gruntfile.js : piqûre de rappel

Je vous ai présenté, dans le précédent article consacré à Grunt, le Gruntfile comme la pierre angulaire de la gestion des tâches avec Grunt. Ce fichier est constitué par la définition d'une fonction module.exports avec comme unique argument le paramètre grunt.

module.exports = function(grunt) {
// Code relatif à grunt
};

Grunt expose toutes ses méthodes et propriétés via cet objet grunt. Toutes ces méthodes et propriétés sont détaillées dans la documentation de l'API Grunt, les principales sont présentées dans ce qui suit.

II - L'API Grunt

L'API Grunt comporte neuf namespaces :

1. grunt.config : accès à la configuration du projet ;

2. grunt.task : enregistrer, de charger et de lancer des tâches externes ;

3. grunt.file : rechercher, lire et écrire des fichiers ;

4. grunt.fail : avertir quand quelque chose se passe mal ;

5. grunt.log : afficher des messages de sortie sur la console ;

6. grunt.option : partager des paramètres entre plusieurs tâches et accéder aux options de la ligne de commande ;

7. grunt.event : gérer les événements ;

8. grunt.template : gérer les templates ;

9. grunt.util : utilitaires pour le Gruntfile et les tâches.

Dans la suite de cet article, les quatre premiers namespaces de l'API et l'objet this dans le contexte d'une tâche sont présentés. Cela vous donnera une idée du fonctionnement global de l'API et vous aidera à aborder les prochains articles de cette série pour créer, configurer et exécuter des tâches Grunt.

III - grunt.config

L'objet grunt.config donne un accès à la configuration du projet définie dans le Gruntfile.

III-A - Initialiser les données

III-A-1 - grunt.config.init

Initialise l'objet de configuration du projet. L'objet configObject est utilisé par les tâches et est accessible via la méthode grunt.config.

grunt.config.init(configObject)
grunt.initConfig(configObject)

III-B - Requérir une donnée

III-B-1 - grunt.config.requires

Met en échec la tâche courante si au moins l'une des propriétés requises de la configuration est manquante, null ou undefined. Une ou plusieurs propriétés ou tableaux de propriétés de la configuration peuvent être passés en paramètre.

grunt.config.requires(p1 [, p2 [, …]])
this.requiresConfig(p1 [, p2 [, …]]) // depuis le contexte d'une tâche

III-C - Accéder aux données : accesseurs

III-C-1 - grunt.config.getRaw

Retourne une valeur brute de la configuration du projet Grunt, sans traiter les chaînes template <% %>. Si la propriété spécifiée existe, sa valeur est retournée, sinon null. Si aucune propriété n'est spécifiée, une copie de l'objet config est retournée.

grunt.config.getRaw([prop])

III-C-2 - grunt.config.process

Traite une valeur en évaluant récursivement les templates <% %>.

grunt.config.process(value)

1. module.exports = function(grunt) {

2. grunt.config.init({

3. bar : "C'est mal bar' !",

4. foo : "<%= bar %>"

5. });

7. grunt.registerTask("default", "Trace des choses...", function() {

8. var processed = grunt.config.process(grunt.config("foo"));

9. grunt.log.write(processed).ok(); // retourne "C'est mal bar' !"

10. );

11. };

III-C-3 - grunt.config.get

Retourne une valeur de la configuration du projet Grunt. Si la propriété spécifiée existe, sa valeur est retournée, sinon null. Si aucune propriété n'est spécifiée, une copie de l'objet config est retournée. Les templates <% %> sont traités récursivement par appel à la méthode grunt.config.process.

grunt.config.get([prop])

III-C-4 - grunt.config.set

Assigne une valeur à une propriété de la configuration du projet Grunt et la retourne.

grunt.config.set(prop, value)

III-C-5 - grunt.config

Retourne ou assigne une propriété de la configuration du projet Grunt. Cette méthode est un alias de grunt.config.set et grunt.config.get.

1. grunt.config([prop [, value]])

3. grunt.config(prop); // alias de grunt.config.get(prop)

4. grunt.config(prop, value); // alias de grunt.config.set(prop, value)

III-C-6 - grunt.config.escape

Échappe les points dans la propriété spécifiée

grunt.config.escape(propString)

1. module.exports = function(grunt) {

2. grunt.config.init({

3. foo: {

4. bar: "value"

5. }

6. });

8. grunt.registerTask("default","Trace des choses... ", function() {

9. grunt.log.write(grunt.config.escape("foo.bar")).ok(); // retourne "foo\.bar"

10. });

11. };

III-C-7 - grunt.config.merge

Fusionne récursivement les propriétés de l'objet configObject à la configuration du projet Grunt.

grunt.config.merge(configObject)

IV - grunt.task

L'API task permet d'enregistrer, de charger et de lancer des tâches externes.

IV-A - Créer des tâches

IV-A-1 - grunt.task.registerTask

Enregistre sous un alias une liste d'alias de tâches ou une tâche. Cette méthode a deux signatures :

// liste d'alias
grunt.task.registerTask(taskName, taskList)
grunt.registerTask(taskName, taskList)

// tâche
grunt.task.registerTask(taskName, description, taskFunction)
grunt.registerTask(taskName, description, taskFunction)

Si une liste d'alias est spécifiée, la nouvelle tâche sera un alias pour une ou plusieurs autres tâches. Quand cette tâche est lancée, les tâches de la taskList sont lancées dans l'ordre spécifié. L'argument taskList doit être un tableau d'alias de tâche.

Si une description et une taskFunction sont passées, la fonction est exécutée quand la tâche est lancée. La description est affichée quand la commande grunt --help est exécutée.

1. grunt.task.registerTask('default', ['jshint', 'qunit', 'concat:dist', 'uglify:dist']);

3. grunt.task.registerTask(

4. 'foo',

5. 'Une tâche simple pour tracer des choses',

6. function(arg1, arg2) {

7. if (arguments.length === 0) {

8. grunt.log.writeln(this.name + ", pas d'argument");

9. }

10. else {

11. grunt.log.writeln(this.name + ", " + arg1 + " " + arg2);

12. }

13. }

14. );

IV-A-2 - grunt.task.registerMultiTask

Enregistre une multitâche ou tâche à cibles multiples. Une multitâche est une tâche qui se répète pour chacune de ses sous-propriétés (ou targets) si aucune target n'est spécifiée.

grunt.task.registerMultiTask(taskName, description, taskFunction)
grunt.registerMultiTask(taskName, description, taskFunction)

1. module.exports = function(grunt) {

2. grunt.initConfig({

3. log: {

4. foo: [1, 2, 3],

5. bar: "Salut monde !",

6. oque: false

7. }

8. });

10. grunt.task.registerMultiTask("log", "Trace des choses…", function() {

11. grunt.log.writeln(this.target + ": " + this.data);

12. });

13. };

Dans l'exemple précédent, l'exécution du log multitâche provoque l'écriture dans la console pour chacune des trois sous-propriétés de la propriété log de la configuration du projet. Par contre, en indiquant la target foo, la tâche ne s'exécute qu'une fois pour la target spécifiée.

IV-A-3 - grunt.task.requires

Met en échec la tâche si une autre tâche est en échec ou n'a jamais été lancée.

grunt.task.requires(taskName)

IV-A-4 - grunt.task.exists

Vérifie en fonction de son nom si une tâche existe parmi les tâches enregistrées. Retourne un booléen.

grunt.task.exists(name)

IV-A-5 - grunt.task.renameTask

Renomme une tâche. Cela peut être utile pour remplacer le comportement par défaut d'une tâche, tout en conservant l'ancien nom.

grunt.task.renameTask(oldname, newname)
grunt.renameTask(oldname, newname)

IV-B - Charger des tâches externes

Pour la plupart des projets, les tâches seront définies dans le Gruntfile. Pour de grands projets, ou dans le cas où l'on a besoin de partager les tâches entre projets, les tâches peuvent être chargées depuis un ou plusieurs chemins ou plugins Grunt installés avec npm.

IV-B-1 - grunt.task.loadTasks

Charge les fichiers de tâches depuis le chemin spécifié, relatif au répertoire du Gruntfile. Cette méthode peut être utilisée pour charger des fichiers de tâches depuis un plugin Grunt local.

grunt.task.loadTasks(tasksPath)
grunt.loadTasks(tasksPath)

IV-B-2 - grunt.task.loadNpmTasks

Charge les tâches du plugin Grunt spécifié. Ce plugin doit être installé localement via npm et relativement au Gruntfile.

grunt.task.loadNpmTasks(pluginName)
grunt.loadNpmTasks(pluginName)

IV-C - Mettre les tâches en file d'attente

Grunt met automatiquement en file d'attente et lance toutes les tâches spécifiées dans la ligne de commande, mais chaque tâche peut met en file d'attente d'autres tâches à lancer.

IV-C-1 - grunt.task.run

Met en file d'attente une ou plusieurs tâches. Chaque tâche spécifiée dans taskList sera lancée immédiatement après la fin de l'exécution de la précédente. La liste de tâches peut être un tableau de tâches ou une suite d'arguments.

grunt.task.run(taskList)

1. grunt.registerTask('foo-bar-oque', 'Met en file d\'attente.', function() {

2. grunt.task.run('foo', 'bar:man', 'oque');

3. grunt.task.run(['foo', 'bar:man', 'oque']);

4. });

IV-C-2 - grunt.task.clearQueue

Vide la file d'attente. À moins que des tâches soient de nouveau mises en file d'attente, plus aucune tâche ne sera lancée.

grunt.task.clearQueue()

IV-C-3 - grunt.task.normalizeMultiTaskFiles

Normalise l'objet de configuration d'une target de tâche dans un tableau de correspondances de fichiers src-dest.

grunt.task.normalizeMultiTaskFiles(data [, targetname])

1. grunt.registerTask('normalize', function(pattern) {

2. var result = grunt.task.normalizeMultiTaskFiles(['files/**/*'], "myTargetName");

3. grunt.log.writeln(JSON.stringify(result));

4. });

V - grunt.file

Il y a plein de méthodes fournies pour lire et écrire dans les fichiers, traverser le système de fichiers et trouver des fichiers. Beaucoup de ces méthodes encapsulent les fonctionnalités de base de Node.js, mais avec en plus de la gestion d'erreur, des traces et une normalisation de l'encodage de caractères.

Note : tous les chemins sont relatifs au répertoire du Gruntfile à moins que le répertoire de travail courant soit modifié avec grunt.file.setBase ou l'option de ligne de commande --base.

V-A - Lecture et écriture

V-A-1 - grunt.file.read / grunt.file.readJSON / grunt.file.readYAML

Lit et retourne un contenu de fichier. Retourne une chaîne de caractères, à moins que options.encoding soit null, auquel cas la méthode retourne un Buffer.

grunt.file.read(filepath [, options])
grunt.file.readJSON(filepath [, options]) // contenu parsé en JSON
grunt.file.readYAML(filepath [, options]) // contenu parsé en YAML

Les propriétés reconnues dans l'objet options sont :

1. var options = {

2. // Si aucun encodage n'est spécifié, par défaut à grunt.file.defaultEncoding.

3. // S'il est spécifié à null, retourne un Buffer non décodé au lieu d'une chaîne.

4. encoding: encodingName

5. };

V-A-2 - grunt.file.write

Écrit le contenu spécifié dans un fichier en créant le chemin si nécessaire.

grunt.file.write(filepath, contents [, options])

Les propriétés reconnues dans l'objet options sont :

1. var options = {

2. // Si aucun encodage n'est spécifié, par défaut à grunt.file.defaultEncoding.

3. // Si 'contents' est un Buffer, l'encodage est ignoré.

4. encoding: encodingName

5. };

V-A-3 - grunt.file.copy

Copie un fichier source à une destination en créant le chemin si nécessaire.

grunt.file.copy(srcpath, destpath [, options])

Les propriétés reconnues dans l'objet options sont :

1. var options = {

2. // Si aucun encodage n'est spécifié, par défaut à grunt.file.defaultEncoding.

3. // Si null, la fonction 'process' reçoit un Buffer au lieu d'un String.

4. encoding: encodingName,

5. // bool processFunction(srcPath, srcContent, destPath)

6. // Si la fonction retourne 'false', la copie est interrompue.

7. process: processFunction,

8. // Patterns sur le chemin de la source. Si aucun ne correspond,

9. // le fichier ne sera pas traité par la fonction 'process'.

10. // Si globbingPatterns='true', le traitement n'aura pas lieu.

11. noProcess: globbingPatterns

12. };

V-A-4 - grunt.file.delete

Supprime le chemin spécifié. Cela supprimera les fichiers et les répertoires de manière récursive.

grunt.file.delete(filepath [, options])

Les propriétés reconnues dans l'objet options sont :

1. var options = {

2. // Permet de supprimer en dehors du répertoire de travail courant.

3. // Cette option permet être surchargée par l'option de ligne de commande --force.

4. force: true

5. };

V-B - Répertoires

V-B-1 - grunt.file.mkdir

Fonctionne comme mkdir -p0777&(~process.umask()). Crée un chemin avec tous les répertoires intermédiaires. Si mode n'est pas spécifié, la valeur par défaut est 0777&(~process.umask()).

grunt.file.mkdir(dirpath [, mode])

V-C - Types de fichiers

V-C-1 - grunt.file.exists / grunt.file.isLink / grunt.file.isDir / grunt.file.isFile

Retourne un booléen indiquant si le chemin spécifié existe, est un lien, un chemin ou un fichier ; retourne faux si le chemin n'existe pas.

Comme la méthode path.join de Node.js, ces méthodes joignent tous les arguments ensemble et normalisent le chemin résultant.

1. grunt.file.exists(path1 [, path2 [, ...]])

2. grunt.file.isLink(path1 [, path2 [, ...]])

3. grunt.file.isDir (path1 [, path2 [, ...]])

4. grunt.file.isFile(path1 [, path2 [, ...]])

V-D - Chemins

V-D-1 - grunt.file.isPathAbsolute

Retourne un booléen indiquant si le chemin spécifié est absolu.

Comme la méthode path.join de Node.js, ces méthodes joignent tous les arguments ensemble et normalisent le chemin résultant.

grunt.file.isPathAbsolute(path1 [, path2 [, ...]])

V-D-2 - grunt.file.arePathsEquivalent

Retourne un booléen indiquant si tous les chemins spécifiés se réfèrent au même chemin.

grunt.file.arePathsEquivalent(path1 [, path2 [, ...]])

V-D-3 - grunt.file.doesPathContain

Retourne un booléen indiquant si tous les chemins descendants sont contenus par le chemin ascendant.

grunt.file.doesPathContain(ancestorPath, descendantPath1 [, descendantPath2 [, ...]])

V-D-4 - grunt.file.setBase

Change le chemin de travail courant. Par défaut tous les chemins sont relatifs au Grunfile.

Comme la méthode path.join de Node.js, ces méthodes joignent tous les arguments ensemble et normalisent le chemin résultant.

grunt.file.setBase(path1 [, path2 [, ...]])

VI - grunt.fail

L'API fail est là pour vous aider quand quelque chose d'horrible survient ! Si quelque chose dysfonctionne ou est sur le point d'échouer dans une tâche, il est possible de forcer l'arrêt de Grunt.

VI-A - grunt.fail.warn

Affiche une alerte et arrête Grunt immédiatement. Grunt continuera de traiter les tâches si l'option de ligne de commande --force est utilisée. L'argument error peut être une chaîne de caractères ou un objet erreur.

grunt.fail.warn(error [, errorcode])
grunt.warn(error [, errorcode])

Si l'option de ligne de commande --stack est utilisée et qu'un objet erreur est passé, la stack trace sera affichée.

VI-B - grunt.fail.fatal

Affiche une alerte et arrête immédiatement Grunt. L'argument error peut être une chaîne de caractères ou un objet erreur.

grunt.fail.fatal(error [, errorcode])
grunt.fatal(error [, errorcode])

Si l'option de ligne de commande --stack est utilisée et qu'un objet erreur est passé, la stack trace sera affichée.

Un bip est émis à moins que l'option --no-color ne soit utilisée.

VII - Dans les tâches

Pendant l'exécution d'une tâche, Grunt expose un certain nombre de propriétés et méthodes spécifiques aux tâches via l'objet this. Le même objet est également exposé via grunt.task.current dans les templates.

VII-A - Dans toutes les tâches

VII-A-1 - this.async

Si une tâche est asynchrone, cette méthode doit être invoquée pour indiquer à Grunt d'attendre. Elle retourne une fonction done qui doit être appelée quand la tâche s'est terminée. false ou un objet erreur peut être passé à la méthode done pour indiquer à Grunt que la tâche a échoué.

Si la méthode this.async n'est pas appelée, la tâche s'exécutera de manière synchrone.

1. // Indique à Grunt que la tâche est asynchrone.

2. var done = this.async();

3. // Le code asynchrone.

4. setTimeout(function() {

5. // Simulons une erreur de manière aléatoire.

6. var error = Math.random() > 0.5;

7. // Terminé!

8. done(error);

9. }, 1000);

VII-A-2 - this.requires

Si une tâche dépend du succès de l'exécution d'une ou plusieurs autres tâches, cette méthode peut être utilisée pour forcer Grunt à s'arrêter si cette ou ces autres tâches n'ont pas été exécutées ou ont échoué. La liste de tâches peut être un tableau ou une suite de noms de tâches.

this.requires(tasksList)

VII-A-3 - this.requiresConfig

Met en échec la tâche courante si au moins l'une des propriétés de configuration requises est manquante. Un tableau ou une suite de propriétés de configuration peuvent être spécifiés.

this.requiresConfig(prop1 [, prop2 [, ...]])

Cette méthode est un alias de la méthode grunt.config.requires.

VII-A-4 - this.name

Le nom de la tâche, tel que défini avec grunt.registerTask. Dans le cas d'une multitâche, le nom est le même, quelle que soit la target.

1. module.exports = function(grunt) {

2. grunt.initConfig({

3. exemple: {

4. foo: [1, 2, 3],

5. bar: 'Salut monde !',

6. oque: false

7. }

8. });

10. grunt.task.registerMultiTask('exemple', 'Un exemple de tâche…', function() {

11. grunt.log.writeln(this.name);

12. });

13. };

Si la tâche est renommée avec grunt.task.renameTask, la propriété this.name renvoie le nouveau nom.

VII-A-5 - this.nameArgs

Le nom de la tâche, incluant tous les arguments ou flags séparés par un deux-points spécifié dans la ligne de commande. Par exemple, si une tâche exemple est exécutée avec la commande grunt exemple:foo, dans la tâche, this.nameArgs sera exemple:foo.

Si la tâche est renommée avec grunt.task.renameTask, la propriété this.nameArgs renvoie le nouveau nom.

VII-A-6 - this.args

Un tableau d'arguments passés à la tâche. Par exemple, si une tâche « exemple » est exécutée avec la commande grunt exemple:foo:tez, dans la tâche, this.args sera ["foo", "tez"].

Pour les multitâches, la target courante est omise du tableau this.args.

VII-A-7 - this.flags

Un objet généré à partir des arguments passés à la tâche. Par exemple, si une tâche exemple est exécutée avec la commande grunt exemple:foo:tez, dans la tâche, this.flags sera {foo: true, tez: true}.

Pour les multitâches, la target courante est omise de l'objet this.flags.

VII-A-8 - this.errorCount

Le nombre d'appels à grunt.log.error pendant l'exécution de la tâche. Cela peut être utilisé pour mettre en échec la tâche si des erreurs sont logées pendant l'exécution de la tâche.

VII-A-9 - this.options

Retourne un objet options. Les propriétés de l'argument optionnel defaultsObj seront surchargées par les propriétés de l'objet options au niveau de la tâche, qui seront également surchargées dans les multitâches par les propriétés de l'objet options au niveau de la target.

this.options([defaultsObj])

Cet exemple montre comment une tâche peut utiliser la méthode this.options :

1. var options = this.options({

2. enabled: false,

3. });

5. doSomething(options.enabled);

VII-B - Dans les multitâches

VII-B-1 - this.target

Contient le nom de la target courante.

VII-B-2 - this.files

Tous les fichiers spécifiés en utilisant un format et des options supportés par Grunt, un motif ou une correspondance dynamique seront automatiquement normalisés dans un format unique : un tableau de fichiers.

Cela signifie que les tâches ne gèrent pas la normalisation des chemins de fichiers. L'action est réalisée en amont par Grunt.

La tâche doit itérer sur le tableau this.files en utilisant les propriétés src et dest de chaque objet du tableau. La propriété this.files sera toujours un tableau. La propriété src sera également toujours un tableau, car il est possible d'avoir plusieurs sources pour un fichier destination.

Comme il est possible que des fichiers non existants soient inclus dans les sources, il est préférable de tester l'existence des fichiers source avant de les utiliser.

Cet exemple montre comment une tâche simple de concaténation peut utiliser la propriété this.files :

1. this.files.forEach(function(file) {

2. var contents = file.src.filter(function(filepath) {

3. // Supprimer les fichiers non existants (à vous de filtrer ou alerter).

4. if (!grunt.file.exists(filepath)) {

5. grunt.log.warn('Fichier source "' + filepath + '" non trouvé.');

6. return false;

7. }

8. else {

9. return true;

10. }

11. }).map(function(filepath) {

12. // Lit et retourne le fichier source.

13. return grunt.file.read(filepath);

14. }).join('\n');

16. // Écrit les contenus joints dans le fichier destination filepath.

17. grunt.file.write(file.dest, contents);

19. // Imprime un message de succès.

20. grunt.log.writeln('Fichier "' + file.dest + '" créé.');

21. });

Si vous avez besoin des propriétés de l'objet file d'origine, elles sont disponibles sur chaque objet file dans la propriété orig.

VII-B-3 - this.filesSrc

Tous les fichiers spécifiés par n'importe quel format sont réduits à un seul tableau. Si votre tâche est en « lecture seule » et ne tient aucun compte des chemins de destination, utilisez ce tableau plutôt que this.files.

Cet exemple montre comment une tâche « lint » simple peut utiliser la propriété this.filesSrc :

1. // Lit les fichiers spécifiés.

2. var files = this.filesSrc;

3. var errorCount = 0;

5. files.forEach(function(filepath) {

6. if (!lint(grunt.file.read(filepath))) {

7. errorCount++;

8. }

9. });

11. // Met la tâche en échec si des erreurs sont loggées.

12. if (errorCount > 0) {

13. return false;

14. }

16. // Autrement, imprime un message de succès.

17. grunt.log.ok('Fichiers lintés: ' + files.length);

VII-B-4 - this.data

Objet de configuration pour la target courante.

1. grunt.initConfig({

2. exemple: {

3. foo: [1, 2, 3],

4. bar: 'Salut monde !',

5. oque: { prop: 'value' }

6. }

7. });

9. grunt.task.registerMultiTask('exemple', 'Un exemple de tâche…', function() {

10. grunt.log.writeln(JSON.stringigy(this.data));

11. // grunt exemple:foo  >> this.data = [1, 2, 3]

12. // grunt exemple:bar  >> this.data = 'Salut monde !'

13. // grunt exemple:oque >> this.data = { prop: 'value' }

14. });

Il est recommandé d'utiliser this.options, this.files et this.filesSrc au lieu de this.data, car leurs valeurs sont normalisées.

VIII - Et après ?

L'API Grunt est assez riche et il faut bien la connaître pour comprendre et mettre en œuvre des tâches tierces ou pour créer et paramétrer ses propres tâches.

Les quatre premiers namespaces de l'API vous ont été détaillés ici, ce qui vous permettra d'aborder en toute quiétude la suite de cette série d'articles consacrés à Grunt. Je ne peux que vous recommander d'aller vous documenter sur les autres namespaces sur le site de Grunt, car ça ne peut que vous être profitable par la suite.

Dans le prochain article, nous verrons comment configurer les tâches Grunt.

IX - Remerciements

Nous remercions la société SOAT qui nous a autorisés à publier ce tutoriel.

Nous remercions également Winjerome pour la mise au gabarit et Claude Leloup pour la relecture orthographique.