资讯专栏INFORMATION COLUMN

webpack源码之tapable

Keagan / 1158人阅读

摘要:它的行为和的方法相似,用来注册一个处理函数监听器,来在信号事件发生时做一些事情他最终还是调用进行存储。而就全部取出来执行。总结上面这些知识是理解插件和运行原理的前置条件更多内容待下次分解参考源码版本说明参考链接

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93783.html

相关文章

  • 浅析webpack源码Tapable粗解(五)

    摘要:打开是个构造函数,定义了一些静态属性和方法我们先看在插件下地址上面写的解释就跟没写一样在文件下我们看到输出的一些对象方法每一个对应一个模块而在下引入的下面,我们先研究引入的对象的英文单词解释,除了最常用的点击手势之外,还有一个意思是水龙头进 打开compile class Compiler extends Tapable { constructor(context) { ...

    Arno 评论0 收藏0
  • Webpack源码阅读Tapable

    摘要:源码分析安装好包,根据上述方法,我们运行如下命令初始化在构造函数处打上断点,可以看到继承自,上面定义了一个函数。因为函数定义在原型上,并通过在构造函数中赋值。 Webpack源码阅读之Tapable webpack采用Tapable来进行流程控制,在这套体系上,内部近百个插件有条不紊,还能支持外部开发自定义插件来扩展功能,所以在阅读webpack源码前先了解Tapable的机制是很有必...

    yanwei 评论0 收藏0
  • webpack源码分析四:plugin

    摘要:流程划分纵观整个打包过程,可以流程划分为四块。核心类关系图功能实现模块通过将源码解析为树并拆分,以及直至基础模块。通过的依赖和切割文件构建出含有和包含关系的对象。通过模版完成主入口文件的写入,模版完成切割文件的写入。 前言 插件plugin,webpack重要的组成部分。它以事件流的方式让用户可以直接接触到webpack的整个编译过程。plugin在编译的关键地方触发对应的事件,极大的...

    yhaolpz 评论0 收藏0
  • webpack源码plugin机制

    摘要:调用的目的是为了注册你的逻辑指定一个绑定到自身的事件钩子。这个对象在启动时被一次性建立,并配置好所有可操作的设置,包括,和。对象代表了一次资源版本构建。一个对象表现了当前的模块资源编译生成资源变化的文件以及被跟踪依赖的状态信息。 引言 在上一篇文章Tapable中介绍了其概念和一些原理用法,和这次讨论分析webpack plugin的关联很大。下面从实现一个插件入手。 demo插件 f...

    glumes 评论0 收藏0
  • 浅析webpack源码Compiler.js模块(八)

    摘要:小尾巴最终返回了属性挂载把引入的函数模块全部暴露出来下面暴露了一些插件再通俗一点的解释比如当你你能调用文件下的方法这个和上面的不同在于上面的是挂在函数对象上的正题要想理解必须要理解再写一遍地址我们先简单的理解它为一个通过注册插件是插件的事 webpack.js小尾巴 const webpack = (options, callback) => { //... if (...

    PumpkinDylan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<