《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的插件学习是一件任重而道远的事情,参考资料少外加内容多,可能学习插件就是阅读源码的起点。


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


目录
相关文章
|
5天前
|
测试技术 开发者
如何确保 Webpack plugin 与其他插件的兼容性?
【10月更文挑战第23天】确保 Webpack plugin 与其他插件的兼容性需要从多个方面进行考虑和努力。通过遵循规范、进行充分测试、保持沟通协作等方式,
|
5天前
|
监控 前端开发 JavaScript
Webpack 中 HMR 插件的工作原理
【10月更文挑战第23天】可以进一步深入探讨 HMR 工作原理的具体细节、不同场景下的应用案例,以及与其他相关技术的结合应用等方面的内容。通过全面、系统地了解 HMR 插件的工作原理,能够更好地利用这一功能,为项目的成功开发提供有力保障。同时,要不断关注技术的发展动态,以便及时掌握最新的 HMR 技术和最佳实践。
|
5天前
|
缓存 前端开发 JavaScript
Webpack 动态加载的原理
【10月更文挑战第23天】Webpack 动态加载通过巧妙的机制和策略,实现了模块的按需加载和高效运行,提升了应用程序的性能和用户体验。同时,它也为前端开发提供了更大的灵活性和可扩展性,适应了不断变化的业务需求和技术发展。
|
5天前
|
缓存 前端开发 JavaScript
Webpack 4 和 Webpack 5 区别?
【10月更文挑战第23天】随着时间的推移,Webpack 可能会继续发展和演进,未来的版本可能会带来更多的新特性和改进。保持对技术发展的关注和学习,将有助于我们更好地应对不断变化的前端开发环境。
|
5天前
|
缓存 前端开发 JavaScript
webpack 原理
【10月更文挑战第23天】Webpack 原理是一个复杂但又非常重要的体系。它通过模块解析、依赖管理、加载器和插件的协作,实现了对各种模块的高效打包和处理,为现代前端项目的开发和部署提供了强大的支持。同时,通过代码分割、按需加载、热模块替换等功能,提升了应用程序的性能和用户体验。随着前端技术的不断发展,Webpack 也在不断演进和完善,以适应不断变化的需求和挑战。
|
24天前
|
缓存 前端开发 JavaScript
Webpack 打包的基本原理
【10月更文挑战第5天】
|
22天前
|
移动开发 JavaScript 前端开发
webpack学习四:使用webpack配置plugin,来使用HtmlWebpackPlugin、uglifyjs-webpack-plugin、webpack-dev-server等插件简化开发
这篇文章主要介绍了如何通过配置Webpack的插件,如HtmlWebpackPlugin、uglifyjs-webpack-plugin和webpack-dev-server,来简化前端开发流程。
31 0
webpack学习四:使用webpack配置plugin,来使用HtmlWebpackPlugin、uglifyjs-webpack-plugin、webpack-dev-server等插件简化开发
|
16天前
|
前端开发 JavaScript 数据可视化
Webpack加载器和插件之间有什么区别
【10月更文挑战第13天】Webpack加载器和插件之间有什么区别
|
2月前
|
JavaScript 前端开发
手写一个简易bundler打包工具带你了解Webpack原理
该文章通过手写一个简易的打包工具bundler,帮助读者理解Webpack的工作原理,包括模块解析、依赖关系构建、转换源代码以及生成最终输出文件的整个流程。
|
3月前
|
缓存 前端开发 JavaScript
Webpack 模块解析:打包原理、构造形式、扣代码补参数和全局导出
Webpack 模块解析:打包原理、构造形式、扣代码补参数和全局导出
103 1