bower

Peut-être vous êtes vous déjà lancé dans une montée de version de librairies Javascript. Ou pire encore, vous êtes actuellement entrain de le faire !

Lâchez votre clavier, allez vous cherchez un café et lisez cette article. Il vous aiderait peut-être à réaliser cette tâche ingrate et vous simplifiera la vie pour la prochaine fois que vous aurez à le faire !

 

Introduction

La majorité des technologies disponibles sur le marché possèdent un package manager. Si vous faites du .Net vous connaissez bien évidement NuGet. En Node c'est NPM qui fait ce travail pour vous. Ce genre d'outil est pratique car il dispense de faire à la main la gestion des dépendances de votre projet, mais aussi les dépendances des bibliothèques tierces. C'est un bon moyen d'éviter de connaitre l'enfer (rappelez vous le DLL HELL...). J'aime souvent à me dire que sans ce genre d'outil, gérer cette problématique revient à monter sur le radeau de la méduse !

Dans le cas de Javascript les choses étaient compliquées jusqu’à ce que Twitter se colle sur le sujet et fournisse Bower, un manager entièrement dédié aux librairies Javascript clientes.

Ce gestionnaire de package fonctionne à la manière de NPM et repose sur GitHub comme repository de librairies.

 

Installation

Bower fonction grâce à Node.js et est disponible sous la forme d'une CLI (command line interface). Avant d'installer Bower il vous faut donc installer Node.js. Une fois Node installé ouvrez un terminal et tapez la commande suivante :

npm install bower -g

Comme je l'ai déjà expliqué dans mon article sur Sails.js (à lire ici) l'argument -g de la commande permet d'installer Bower dans les packages globaux de Node afin de pouvoir l'utiliser partout !

A présent Bower est utilisable directement depuis votre terminal via la commande :

bower

 

Configuration

Avant tout chose pour utiliser Bower dans votre projet il faut que celui-ci soit bower compliant. Par défaut Bower ne connait pas l'emplacement de stockage des packages Javascript dans votre projet. Si vous lancez l'installation d'une librairie il utilisera par défaut le répertoire bower_components à la racine de votre projet. Pour éviter cela ajoutez un fichier .bowerrc à la racine du projet et spécifiez le répertoire de destination des librairies :

{
    "directory" : "myJsPath",
    "json" : "bower.json"
}

Ce fichier contient aussi une information sur le fichier json utilisé par Bower pour gérer les packages. Voici le contenu d'un fichier bower.json avec une gestion de dépendance sur Angular :

{
    "name" : "myAppName",
    "version" : "0.0.1",
    "dependencies" : {
        "angular" : "1.2.22"
    }
}

Les Nodeurs auront surement reconnu la structure du json qui est similaire à celle contenue dans le fichier package.json utilisé par NPM.

 

Utilisation de la CLI

Bower est une manager particulièrement bien documenté sur le web. Plutôt que de faire l'énumération de toute les commandes contenues dans la documentation de l'API je vous propose une découverte des plus utiles !

Pour commencer vu que vous avez définit une dépendance sur Angular dans le fichier bower.json, ouvrez votre terminal, mettez vous à la racine du projet et tapez :

bower install

Les dépendances downloadées se trouvent à présent dans le répertoire angular contenu dans le chemin que vous avez définit dans le fichier .bowerrc.

Si vous voulez désinstaller la librairie il suffit de taper :

bower uninstall angular

Avant d'installer un package, vous pouvez vérifier si il est disponible via la commande :

bower search angular

Pour installer une librairie, rien de plus simple :

bower install angular

Par défaut Bower va aller chercher la librairie sur Github mais il est possible d'aller récupérer le package sur une autre url (path Github spécifique, répertoire privée ...). Il est donc possible d'aller chercher la librairie Angular directement sur Git via la commande :

bower install https://github.com/angular/angular.js.git

Ce mode d'installation n'est pas recommandé mais il peut avoir son utilité dans certains cas (ici le choix est discutable car Bower va faire un checkout complet du repository Git d'Angular dans le projet).

Par défaut Bower fait l'installation mais n'ajoute pas la dépendance dans le fichier bower.json. Il convient d'utiliser l'argument save pour le faire :

bower install angular --save

Autre détail qui peut avoir son importance avant la mise en production, il est possible de spécifier des dépendances de développement. Lors de l'installation il faudra alors utilise l'argument save-dev :

bower install angular --save-dev

Une fois l'application déployée, la récupération des packages en production se fait via la commande :

bower install --production

ou pour mettre à jour les dépendances :

bower update --production

Dans ce cas précis Bower installera / mettera à jour uniquement les packages qui n'ont pas été déclarés dans les dépendances de développement.

Nota : les arguments save et save-dev sont aussi utilisables avec la commande uninstall pour les rétirer du fichier bower.json

Pour finir il possible de spécifier explicitement une version de librairie à downloader :

bower install angular#1.2.22

Voilà pour ce tour rapide des commandes les plus utiles de Bower. Il existe d'autres petites subtilités, je vous laisses les consulter dans la documentation en ligne (ici).

 

Bower API

Il est possible de manipuler Bower directement via du code Javascript sous Node. On peut imaginer l'utilisation de bower en combinaison d'un Tasks Manager pour de l'industrialisation. Les cas d'utilisations restent rares, mais les développeurs de Bower ont  laissé la porte ouverte. Il faut en premier lieu récupérer Bower dans votre projet via NPM :

npm install bower

Ensuite ajouter la CLI Grunt dans les packages globaux de Node :

npm install grunt -g

Nota : Si vous ne connaissez pas le fonctionnement de Grunt je l'aborderais bientôt sur le blog

Pour vous montrer une utilisation de l'API Bower voici une tâche Grunt mettant à jour chaque dépendances du projet :

var bowerConfig = require('./bower');
var bower = require('bower');
var fs = require('fs');
var path = require('path');

module.exports = function(grunt){

    //définition de la tâche grunt dédié à la mise à jour des packages
    grunt.registerTask('bower', 'Client packages management', function(){
        var done = this.async();//à utiliser pour dév en async avec grunt 🙂
        
        console.log('Start bower task');

        //lecture du fichier bowerrc pour récupération du path de stockage
        fs.readFile('.bowerrc', 'utf8', function(err, buffer){
            if(err){
                console.log('Can not find .bowerrc file');
                done();
            }

            //récupération du path
            var packagePath = JSON.parse(buffer).directory;
            console.log('Package path : ' + packagePath);

            //récupération des dépendances contenues dans le fichier bower.json
            var dependencies = bowerConfig.dependencies;

            //pour chaque dépendance
            for(var dependency in dependencies){
                console.log('Dependency : ' + dependency);

                //constitution du path de la dépendance
                var dependencyPath = path.join(packagePath, dependency);
                console.log(dependencyPath);

                //on vérifie si le répertoire de la dépendance existe ou pas
                fs.exists(dependencyPath, function(exists){

                    //si package existant on update
                    if(exists){
                        console.log('Updating package');

                        //on utilise la command update pour mettre à jour.
                        //inutile d'enregistrer la dépendance dans le fichier bower.json
                        bower.commands.update([dependency], { save : false }).on('end', function(){
                            done();
                            console.log('Update done');
                        });
                    }

                    //sinon on install 🙂
                    else {
                        console.log('Installing package');

                        //on utilise la command install.
                        //inutile d'enregistrer la dépendance dans le fichier bower.json
                        bower.commands.install([dependency], { save : true }).on('end', function(){
                            done();
                            console.log('Install done');
                        });
                    }
                });
            }
        });
    });
    grunt.registerTask('default', ['bower']);
}

L’intérêt de cette exemple est discutable car il revient à faire exécuter dans votre terminal une commande update, c'est donc plus un prétexte pour vous montrez qu'il est possible d'aller plus loin avec cette technologie.

 

Conclusion

Bower est une technologie très simple d'utilisation et qui fonctionne comme NPM. C'est une aide précieuse pour gérer les dépendances dans vos projet et je vous encourage fortement à l'utiliser si vous ne voulez pas souffrir lors de la prochaine montée de version de vos librairies Javascript (ou au moins testez le ;-p) !

Catégories : Javascript

DCube · 5 septembre 2014 à 15 h 09 min

[…] de bower et grunt je vous renvoi vers les articles publiés précédemment sur le blog de Dcube (bower et grunt). Lors de la création de votre application, yeoman vous créer les fichiers de […]

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *