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

标签 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.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'
    ...
  }
}

那么...出了什么问题?

问题是 Require JS 正在写入文件 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';
}())

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

或者查看https://github.com/shama/blackbox一个使这个方法变得更简单的库。

fork 父进程而不是spawn/exec
另一种方法是使用 fork:http://nodejs.org/api/child_process.html#child_process_child_process_fork_modulepath_args_options而不是 grunt 并发。 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);
});

上面的内容可以简化为专门在 requirejs 上设置值,但此处仅作为可应用于任何任务的通用示例显示。

关于javascript - 在 grunt.util.spawn 中调用 grunt.config.set 似乎没有任何效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21793480/

相关文章:

Javascript检查 Canvas 上的透明图像是否被点击

java - Volley 没有收到 http 响应,但 postman 收到了

javascript - hasOwnProperty 和 ECMAScript 5 严格模式

javascript - 为什么 Express 不实现 Node.js 风格的回调?

javascript - Sails.js 无法使用日期范围查询参数获取新创建的用户

javascript - 通过命令行更改 Grunt 配置变量

requirejs - 使用r.js打包一个使用 'text'加载 View 的SPA应用程序

html - 更改 css 文件和 htmls 或 jade 中的 css 类名称的 Grunt 任务

javascript - 如何删除代理创建的对象的属性?

JavaScript 顶部和左侧位置未按预期工作