摘要:源码简介源码核心部分寥寥行。同时本身是直接继承于模块。写在末尾阅读代码的这一次,是我第一次阅读这种开源的模块化项目。深深的被震撼到了,认识到了模块化的巨大力量。就能完成非常复杂的事情,而不需要凡是亲力亲为,一行行代码,一个个小问题依次解决。
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
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/87788.html
摘要:所以实现小图标时雪碧图跟图标字体会在一个网站共存,自定义图标字体为什么比较耗时,且太复杂图标无法实现请往下看开发流程就了解了。参考资料细谈浅谈图标字体向下兼容优雅降级技术绘制小图标技巧雪碧图图标字体矢量小图标设计本文对应源码源码地址演示地址 showImg(https://segmentfault.com/img/bVRnAC?w=431&h=220); 之前写了一篇关于雪碧图的博文,...
摘要:在真正写了一段时间的基础组件和基础工具后,才发现自动化测试有很多好处。有了自动化测试,开发者会更加信任自己的代码。由于维护测试用例也是一大笔开销毕竟没有多少测试会专门帮前端写业务测试用例,而前端使用的流程自动化工具更是没有测试参与了。 本文转载自 天猫前端博客,更多精彩文章请进入天猫前端博客查看 前言 为何要测试 以前不喜欢写测试,主要是觉得编写和维护测试用例非常的浪费时间。在真正写了...
摘要:组建属性初始化默认值类型在中将下面的代码替换成下面的代码最后一步将初始状态从构造函数中转变成属性初始化。在构造函数的后天添加正确的代码你需要把状态初始化代码从构造函数中删除。 这是React和ECMAScript6结合使用系列文章的第二篇。 下面是所有系列文章章节的链接: React 、 ES6 - 介绍(第一部分) React类、ES7属性初始化(第二部分) React类,方法绑定...
阅读 1133·2023-04-26 00:34
阅读 3331·2023-04-25 16:47
阅读 2085·2021-11-24 11:14
阅读 3068·2021-09-26 09:55
阅读 3586·2019-08-30 15:56
阅读 3180·2019-08-29 16:57
阅读 1878·2019-08-26 13:38
阅读 2646·2019-08-26 12:22