webpack源码之tapable
引言
去年3月的时候当时写了一篇webpack2-update之路,到今天webpack已经到了4.2,更新挺快的,功能也在不断的完善,webpack4特性之一就是零配置, webpack生命力真的很顽强,积极跟上环境的变化,响应社区的需求,不断的迭代,因为parcel在其之前就有这个特性了。直接运行webpack命令,默认production模式,但是会有WARNING。
如下所示在package.json中启动脚本配置
"scripts": {"build": "webpack --mode production", //代码做了压缩/作用域提升(就是将依赖模块内容直接放到当前模块内)/去掉了开发模式下存在的代码/更容易使用输出的资源文件(assets做了优化处理)"dev": "webpack-dev-server --open --mode development", //支持注释/提示/source maps},
这种约定大于配置的开发方式,在很多框架中都存在, 默认的配置覆盖了大部分用户使用的场景,提高了大部分人的生产力。当然除了默认配置外还有其它一些特性,例如支持导入更多的模块类型,可以解析.json.wasm类型的文件等等。
虽然使用形式上变化的这么快, 但是其核心思想没多大变化。 其中webpack内部有一个事件流机制,基于tapable,也是本文研究的对象,它的作用是将各个插件串联起来,还有webpack中负责编译的Compile也是tapable的实例,所以这个蛮重要的,下面详细说一下。
tapable概念
tapable类似于node中的EventEmitter,专注于自定义事件的触发和处理,自身可以被继承或混入到其它模块中。例如compile的实现就用到了tapable,如下所示。
var Tapable = require("tapable");function Compiler() {Tapable.call(this);
}Compiler.prototype = Object.create(Tapable.prototype);
Hook分析
class Car {constructor() {this.hooks = {accelerate: new SyncHook(["newSpeed"]),break: new SyncHook(),calculateRoutes: new AsyncParallelHook(["source", "target", "routesList"])};}}
const myCar = new Car();
//使用tap方法添加了一个消费者,其中tap的第一个参数,一般是用来确认插件的名称
myCar.hooks.accelerate.tap("LoggerPlugin", newSpeed => console.log(`Accelerating to ${newSpeed}`));
myCar.hooks.accelerate.call('100')
//输出 Accelerating to 100
说明 其中SyncHook继承了Hook方法,主要作用是重写了compile方法。而Hook内部维护了 this.taps = [],每次执行tap时,都会进行insert,call的时候通过
this[name](...args)
进行执行,在call执行的时候其内部涉及到工厂模式,因为call的调用,需要先执行当前SyncHook的compile方法,用工厂模式的目的就是根据传入的不同option返回不同的通过new Function拼接出的
处理逻辑函数,因为Hook有好几种实现,在实现类的实例中添加的消费者可以是sync,promise,async等等,都需要对应不同compile来进行处理。
tapable使用分析
const {Tapable,SyncHook} = require("tapable");
const myCar = new Tapable();
myCar.hooks = {myHook: new SyncHook()
};
let speed = 0;
myCar.plugin("my-hook", () => speed+=2);
myCar.hooks.myHook.call();
myCar.plugin("my-hook", () => speed += 10);
myCar.hooks.myHook.call();
console.log(speed);
//输出14
说明
plugin(name:string, handler:function):允许将一个自定义插件注册到 Tapable 实例 的事件中。它的行为和 EventEmitter 的 on() 方法相似,用来注册一个处理函数/监听器,来在信号/事件发生时做一些事情,他最终还是调用hook.tap(tapOpt, options.fn)进行存储。而call就全部取出来执行。
总结
上面这些知识是理解插件和webpack运行原理的前置条件,更多内容待下次分解
参考源码版本说明
tapable: "1.0.0",
webpack: "^4.2.0",
参考链接
https://medium.com/webpack/we...
https://medium.com/webpack/we...
https://github.com/dwqs/blog/...
https://doc.webpack-china.org...
https://github.com/webpack/ta...
webpack源码之tapable相关推荐
- .17-浅析webpack源码之compile流程-入口函数run
本节流程如图: 现在正式进入打包流程,起步方法为run: Compiler.prototype.run = (callback) => {const startTime = Date.now() ...
- webpack 源码分析(四)——complier模块
webpack 源码分析(四)--complier模块 上一篇我们看到,webpack-cli 通过 yargs 对命令行传入的参数和配置文件里的配置项做了转换包装,然后传递给 webpack 的 c ...
- webpack源码阅读——npm脚本运行webpack与命令行输入webpack的区别
原文地址:webpack源码阅读--npm脚本执行webpack与命令行输入webpack执行的区别 如有错误,欢迎指正! webpack是目前被大家广为使用的模块打包器.从命令行输入webpack或 ...
- webpack 源码泄露
0x01 漏洞简介 webpack是一个JavaScript应用程序的静态资源打包器(module bundler).它会递归构建一个依赖关系图(dependency graph),其中包含应用程序需 ...
- webpack源码解析七(optimization)
前言 前面我们写了几篇文章用来介绍webpack源码,跟着官网结合demo把整个webpack配置撸了一遍: webpack源码解析一 webpack源码解析二(html-webpack-plugin ...
- webpack 源码分析系列 ——loader
想要更好的格式阅读体验,请查看原文:webpack 源码分析系列 --loader 为什么需要 loader webpack是一个用于现代 JavaScript 应用程序的静态模块打包工具.内部通过构 ...
- webpack源码解析
前言: webpack作为一个打包工具,它的入参是各种静态文件和配置参数,可以实现灵活的可扩展性的插件配置和loaders加载,最后输出打包后的bundle文件.下图是官网中的webpack打包示意图 ...
- .16-浅析webpack源码之编译后流程梳理
这节把编译打包后的流程梳理一下,然后集中处理compile. 之前忽略了一个点,如下: new NodeEnvironmentPlugin().apply(compiler); // 引入插件加载 i ...
- Webpack 源码学习系列(一)
学习源码,在于了解整体结构,对整个机制有一个整体了了解,做到心里有数,而不是看别人怎么用就怎么用,不报错就行. 获取源码 首先,先到github中获取源码. git clone https://git ...
最新文章
- Machine Learning | (2) sklearn数据集与机器学习组成
- 3台廉价服务器支撑200万TPS的消息中间件
- 部署环境_Hyperledger Fabric Composer环境部署(一)
- Liferay CE 6.1安装教程
- kafka自带的zk启动_Centos上将zookeeper和kafka设置为开机自启
- tmap | R语言中专门绘制地图的工具包
- html 刷新div_HTML悬浮星星:
- 探索Google App Engine背后的奥秘(5)- Datastore的设计(转载)
- Kent Beck 的《测试驱动开发》(TDD) Money示例Ruby版
- mpvue开发坑点总结
- java笔记:熟练掌握线程技术---基础篇之解决资源共享的问题(中)--前篇
- 软件构造 git 图形界面看Object Graph
- 阿里巴巴重要开源项目汇总
- 实现带附件格式的业务服务质量周报邮件
- java判断对象属性为空_Java判断对象属性全为空
- uos命令_UOS与Deepin OS区别详解
- 和女友做完后.......她说.....
- 通过Java批量导出带有图片的Excel文件数据
- 动态规划特训:贝茜的晨练(多状态转移)
- 疫情之后,SaaS的春天就来了吗?
热门文章
- Ubuntu下通过CMake文件编译CUDA+OpenCV代码操作步骤
- Caffe源码中caffe.proto文件分析
- linux驱动:音频驱动(二)ASoc
- linux驱动:i2c驱动(四)流程图之注册驱动
- 小插件 打开Android程序动画,android-单击小部件后如何启动活动?
- delphi 判断鼠标 左右_外设评测HyperX Pulsefire Haste游戏鼠标分享
- python试题for循环布尔值_Python自我修炼(升仙中....整数,布尔值,字符串,for循环)
- nmap 命令行执行错误_Unimap:一款基于Nmap实现的扫描速度提升工具
- Caught exception java.lang.interruptedException(在集群上进行多个文件合并压缩时出错)
- 梯度下降算法_神经网络梯度下降算法