web-dev-qa-db-fra.com

Automatisez l'installation de NPM et Bower avec Grunt

J'ai un nœud/angular qui utilise npm pour la gestion des dépendances backend et bower pour la gestion des dépendances frontend. Je voudrais utiliser une tâche grognement pour effectuer les deux commandes d'installation. Je n'ai pas été capable de comprendre comment le faire.

J'ai fait une tentative en utilisant exec, mais il n'installe en fait rien.

module.exports = function(grunt) {

    grunt.registerTask('install', 'install the backend and frontend dependencies', function() {
        // adapted from http://www.dzone.com/snippets/execute-unix-command-nodejs
        var exec = require('child_process').exec,
            sys  = require('sys');

        function puts(error, stdout, stderr) { console.log(stdout); sys.puts(stdout) }

        // assuming this command is run from the root of the repo
        exec('bower install', {cwd: './frontend'}, puts);
    });

};

Lorsque je cd dans le frontend, ouvre node et exécute ce code à partir de la console, cela fonctionne très bien. Que fais-je de mal dans la tâche de grognement?

(J'ai également essayé d'utiliser les API bower et npm, mais je n'ai pas pu faire fonctionner cela non plus.)

63
Nick Heiner

Vous devez dire à grunt que vous utilisez une méthode asynchrone (.exec) En appelant la méthode this.async(), en obtenant un rappel et en l'appelant lorsque exec est terminé.

Cela devrait fonctionner:

module.exports = function(grunt) {
    grunt.registerTask('install', 'install the backend and frontend dependencies', function() {
        var exec = require('child_process').exec;
        var cb = this.async();
        exec('bower install', {cwd: './frontend'}, function(err, stdout, stderr) {
            console.log(stdout);
            cb();
        });
    });
};

Voir Pourquoi ma tâche asynchrone ne se termine-t-elle pas?

35
Sindre Sorhus

Pour installer des composants côté client pendant npm install en même temps que les bibliothèques côté serveur, vous pouvez ajouter vos package.json

"dependencies": {
    ...
    "bower" : ""
},
"scripts": {
    ...
    "postinstall" : "bower install"
}

Je préfère faire la différence entre l'installation et le test/build

134
jsan

Pour info, voici où je suis pour l'instant.

Vous auriez également pu prendre le problème d'une autre manière, c'est-à-dire laisser npm gérer l'exécution de bower, et finalement laisser grogner gérer npm. Voir tiliser bower avec herok .

grunt.registerTask('install', 'install the backend and frontend dependencies', function() {
    var async = require('async');
    var exec = require('child_process').exec;
    var done = this.async();

    var runCmd = function(item, callback) {
        process.stdout.write('running "' + item + '"...\n');
        var cmd = exec(item);
        cmd.stdout.on('data', function (data) {
            grunt.log.writeln(data);
        });
        cmd.stderr.on('data', function (data) {
            grunt.log.errorlns(data);
        });
        cmd.on('exit', function (code) {
            if (code !== 0) throw new Error(item + ' failed');
            grunt.log.writeln('done\n');
            callback();
        });
    };

    async.series({
        npm: function(callback){
            runCmd('npm install', callback);
        },
        bower: function(callback){
            runCmd('bower install', callback);  
        }
    },
    function(err, results) {
        if (err) done(false);
        done();
    });
});
7
xavier.seignard

Grunt tâche qui fait juste ce travail (selon la solution de Sindre ci-dessus):

https://github.com/ahutchings/grunt-install-dependencies

2
nostopbutton

Tâche Grunt qui fait la commande d'installation de bower: https://github.com/yatskevich/grunt-bower-task

vous pouvez également utiliser https://github.com/stephenplusplus/grunt-bower-install

injecter automatiquement vos dépendances dans le fichier index.html

2
Itsik Avidan