使用grunt自动执行npm和bower安装

Nic*_*ner 63 javascript node.js npm gruntjs bower

我有一个节点/角度项目,它使用npm进行后端依赖管理,并使用bower进行前端依赖管理.我想使用grunt任务来执行两个安装命令.我一直无法弄清楚如何做到这一点.

我尝试使用exec,但实际上并没有安装任何东西.

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);
    });

};
Run Code Online (Sandbox Code Playgroud)

当我cd进入前端,打开node,并从控制台运行此代码,这工作正常.我在咕噜咕噜的任务中做错了什么?

(我也尝试使用bower和npm API,但也无法使用.)

jsa*_*san 134

npm install在服务器端库的同时安装客户端组件,可以添加package.json

"dependencies": {
    ...
    "bower" : ""
},
"scripts": {
    ...
    "postinstall" : "bower install"
}
Run Code Online (Sandbox Code Playgroud)

我更喜欢在安装和测试/构建之间做出区分

  • 最简化的解决方案,明确分离构建和开发设置问题,而无需添加额外的grunt任务别名,或者需要向我的项目添加其他文档.这太棒了,谢谢! (10认同)
  • 最好吃的......干净利落的 (3认同)
  • 很简单!如此如此简单.这是迄今为止最优雅的解决方案.谢谢 (2认同)
  • `"postinstall":"bower install"`也适用于这种情况,因为`node_modules/.bin`被添加到`PATH` env变量中. (2认同)

Sin*_*hus 35

你需要.exec通过调用this.async()方法,获取回调并在exec完成时调用它来告诉grunt你正在使用异步方法().

这应该工作:

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();
        });
    });
};
Run Code Online (Sandbox Code Playgroud)

请参阅为什么我的异步任务没有完成?


xav*_*ard 7

仅供参考,这是我现在所处的位置.

您也可以采用另一种方式解决问题,即让npm处理bower的执行,并最终让grunt处理npm.请参阅使用带有heroku的凉亭.

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();
    });
});
Run Code Online (Sandbox Code Playgroud)