如何在grunt.initConfig()之前执行异步操作?

时间:2013-05-14 15:46:07

标签: javascript node.js asynchronous gruntjs

现在我有了我的Gruntfile设置来执行一些自动检测魔术,比如解析源文件来解析roder中的一些PHP源,以便在运行grunt.initConfig()之前动态地找出我需要知道的文件名和路径。

不幸的是grunt.initConfig()似乎不是异步运行的,所以在我可以调用之前,我看不到让异步代码执行的方法。有没有一个技巧来完成这个或我是否必须同步重写我的检测程序?在我的回调到来之前,有没有简单的方法来阻止执行?

在grunt任务中,当然有this.async(),但initConfig()不起作用。

这是一个精简的例子:

function findSomeFilesAndPaths(callback) {
  // async tasks that detect and parse
  // and execute callback(results) when done
}

module.exports = function (grunt) {
  var config = {
    pkg: grunt.file.readJSON('package.json'),
  }

  findSomeFilesAndPaths(function (results) {
    config.watch = {
      coffee: {
        files: results.coffeeDir + "**/*.coffee",
        tasks: ["coffee"]
         // ...
      }
    };

    grunt.initConfig(config);

    grunt.loadNpmTasks "grunt-contrib-coffee"
    // grunt.loadNpmTasks(...);
  });
};

如何完成这项任务?

非常感谢!

3 个答案:

答案 0 :(得分:5)

我会将此作为一项任务,因为Grunt是同步的,或者如果您可以findSomeFilesAndPaths同步。

grunt.initConfig({
  initData: {},
  watch: {
    coffee: {
      files: ['<%= initData.coffeeDir %>/**/*.coffee'],
      tasks: ['coffee'],
    },
  },
});

grunt.registerTask('init', function() {
  var done = this.async();
  findSomeFilesAndPaths(function(results) {
    // Set our initData in our config
    grunt.config(['initData'], results);
    done();
  });
});

// This is optional but if you want it to
// always run the init task first do this
grunt.renameTask('watch', 'actualWatch');
grunt.registerTask('watch', ['init', 'actualWatch']);

答案 1 :(得分:2)

通过重写,同步风格解决。 ShellJS派上用场,特别是对于同步执行shell命令。

答案 2 :(得分:1)

如何在Grunt中使用ShellJS的示例:

grunt.initConfig({
    paths: {
        bootstrap: exec('bundle show bootstrap-sass').output.replace(/(\r\n|\n|\r)/gm, '')
    },
    uglify: {
        vendor: {
            files: { 'vendor.js': ['<%= paths.bootstrap %>/vendor/assets/javascripts/bootstrap/alert.js']
        }
    }
});