문제 설명
grunt.initConfig() 전에 비동기 작업을 수행하려면 어떻게 해야 합니까? (How can I perform an asynchronous operation before grunt.initConfig()?)
Now I have my Gruntfile setup to perform some automatic detection magic like parsing sourcefiles to parse some PHP sources in roder to dynamically figure out filenames and paths I need to know before running grunt.initConfig()
.
Unfortunately grunt.initConfig()
doesn't seem to be meant to be run asynchronously, so I see no way to have my asynchronous code executed before I can call it. Is there a trick to accomplish this or do I have to rewrite my detection routines synchronously? Is there any easy way to block execution before my callback has arrived?
Inside grunt tasks there is of course this.async()
, but for initConfig()
that doesn't work.
Here's a stripped down example:
<pre class="lang‑js prettyprint‑override">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(...);
});
};
</code></pre>
Any good ideas how to get this done?
Thanks a lot!
참조 솔루션
방법 1:
I would do it as a task since Grunt is sync or if you can make findSomeFilesAndPaths
sync.
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']);
방법 2:
Solved by rewriting, synchronous style. ShellJS came in handy, especially for synchronously executing shell commands.
방법 3:
Example of how you could use ShellJS in Grunt:
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']
}
}
});
(by leyyinad、Kyle Robinson Young、leyyinad、jgillich)
참조 문서