webpack源码之tapable

news/2024/6/28 19:14:05

引言

去年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...


http://lihuaxi.xjx100.cn/news/238535.html

相关文章

我如何使用深度学习通过Fast.ai对医学图像进行分类

by James Dietle詹姆斯迪特尔(James Dietle) Convolutional Neural Networks (CNNs) have rapidly advanced the last two years helping with medical image classification. How can we, even as hobbyists, take these recent advances and apply them to new datasets? W…

区块链本质及特点

想知道更多关于区块链技术知识,请百度【链客区块链技术问答社区】 链客,有问必答!!1.什么是区块链? 区块链是通过去中心,化去信任的方式集体维护一个可靠数据库的技术方案。参与系统中的任意多个节点把系统…

Docker的使用(二:Docker客户端常用指令练习)

1、列出镜像; 2、搜索镜像; 3、拉取镜像; 4、构建镜像; 4.1、在Dockerfile文件所在目录构建镜像; 4.2、在其他目录构建镜像; 4.3、查看镜像是否构建成功; 5、删除镜像; 6、创建并启…

脚本练习

1.题目 2.脚本内容 #!/bin/bash while [ "$#" -lt "2" ] //验证脚本后的文件是否小于2个 do echo "please give me userfile or passwd file " exit 0 done xcat $1 | wc -l ycat $2 | wc -l while [ "$x" -ne "$y"…

从零开始学 Python 之运算符

从零开始学 Python 之运算符 前言 大家好,这里是「痴海」从零开始学习 Python 系列教程。此文首发于「痴海」公众号,欢迎大家去关注。学习一门语言最好的办法,就是教懂别人。在这公众号,我会从 Python 最基础的教程写起&#xff0…

初级开发人员的缺点_这是我想放弃初级开发人员时所做的事情

初级开发人员的缺点Coding is hard. Really hard. There are times when you’ll think “this is amazing! I love this!”编码很难。 真的很难。 有时您会认为“这太神奇了! 我喜欢这个!” But you’ll also have the not so amazing times. The time…

区块,链条的关系是什么,其含义是什么?

想知道更多关于区块链技术知识,请百度【链客区块链技术问答社区】 链客,有问必答!!区块链顾名思义有两个概念区块、链条,即数据存储在一个个区块内,区块按照时间顺序相连方式组合成的链式数据结构&#xff…

Docker的使用(三:Docker Hub远程镜像管理)

1、登录 Docker Hub; 2、修改镜像名称; 3、登录认证; 4、推送镜像; 5、查看验证;