引言

去年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相关推荐

  1. .17-浅析webpack源码之compile流程-入口函数run

    本节流程如图: 现在正式进入打包流程,起步方法为run: Compiler.prototype.run = (callback) => {const startTime = Date.now() ...

  2. webpack 源码分析(四)——complier模块

    webpack 源码分析(四)--complier模块 上一篇我们看到,webpack-cli 通过 yargs 对命令行传入的参数和配置文件里的配置项做了转换包装,然后传递给 webpack 的 c ...

  3. webpack源码阅读——npm脚本运行webpack与命令行输入webpack的区别

    原文地址:webpack源码阅读--npm脚本执行webpack与命令行输入webpack执行的区别 如有错误,欢迎指正! webpack是目前被大家广为使用的模块打包器.从命令行输入webpack或 ...

  4. webpack 源码泄露

    0x01 漏洞简介 webpack是一个JavaScript应用程序的静态资源打包器(module bundler).它会递归构建一个依赖关系图(dependency graph),其中包含应用程序需 ...

  5. webpack源码解析七(optimization)

    前言 前面我们写了几篇文章用来介绍webpack源码,跟着官网结合demo把整个webpack配置撸了一遍: webpack源码解析一 webpack源码解析二(html-webpack-plugin ...

  6. webpack 源码分析系列 ——loader

    想要更好的格式阅读体验,请查看原文:webpack 源码分析系列 --loader 为什么需要 loader webpack是一个用于现代 JavaScript 应用程序的静态模块打包工具.内部通过构 ...

  7. webpack源码解析

    前言: webpack作为一个打包工具,它的入参是各种静态文件和配置参数,可以实现灵活的可扩展性的插件配置和loaders加载,最后输出打包后的bundle文件.下图是官网中的webpack打包示意图 ...

  8. .16-浅析webpack源码之编译后流程梳理

    这节把编译打包后的流程梳理一下,然后集中处理compile. 之前忽略了一个点,如下: new NodeEnvironmentPlugin().apply(compiler); // 引入插件加载 i ...

  9. Webpack 源码学习系列(一)

    学习源码,在于了解整体结构,对整个机制有一个整体了了解,做到心里有数,而不是看别人怎么用就怎么用,不报错就行. 获取源码 首先,先到github中获取源码. git clone https://git ...

最新文章

  1. Machine Learning | (2) sklearn数据集与机器学习组成
  2. 3台廉价服务器支撑200万TPS的消息中间件
  3. 部署环境_Hyperledger Fabric Composer环境部署(一)
  4. Liferay CE 6.1安装教程
  5. kafka自带的zk启动_Centos上将zookeeper和kafka设置为开机自启
  6. tmap | R语言中专门绘制地图的工具包
  7. html 刷新div_HTML悬浮星星:
  8. 探索Google App Engine背后的奥秘(5)- Datastore的设计(转载)
  9. Kent Beck 的《测试驱动开发》(TDD) Money示例Ruby版
  10. mpvue开发坑点总结
  11. java笔记:熟练掌握线程技术---基础篇之解决资源共享的问题(中)--前篇
  12. 软件构造 git 图形界面看Object Graph
  13. 阿里巴巴重要开源项目汇总
  14. 实现带附件格式的业务服务质量周报邮件
  15. java判断对象属性为空_Java判断对象属性全为空
  16. uos命令_UOS与Deepin OS区别详解
  17. 和女友做完后.......她说.....
  18. 通过Java批量导出带有图片的Excel文件数据
  19. 动态规划特训:贝茜的晨练(多状态转移)
  20. 疫情之后,SaaS的春天就来了吗?

热门文章

  1. Ubuntu下通过CMake文件编译CUDA+OpenCV代码操作步骤
  2. Caffe源码中caffe.proto文件分析
  3. linux驱动:音频驱动(二)ASoc
  4. linux驱动:i2c驱动(四)流程图之注册驱动
  5. 小插件 打开Android程序动画,android-单击小部件后如何启动活动?
  6. delphi 判断鼠标 左右_外设评测HyperX Pulsefire Haste游戏鼠标分享
  7. python试题for循环布尔值_Python自我修炼(升仙中....整数,布尔值,字符串,for循环)
  8. nmap 命令行执行错误_Unimap:一款基于Nmap实现的扫描速度提升工具
  9. Caught exception java.lang.interruptedException(在集群上进行多个文件合并压缩时出错)
  10. 梯度下降算法_神经网络梯度下降算法