2013-05-14 88 views
9

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

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

里面的咕噜声任务当然有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(...); 
    }); 
}; 

任何好的想法如何完成这件事?

非常感谢!

+0

会发生什么? – 2013-05-14 15:55:14

+0

这不是我上面做的吗?会发生什么是grunt不会等待我的回调,因此在grunt客户端返回之前不会调用grunt.initConfig()等。 – leyyinad 2013-05-14 15:58:12

+0

哦,是的,你做到了,我的错误... – 2013-05-14 20:57:40

回答

2

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

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']); 
+0

非常感谢Kyle,你的解决方案对于这个最简单的例子非常有帮助。事实上,我可能有多个脚本和样式表的目录以及许多其他任务,这些任务只能在运行时才知道,比如自动下载和解压缩(所有这些在rake中都能正常工作,但由于各种原因,我想切换到grunt) 。我可能会以这种方式工作,但在调用'grunt.initConfig()'之前让整个配置对象准备好会更容易,更简洁。这可以完成吗? – leyyinad 2013-05-14 18:21:40

+0

由于Grunt是同步的,不幸的是你不能不写你自己的grunt-cli;这比上面的解决方案imo更麻烦。 – 2013-05-14 18:37:44

+0

我想你是对的。无论如何,刚刚在GitHub上打开了一个[issue](https://github.com/gruntjs/grunt/issues/783)。 – leyyinad 2013-05-14 18:43:12

1

的你怎么可以在咕噜使用ShellJS例如:如果你只是把grunt.initconfig和grunt.loadnpmtasks等回调从异步函数

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'] 
     } 
    } 
}); 
相关问题