《Webpack5 核心原理与应用实践》学习笔记-> webpack插件开发基础

简介: 《Webpack5 核心原理与应用实践》学习笔记-> webpack插件开发基础


webpack和loader一样,都是webpack非常重要的组成部分,插件对比loader能做更多事情,毫不夸张的说插件可以控制整个webpack构建流程,但是同样的,他的学习成本也相当大,今天就带你认识插件,入门都不算,只是认识。

插件简介


插件是什么?插件就是一个构造函数,这个构造函数上面挂载着一个apply函数:


// es5 构造函数
function MyPlugin() {
}
MyPlugin.apply = function (compiler) {
}
// es6 class 语法
class MyPlugin {
    apply(compiler) {
    }
}


Webpack在启动时会调用插件对象的apply函数,并且会向这个函数传递一个核心对象compiler ,通过compiler ,插件内可以注册 compiler 对象及其子对象的钩子(Hook)回调,例如:


class MyPlugin {
    apply(compiler) {
        compiler.hooks.compile.tap('MyPlugin', (params) => {
          console.log('以同步方式触及 compile 钩子。');
        });
    }
}


示例中可以很看到log输出以同步方式触及 compile 钩子。,上面挂载的钩子是编译阶段的钩子,也只有同步的钩子,当然还有其他异步的钩子tapAsynctapPromise


上面的代码的意思是,通过compiler挂载钩子,钩子就是hookshooks.compile就是指定编译阶段的钩子,compile就是钩子的名称,compile.tap就是这个阶段的钩子触发的方式,有taptapAsynctapPromise


Tapable


上面说的那些玩意全都靠着Tapable这个类来实现的,参考:Tapable


webpack的钩子全都围绕着这个核心库来实现的,因为内部依赖的方法不同,所以并不是所有的tap(xxx)都可以使用,这里注意了,它并不是像某些库,你不传回调就给你返回一个Promise,可以使用同步或者异步来调用。


它是根据钩子的编写和作用,来使用什么tap(xxx),由于钩子太多了,文档写的并不好,甚至记录的不全,所以需要你看源码再来确定使用什么。


这一块实在是太绕了,重点就是让你看源码,源码怎么看?硬着头皮看。


webpack核心对象


上面说到了Tapablewebpack就有两个核心的对象使用Tapable来创建的钩子,如下:


  • Compiler:全局构建管理器,下面取自官网的解释


Compiler 模块是 webpack 的主要引擎,它通过 CLI 或者 Node API 传递的所有选项创建出一个 compilation 实例。 它扩展(extends)自 Tapable 类,用来注册和调用插件。 大多数面向用户的插件会首先在 Compiler 上注册。

在为 webpack 开发插件时,你可能需要知道每个钩子函数是在哪里调用的。想要了解这些内容,请在 webpack 源码中搜索 hooks.<hook name>.call


  • Compilation:单次构建过程的管理器,官网解释


Compilation 模块会被 Compiler 用来创建新的 compilation 对象(或新的 build 对象)。 compilation 实例能够访问所有的模块和它们的依赖(大部分是循环依赖)。 它会对应用程序的依赖图中所有模块, 进行字面上的编译(literal compilation)。 在编译阶段,模块会被加载(load)、封存(seal)、优化(optimize)、 分块(chunk)、哈希(hash)和重新创建(restore)。


当然还有其他的核心对象,课程中这一章只是提及,我就不记录了,后面应该会讲到,避免学习焦虑。


hooks的使用会有两个重点,1. 使用的时机,上面的示例有过提及,2. 触发时传递的对象。


  • compiler.hooks.compilation


  • 时机:Webpack 刚启动完,创建出 compilation 对象后触发;
  • 参数:当前编译的 compilation 对象。


  • compiler.hooks.make


  • 时机:正式开始构建时触发;
  • 参数:同样是当前编译的 compilation 对象。


  • compilation.hooks.optimizeChunks


  • 时机: seal 函数中,chunk 集合构建完毕后触发;
  • 参数:chunks 集合与 chunkGroups 集合。


  • compiler.hooks.done


  • 时机:编译完成后触发;
  • 参数: stats 对象,包含编译过程中的各类统计信息。


每个钩子传递的上下文参数不同,但主要包含如下几种类型(以 Webpack5 为例):


  • complation 对象:构建管理器,提供如下接口:


  • addModule:用于添加模块
  • addEntry:添加新的入口模块
  • emitAsset:用于添加产物文件
  • getDependencyReference:从给定模块返回对依赖项的引用
  • 等等。


  • compiler 对象:全局构建管理器,提供如下接口:


  • createChildCompiler:创建子 compiler 对象,子对象将继承原始 Compiler 对象的所有配置数据;
  • createCompilation:创建 compilation 对象,可以借此实现并行编译;
  • close:结束编译;
  • getCache:获取缓存接口
  • getInfrastructureLogger:获取日志对象
  • 等等。


  • module 对象:资源模块,有诸如 NormalModule/RawModule/ContextModule 等子类型,提供如下接口:


  • identifier:读取模块的唯一标识符;
  • getCurrentLoader:获取当前正在执行的 Loader 对象;
  • originalSource:读取模块原始内容;
  • serialize/deserialize:模块序列化与反序列化函数,用于实现持久化缓存
  • issuer:模块的引用者;
  • isEntryModule:用于判断该模块是否为入口文件;
  • 等等。


  • chunk 对象:模块封装容器,提供如下接口:


  • addModule:添加模块,之后该模块会与 Chunk 中其它模块一起打包,生成最终产物;
  • removeModule:删除模块;
  • containsModule:判断是否包含某个特定模块;
  • size:推断最终构建出的产物大小;
  • hasRuntime:判断 Chunk 中是否包含运行时代码;
  • updateHash:计算 Hash 值。


  • stats 对象:构建过程收集到的统计信息,包括模块构建耗时、模块依赖关系、产物文件列表等。


上面的这些来自课程中,个人对其进行了一定的删减,尊重原作者,同时课程中表示参考资料很少,并且在快速迭代,建议通过源码学习,所以我旨意让其难以理解,但是需要知道有这么一个玩意,好对应的查看源码。


总结


webpack的插件学习是一件任重而道远的事情,参考资料少外加内容多,可能学习插件就是阅读源码的起点。


课程中后面讲的是第三方插件的源码解读,内容讲的大概是这个插件使用了什么钩子,为什么要在这么阶段使用这个钩子,多看看第三方库也能培养阅读源码的能力,同时也能提升自己。


目录
相关文章
|
20天前
|
缓存 JavaScript 前端开发
js开发:请解释什么是Webpack,以及它在项目中的作用。
Webpack是开源的JavaScript模块打包器,用于前端项目构建,整合并优化JavaScript、CSS、图片等资源。它实现模块打包、代码分割以提升加载速度,同时进行资源优化和缓存。借助插件机制扩展功能,并支持热更新,加速开发流程。
15 4
|
2月前
|
缓存 前端开发 算法
Webpack 进阶:深入理解其工作原理与优化策略
Webpack 进阶:深入理解其工作原理与优化策略
35 2
|
2月前
|
缓存 前端开发 JavaScript
|
4月前
|
自然语言处理 JavaScript 前端开发
webpack 的热更新是如何做到的?原理是什么?
webpack 的热更新是如何做到的?原理是什么?
37 0
|
4月前
|
前端开发 JavaScript API
webpack插件开发必会Tapable
webpack插件开发必会Tapable
51 0
|
4月前
|
JSON 监控 测试技术
《Webpack5 核心原理与应用实践》学习笔记-> 提升插件健壮性
《Webpack5 核心原理与应用实践》学习笔记-> 提升插件健壮性
48 0
|
4月前
|
前端开发 JavaScript 测试技术
《Webpack5 核心原理与应用实践》学习笔记-> webpack的loader运行与调试
《Webpack5 核心原理与应用实践》学习笔记-> webpack的loader运行与调试
32 0
|
1月前
|
JavaScript 前端开发
webpack成长指北第9章---webpack如何对icon字体进行打包
webpack成长指北第9章---webpack如何对icon字体进行打包
26 1
|
1月前
|
前端开发 JavaScript
webpack成长指北第7章---webpack的css\less\scss样式打包
webpack成长指北第7章---webpack的css\less\scss样式打包
41 0
|
1月前
|
前端开发 JavaScript
webpack成长指北第8章---webpack的CSS Modules打包
webpack成长指北第8章---webpack的CSS Modules打包
19 0