【发布时间】:2017-11-18 20:11:57
【问题描述】:
我正在使用 Grunt 生成构建。我是 Grunt、javascript 和 nodejs 的新手,因此欢迎任何新的观点。
我的 Gruntfile 中的一些任务依赖于插件(例如 'uglify' 用于 javascript 缩小),而还有一些其他工作流最适合只编写 javascript 函数本身。
我经常遇到需要执行以下操作的情况:(1) 执行一个 javascript 函数 (2) 在该函数之后立即运行一个 grunt 任务 (3) 执行另一个 javascript 函数。它需要按这个顺序发生。然而,由于 Grunt 只是一个任务调度程序,它最终会运行 (1)、排队 (2)、运行 (3),然后运行 (2) 作为最后一步,在 (1) 和 (3) 完成之后。
以下是假设自定义任务的一个非常简单的用例,以更好地解释情况。
grunt.task.registerTask('minifyJS', function() {
jsFilepathMapping = configureUglifiy();
/** note - configureUglify is needed because the minification filepaths
are generated on the fly, I do not know them before the script runs
and more than that, there are so many that it would be really bulky
to create init targets for each single minification file that needs
to be generated.*/
grunt.task.run('uglify');
updateJsScriptTags(jsFilepathMapping); // update the <script> tags in my HTML
});
问题是我需要按照上面显示的顺序运行这些东西。 然而,由于 grunt 是一个任务调度器,当这个任务运行时会发生以下情况
- configureUglify() 函数将运行。
- 'uglify' 将被排队 - 不运行。
- updateJsScriptTags() 函数将RUN。
- 现在默认任务已经完成 - 现在才会“丑化”,它已排队运行。
现在,我明白为什么会这样了。 Grunt 是一个任务调度程序——任务正在排队。这是有道理的,而不是抱怨它。 相反,我问的是解决这个问题的方法是什么?这样我在使用这种功能和任务的组合时就可以实现这种排序?我想这一定是超级简单和普遍的,我只是不知道它是什么!
我意识到的一个选择是将这些功能中的每一个转换为任务本身。但是,问题在于 configureUglifiy() 返回一个复杂的数据结构,然后 updateJsScriptTags() 会使用该结构。除了使用 'options' 属性之外,似乎没有一种在 Grunt 任务之间共享数据的好方法,该属性仅在任务本身中可用。我想我可以这样做,但是,我在这里担心的是这会使事情变得不可读并且......有点危险,因为你现在有这个任务,它依赖于在另一个任务期间修改的数据结构,而且它不是立即很明显,直到你开始挖掘函数。
让我举个例子。哪个更适合你?
/**
documentation which defines what the argment filepathMapping is
Furthermore, since the function takes an argument, the context is
immediately clearer just looking at the function declaration.
*/
function updateJsScriptTags(filepathMapping) {
// do stuff ...
for ( key in filepathMapping ) { // oh cool! i know what this arg does, my documentation nicely explains it, and its structure too
// lots of stuff
}
}
...
// and elsewhere in the script, where it's being invoked:
var aMapping = someFunc();
updateJsScriptTags(aMapping);
对比
grunt.task.registerTask('updateJsScriptTags', 'update js tags', function() {
// do stuff.
...
// many lines later:
grunt.options('filepathMapping') // Oh, what is this attribute? Let me go look around the rest of the script to find out where it comes from
}
...
// and ultimately, where it's being invoked.
grunt.task.run('someTask'); // global options param gets modified somewhere in here, but you'd never know it looking at this line of code
grunt.task.run('updateJsScriptTags'); // this task will depend on that modification
我发现这让事情变得更不可读,而不是一个简单的函数,它接受要使用的参数,并且可以强加一个特定的结构。如果我在一个任务中修改一些全局参数中的一堆属性,这些属性稍后会在另一个任务中被消耗掉,这似乎也更容易让事情变得错误。更麻烦的是,共享的属性名称是硬编码的。我知道这是一个非常简单的用例,但开始想象一组更复杂的函数,它们依赖于可能是复杂数据类型的多个参数,并且是我关心的地方。
简单总结一下:是否有替代方法可以实现函数/插件任务/函数/插件任务的顺序排列,而不需要将函数本身转换为自定义任务? p>
【问题讨论】:
标签: javascript node.js gruntjs scheduled-tasks