2013-05-14 132 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'] 
     } 
    } 
}); 
相關問題