使用 grunt 自动化 npm 和 bower 安装

Posted

技术标签:

【中文标题】使用 grunt 自动化 npm 和 bower 安装【英文标题】:Automate npm and bower install with grunt 【发布时间】:2012-12-19 10:47:02 【问题描述】:

我有一个节点/角度项目,它使用 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);
    );

;

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

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

【问题讨论】:

我的配置相同,想知道你是如何运行npm install的?以同样的方式?还是有其他方法? 【参考方案1】:

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

这应该可行:

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

见Why doesn't my asynchronous task complete?

【讨论】:

【参考方案2】:

仅供参考,这是我现在的位置。

你也可以用另一种方式解决这个问题,即让 npm 处理 bower 的执行,并最终让 grunt 处理 npm。见Use bower with 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();
    );
);

【讨论】:

【参考方案3】:

完成这项工作的 Grunt 任务(根据上面 Sindre 的解决方案):

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

【讨论】:

【参考方案4】:

要在npm install 期间安装客户端组件而不是服务器端库,您可以添加package.json

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

我更喜欢区分安装和测试/构建

【讨论】:

最精简的解决方案,以及明确分离构建和开发设置关注点,无需添加额外的 grunt 任务别名,或需要向我的项目添加额外的文档。太棒了,谢谢! 最美味的......干净利落 如此简单!如此简单。这是迄今为止最优雅的解决方案。谢谢 "postinstall" : "bower install" 在这种情况下也可以工作,因为 node_modules/.bin 被添加到 PATH 环境变量中。 npm 在运行脚本时添加它,因此它可以在任何地方运行【参考方案5】:

执行 bower install 命令的 Grunt 任务: https://github.com/yatskevich/grunt-bower-task

另外,你可以使用 https://github.com/stephenplusplus/grunt-bower-install

自动将你的依赖注入到 index.html 文件中

【讨论】:

以上是关于使用 grunt 自动化 npm 和 bower 安装的主要内容,如果未能解决你的问题,请参考以下文章

npm、bower、gulp、Yeoman 和 grunt 有啥用?

npm,bower,gulp,Yeoman和grunt有什么好处?

Grunt,NPM和Bower之间的区别(package.json vs bower.json)

sh 系统,Git,Git LFS,NPM,Grunt,Bower和ngrok的bash函数和别名

NPM vs. Bower vs. Browserify vs. Gulp vs. Grunt vs. Webpack [关闭]

设置 nvm 以正确使用 npm 和 grunt