还在使用Grunt吗,来试试Fez吧!
发布在每天学点javascript2014年2月27日view:9459
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

enter image description here

在JavaScript工具中,Grunt是当之无愧的老大。Grunt是一个任务运行器,这意味着构建工作会被定义为一些列的任务,它们UI一个接着一个运行。这些任务可能包括文件连接,应用部署,源文件查错等等。Grunt并不是唯一的任务运行器,你可能还听说过Java中的Ant,或者Ruby中的Rake。

除了使用一个任务运行器之外,开发者还有另一种选择:使用一个基于任务的构建工具。基于文件的构建工具使用非常的普遍;Make就是最有名并使用最为频繁的基于文件的构建工具,但是除此之外还有别的工具。在任务运行器中,我们需要定义任务一个接一个的运行,但是使用一个基于文件的构建工具,我们可以将构建过程定义为文件之间的转换关系。例如,我们无需定义一个任务在一个目录进行搜索并将每一个CoffeeScript文件转换为JavaScript文件,我们只需要对每一个CoffeeScript文件定义一个操作来将它转换为JavaScript文件。一开始看上去,两者之间的差别可能并不重要,但是当我们定义一个工具如何运行时它就变得重要起来了。事实上,如果我们回头看一看的话会发现Grunt显然不是一个够哦件工具。它实际上只是和诸多非构建任务一起,简单的包含了构建的步骤。

现在来说说Fez。Fez从解决了各个方面的问题:它是一个构建工具,而不是一个任务运行器。Fez不仅仅能理解构建一个项目究竟意味着什么,它同时也拥有一个“安全舱口”来允许它执行传统的“排队的任务”。Fez尝试着量两个世界最好的东西合二为一:Make的智能以及Grunt的灵活性。

什么是Fez?

Fez是一个基于tup并用JavaScript写成的基于文件的构建工具。Fez吸取了Grunt中插件操作的灵感,但是走向了一个不同的方向。在Fez中,构建过程被定义为三个不同的组件:输入,输出,以及操作。一个操作并不仅仅是一个函数。不像是Grunt,Fez并没有什么神奇的插件载入过程。你只需要简单地require操作函数并将它作为一个参数传递给一个规则即可。这就是为什么这个简单地基于规则的构建定义系统如此不可思议的原因:Fez能够根据输入的初始数列通配文件系统,然后从输入数列以及规则数列中生成整个依赖图。

例如,假设我们拥有一下的构建标准:

*.less → %f.css    
*.css → %f.min.css      
*.min.css → dist.min.css   

它写成JavaScript的形式为:

exports.default = function(spec) { 
spec.with("*.less").each(function(file) {

spec.rule(file, file.patsubst("%.less", "%.css"), less()); });


spec.with("*.css).not("*.min.css").each(function(file) { 

spec.rule(file, file.patsubst("%.css, "%.min.css), cssmin());
});
spec.with("*.min.css).all(function(files) { 

spec.rule(files, "dist.min.css", concat());
}); };   

(文件对象中的patsubst和make中的patsubst有同样的语义)

我们在文件系统中有以下的开始节点:

#图1

Fez可以创建珍格格图,从开始到结束:

#图2

现在我们所需要做的就是用一个拓扑排序来遍历这个图。我们在此可以引入并行操作,它会在子进程中执行这些操作并等待一个汇合点。和make一样,Fez会在图遍历中比较输入和输出的时间戳,这允许Fez不仅仅做那些它需要做的事。构件图甚至可以清晰地被改善:任何有一个或多个输入的节点是一个生成节点,它完全可以被安全的移除。

幂等性

Fez中最酷一个功能是继承的幂等性。

幂等性(不可数的):(数学的,计算的)幂等性是指重复使用同样的参数调用同一方法时总能获得同样的结果。

这在Fez的上下文中意味着你可以允许你的构建脚本任意多次数,除非输入文件有所变化,在此之前,没有工作会结束。这样的结果就是,在Fez中并不需要一个文件监视系统。(在Unix系统上)你运行watch node fez.js即可。

安全舱口

有时你会想要逃离整个基于规则的系统并做一些命令式的事情。这很简单:spec.fo在构建图种定义了一个节点,你可以进行任何计算,文件操作等等。通常,我们会在目标中放入一个命令节点(或者stage,在Fez中这样称它)并且使用spec.do将目标连起来,但是你可以使用spec.after(…).do来确认你已经将节点放在了图种的正确位置。下面是一个例子:

exports.default = function (spec) { 

var x = 0;

//这个stage将会以jshint规则开始。但是实际的执行顺序还不确定

spec.do(function() {
console.log(x++) });

//在stage上保存一个处理函数

var stage = spec.with("*.js").each(function (file) {
spec.rule(file, jshint()); });

//在这个stage的所有任务完成之后,运行这个任务。

spec.after(stage).do(function() {
console.log(x++); });
};  

例子

在下面,我们会使用一些动态的GIF图来帮助你理解.

在这个李忠我们将编写一个简单的LESS项目。main.less文件中有一个@impoer “mobile.less”的语句。这就是一个依赖于文件内容的二次输入的例子。main.less不会被读取知道Fez确定没有其他的操作继续生产main.less为止。在一些情形中,一个有二次输入的文件可能是一个生成文件,这个文件不会被读取知道它在构建中被再次创建。

var fez = require("fez"),
less = require("fez-less"), 
clean = require("fez-clean-css"),
concat = require("fez-concat");
exports.build = function(spec) { spec.with("main.less").one(function(file) {
spec.rule(file, less.imports(file), file.patsubst("%.less", "css/%.css"), less()); });
spec.with("dist/*.min.css").all(function(files) { spec.rule(files, "dist.min.css", concat());
});
spec.with("css/*.css").each(function(file) {
spec.rule(file, file.patsubst("css/%.css", "dist/%.min.css"), clean());
}); };
exports.default = exports.build; fez(module);  

#动图1

这个例子清楚的说明了with(…).all(…)的灵活性,它能够包含任意数目的源文件(不是生成文件)以及生成文件。和上面的例子一样,许多的节点之间不只有一个边界,而是两个。第一个边界由一个stage的输入和任意在stage中的操作节点创建。第二个边界表示一条规则主要输入和它的操作节点之间的联系。两条边界并不是必须的,但是在将Fez的行为可视化时非常有用。

var fez = require("fez");
exports.build = function(spec) { 
spec.with("a").each(function(file) {
spec.rule(file, "b", function nop1() {}); });
spec.with("b").each(function(file) { spec.rule(file, "c", function nop2() {});
});
spec.with(["a", "b", "c"]).all(function(files) { spec.rule(files, "d", function nop3() {});
}); };
exports.default = exports.build; fez(module);

enter image description here


本文译自http://flippinawesome.org/2014/02/24/using-grunt-consider-fez/,原文地址Using Grunt? Consider Fez

如果你觉得本文对你有帮助,请点击为我提供赞助

评论
发表评论
5年前

还是推荐大家用fis吧,gulp都复杂了

5年前

还是推荐大家用gulp吧, 这个这么复杂!

WRITTEN BY
张小俊128
Intern in Baidu mobile search department。认真工作,努力钻研,期待未来更多可能。
TA的新浪微博
PUBLISHED IN
每天学点javascript

javascript进阶级教程,循序渐进掌握javascript

我的收藏