作者:等待1314578 | 来源:互联网 | 2023-06-07 00:47
gulp源码简介gulp源码中心部份寥寥60+行。然则经由过程这60+行代码,gulp给我们带来的确是前端自动化构建的方便。以往认为其源码一定蛮庞杂,却没想到倒是这么60+行,这6
gulp源码简介
gulp源码中心部份寥寥60+行。然则经由过程这60+行代码,gulp给我们带来的确是前端自动化构建的方便。以往认为其源码一定蛮庞杂,
却没想到倒是这么60+行,这60+行的背地,是来自于模块化的支持。
gulp的四个接口离别来源于orchestrator
,vinyl-fs
两个模块。
所以gulp的一切特征都来自于这两个模块。
Orchestrator
是用来使命治理,以及宣布一些事宜,vinyl-fs
则供应代表gulp魂魄的流式文件体系。
研讨清晰了这两个模块,也就了解了gulp。
gulp.task = Gulp.prototype.task = Gulp.prototype.add;
Gulp.prototype.src = vfs.src;
Gulp.prototype.dest = vfs.dest;
Gulp.prototype.watch = function(glob, opt, fn) { ... return vfs.watch(glob, opt, fn);};
同时gulp自身是直接继续于Orchestrator
模块。
function Gulp() {
Orchestrator.call(this); // gulp直接继续于Orchestrator模块
}
orchestrator
模块引见
A module for sequencing and executing tasks and dependencies in maximum concurrency
译:以最大并发才能递次实行使命与其依靠的一个功能模块
var Orchestrator = function () {
EventEmitter.call(this); //继续了EventEmitter对象
this.dOneCallback= undefined; // 当task里一切的使命完成时挪用这个函数
this.seq = []; // task以及task里依靠的实行递次,(start里会有多个task,每一个task又有可能有多个依靠,每一个依靠又可能有多个依靠,所以须要保留其实行递次)
this.tasks = {}; // 使命对象,包含使命名,依靠,回调函数
this.isRunning = false; // 示意当前是不是在实行使命
};
Orchestrator
应用seq这个行列数组存储须要实行的task,如许假如盘算机有才能实行,它就从行列里取走一个,假如另有才能就再取走一个,
所以这实际上是in maximum concurrency即以最大的并发才能来实行。
关于seq的组织,则是引入sequencify模块递归盘算其依靠并压入行列。
同时经由过程继续EventEmitter
对象,Orchestrator
宣布了一些列可定阅的事宜,用于插件以及命令行里的gulp在事宜发作时输出响应的信息。
`var events = [‘start’,’stop’,’err’,’task_start’,’task_stop’,
‘task_err’,’task_not_found’,’task_recursion’];`
体系暴露了这些事宜以供插件挪用,而且供应了2个要领
listenToEvent是监听某一个事宜
onAll是不论events里的谁人就监听
vinyl-fs
模块引见
重要依靠于vinyl与glob-watcher。后者供应看管文件变化的watch
接口,
前者则在file的基础上封装一些属性与要领,组织出奇特的vinyl
文件对象。
Gulp运用的是Stream,但却不是一般的Node Stream,而是基于vinyl对象的vinyl File Object Stream
。
组织函数以下
function File(file) {
if (!file) file = {};
// 保留该文件的途径变化纪录
var history = file.path ? [file.path] : file.history;
this.history = history || [];
this.cwd = file.cwd || process.cwd(); // 当前文件地点目次,即current work directory
this.base = file.base || this.cwd; // 用于相对途径,代表根目次
this.stat = file.stat || null; // 运用 fs.Stats获得的效果
this.cOntents= file.contents || null; // 文件内容
this._isVinyl = true; // 文件对象是不是是vinyl对象,vinyl对象即对file对象封装后的效果
}
Gulp为何不运用一般的Node Stream呢?
一般的Node Stream只传输String或Buffer范例,也就是只关注内容。但Gulp不只用到了文件的内容,而且还用到了这个文件的相干信息(比方途径)。
因而,Gulp的Stream是Object作风的,也就是Vinyl File Object了。所以须要有有contents、path如许的多个属性了。
写在末端
浏览gulp代码的这一次,是我第一次浏览这类开源的模块化项目。深深的被震动到了,熟悉到了模块化的巨大力量。正如7层盘算级机收集模子。
将层级笼统出来,每一层只须要关注本身那一层的事变,直接挪用下一层供应的API。就可以完成非常庞杂的事变,而不须要通常亲力亲为,一行行
代码,一个个小问题顺次处理。可以解放双手做更多的事变。
参考文档
探讨Gulp的Stream
从零单排之gulp实战
开源Nodejs项目引荐gulp中心模块:Orchestrator
WilsonLiu’s blog首发地点:http://blog.wilsonliu.cn