在grunt.util.spawn中调用grunt.config.set似乎没有任何效果



我试图在项目的Grunt配置中设置当前Git SHA,但当我试图从另一个任务访问它时,它不可用,我缺少什么?

grunt.registerTask('sha', function () {
var done   = this.async();
grunt.util.spawn({
cmd: 'git',
args: ['rev-parse', '--short', 'HEAD']
}, function (err, res) {
if (err) {
grunt.fail.fatal(err);
} else {
grunt.config.set('git', {sha: res.stdout});
if (grunt.option('debug') || grunt.option('verbose')) {
console.log("[sha]:", res.stdout);
}
}
done();
});
});

运行任务后,我希望配置在另一个任务配置中可用:

requirejs: {
dist: {
...
out: '<%= app.dist %>/scripts/module_name.<%= git.sha %>.js'
...
}
}

所以。。。怎么了

问题是RequireJS正在写入文件public/scripts/module_name..js,SHA在配置中不可用(当文件名应该是public/scripts/module_name.d34dc0d3.js时)。

更新:

问题是,我使用grunt-concurrent运行requirejs任务,因此Grunt配置不适用于requirejs

grunt.registerTask('build', [
...
'getsha',
'concurrent:dist',
...
]);

并发任务,看起来像:

concurrent: {
dist: [
...
'requirejs',
...
]
}

由于grunt-concurrent将在子进程中生成任务,因此它们无法访问父进程的上下文。这就是为什么在父上下文中执行grunt.config.set()在子上下文的配置中不可用的原因。

在子上下文中提供更改的一些解决方案是:

将数据写入文件系统
使用grunt.file.write('./tmp/gitsha', res.stdout)将数据写入临时文件,然后让在子进程中运行的任务读取临时文件:

out: (function() {
var out = grunt.config('app.dist') + '/scripts/module_name.';
if (grunt.file.exists('./tmp/gitsha')) {
out += grunt.file.read('./tmp/gitsha');
} else {
out += 'unknown';
}
return out + '.js';
}())

使用套接字
这是一个非常复杂的解决方案,但仍然是一个解决方案。请参阅网络节点文档:http://nodejs.org/api/net.html#net_net_createserver_options_connectionlistener在父进程上创建服务器时,让子进程连接到数据的套接字。

或者退房https://github.com/shama/blackbox对于使此方法更简单的库。

派生父进程而不是派生/exec
另一种方法是使用Fork:http://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options而不是同时咕哝。Fork允许您使用child.send('gitsha')将消息发送到子进程,并使用process.on('message', function(gitsha) {})在子进程中接收消息

这种方法也会变得非常复杂。

使用代理任务
让您的sha任务像您当前所做的那样设置配置:

grunt.registerTask('sha', function() {
grunt.config.set('git', { sha: '1234' });
});

更改并发配置以使用sha:调用代理任务

grunt.initConfig({
concurrent: {
dist: [
'proxy:requirejs:<%= git.sha %>'
]
}
});

然后创建一个代理任务,运行一个首先设置传递值的任务:

grunt.registerTask('proxy', function(task, gitsha) {
grunt.config.set('git', { sha: gitsha });
grunt.task.run(task);
});

上面的内容可以简化为专门针对requirej设置值,但这里只是作为一个通用示例显示的,可以应用于任何任务。

最新更新