Javascript 在grunt.util.spawn内调用grunt.config.set不会';似乎没有任何效果

Javascript 在grunt.util.spawn内调用grunt.config.set不会';似乎没有任何效果,javascript,node.js,gruntjs,spawn,Javascript,Node.js,Gruntjs,Spawn,我试图在我的项目的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配置中设置当前的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'
    ...
  }
}
而并发任务,看起来像:

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';
}())
使用插座
这是一个非常复杂的解决方案,但仍然是一个解决方案。请参阅网络节点文档:在父进程上创建服务器时,让子进程连接到数据的套接字

或者查看使此方法更简单的库

分叉父进程,而不是派生/exec
另一种方法是使用fork:而不是grunt concurrent。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 %>'
    ]
  }
});

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

我看不到您向我们展示的代码中有任何问题。您好,路易斯,问题是,
requirejs
正在生成一个名为:
public/scripts/module\u name..js
的文件,它应该在哪里:
public/scripts/module\u name.DEADC0DE.js
您是如何运行任务的?
requirejs
也在生成吗?如果是这样,它将无法访问您在父进程中设置的grunt配置。啊,谢谢@KyleRobinsonYoung您的问题让我意识到我做错了什么。我的
build
任务运行其他几个任务。。。但是,
requirejs
任务是通过Grunt
并发任务执行的。现在我知道是什么问题了,但仍然不知道如何解决它!有什么想法吗?@IvanTorres对不起,我用了模棱两可的语言。我的意思是,我没有看到你遇到的问题的原因(我称之为“问题”)。我现在意识到,“问题”可以理解为指原因或结果。也许有人知道该怎么做,但我得多看看Gruntile才能弄明白。(当我开始写这篇评论时,我还没有看到最新的编辑。)感谢@KyleRobinsonYoung的详细回复,我将使用代理标签,好主意!
grunt.initConfig({
  concurrent: {
    dist: [
      'proxy:requirejs:<%= git.sha %>'
    ]
  }
});
grunt.registerTask('proxy', function(task, gitsha) {
  grunt.config.set('git', { sha: gitsha });
  grunt.task.run(task);
});