loader 和 plugin

news2024/10/6 4:13:57
  1. loader 是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中
  2. plugin 赋予了 webpack 各种灵活的功能,例如打包优化、资源管理、环境变量注入等,目的是解决 loader 无法实现的其他事

两者在运行时机上的

  1. loader 运行在打包文件之前
  2. plugins 在整个编译周期都起作用

二、编写 loader 在编写 loader 前,我们首先需要了解 loader 的本质 其本质为函数,函数中的 this 作为上下文会被 webpack
填充,因此我们不能将 loader 设为一个箭头函数 函数接受一个参数,为 webpack 传递给 loader 的文件源内容 函数中 this 是由 webpack 提供的对象,能够获取当前 loader 所需要的各种信息 函数中有异步操作或同步操作,异步操作通过 this.callback 返回,返回值要求为 string 或者 Buffer

// 导出一个函数,source为webpack传递给loader的文件源内容
module.exports = function (source) {
  const content = doSomeThing2JsString(source)

  // 如果 loader 配置了 options 对象,那么this.query将指向 options
  const options = this.query

  // 可以用作解析其他模块路径的上下文
  console.log('this.context')

  /*
   * this.callback 参数:
   * error:Error | null,当 loader 出错时向外抛出一个 error
   * content:String | Buffer,经过 loader 编译后需要导出的内容
   * sourceMap:为方便调试生成的编译后内容的 source map
   * ast:本次编译生成的 AST 静态语法树,之后执行的 loader 可以直接使用这个 AST,进而省去重复生成 AST 的过程
   */
  this.callback(null, content) // 异步
  return content // 同步
}

三、编写 plugin

由于 webpack 基于发布订阅模式,在运行的生命周期中会广播出许多事件,插件通过监听这些事件,就可以在特定的阶段执行自己的插件任务

在之前也了解过 webpack 编译会创建两个核心对象:

compiler:包含了 webpack 环境的所有的配置信息,包括 options,loader 和 plugin,和 webpack 整个生命周期相关的钩子

compilation:作为 plugin 内置事件回调函数的参数,包含了当前的模块资源、编译生成资源、变化的文件以及被跟踪依赖的状态信息。当检测到一个文件变化,一次新的 Compilation 将被创建

如果自己要实现 plugin,也需要遵循一定的规范:

插件必须是一个函数或者是一个包含 apply 方法的对象,这样才能访问 compiler 实例

传给每个插件的 compiler 和 compilation 对象都是同一个引用,因此不建议修改

异步的事件需要在插件处理完任务时调用回调函数通知 Webpack 进入下一个流程,不然会卡住

实现 plugin 的模板如下

class MyPlugin {
  // Webpack 会调用 MyPlugin 实例的 apply 方法给插件实例传入 compiler 对象
  apply(compiler) {
    // 找到合适的事件钩子,实现自己的插件功能
    compiler.hooks.emit.tap('MyPlugin', (compilation) => {
      // compilation: 当前打包构建流程的上下文
      console.log(compilation)

      // do something...
    })
  }
}

一、区别

前面两节我们有提到LoaderPlugin对应的概念,先来回顾下

  • loader 是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中
  • plugin 赋予了 webpack 各种灵活的功能,例如打包优化、资源管理、环境变量注入等,目的是解决 loader 无法实现的其他事

从整个运行时机上来看,如下图所示:

可以看到,两者在运行时机上的区别:

  • loader 运行在打包文件之前
  • plugins 在整个编译周期都起作用

Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过Webpack提供的 API改变输出结果

对于loader,实质是一个转换器,将 A 文件进行编译形成 B 文件,操作的是文件,比如将A.scssA.less转变为B.css,单纯的文件转换过程

二、编写 loader

在编写 loader 前,我们首先需要了解 loader 的本质

其本质为函数,函数中的 this 作为上下文会被 webpack 填充,因此我们不能将 loader设为一个箭头函数

函数接受一个参数,为 webpack 传递给 loader 的文件源内容

函数中 this 是由 webpack 提供的对象,能够获取当前 loader 所需要的各种信息

函数中有异步操作或同步操作,异步操作通过 this.callback 返回,返回值要求为 string 或者 Buffer

代码如下所示:

// 导出一个函数,source为webpack传递给loader的文件源内容
module.exports = function (source) {
  const content = doSomeThing2JsString(source)

  // 如果 loader 配置了 options 对象,那么this.query将指向 options
  const options = this.query

  // 可以用作解析其他模块路径的上下文
  console.log('this.context')

  /*
   * this.callback 参数:
   * error:Error | null,当 loader 出错时向外抛出一个 error
   * content:String | Buffer,经过 loader 编译后需要导出的内容
   * sourceMap:为方便调试生成的编译后内容的 source map
   * ast:本次编译生成的 AST 静态语法树,之后执行的 loader 可以直接使用这个 AST,进而省去重复生成 AST 的过程
   */
  this.callback(null, content) // 异步
  return content // 同步
}

一般在编写loader的过程中,保持功能单一,避免做多种功能

less文件转换成 css文件也不是一步到位,而是 less-loadercss-loaderstyle-loader几个 loader的链式调用才能完成转换

三、编写 plugin

由于webpack基于发布订阅模式,在运行的生命周期中会广播出许多事件,插件通过监听这些事件,就可以在特定的阶段执行自己的插件任务

在之前也了解过,webpack编译会创建两个核心对象:

  • compiler:包含了 webpack 环境的所有的配置信息,包括 options,loader 和 plugin,和 webpack 整个生命周期相关的钩子
  • compilation:作为 plugin 内置事件回调函数的参数,包含了当前的模块资源、编译生成资源、变化的文件以及被跟踪依赖的状态信息。当检测到一个文件变化,一次新的 Compilation 将被创建

如果自己要实现plugin,也需要遵循一定的规范:

  • 插件必须是一个函数或者是一个包含 apply 方法的对象,这样才能访问compiler实例
  • 传给每个插件的 compilercompilation 对象都是同一个引用,因此不建议修改
  • 异步的事件需要在插件处理完任务时调用回调函数通知 Webpack 进入下一个流程,不然会卡住

实现plugin的模板如下:

class MyPlugin {
  // Webpack 会调用 MyPlugin 实例的 apply 方法给插件实例传入 compiler 对象
  apply(compiler) {
    // 找到合适的事件钩子,实现自己的插件功能
    compiler.hooks.emit.tap('MyPlugin', (compilation) => {
      // compilation: 当前打包构建流程的上下文
      console.log(compilation)

      // do something...
    })
  }
}

emit 事件发生时,代表源文件的转换和组装已经完成,可以读取到最终将输出的资源、代码块、模块及其依赖,并且可以修改输出资源的内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/727325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据分析:一文带你了解PowerBI技术

目录 一、PowerBI简介 二、Power BI 的组成部分 三、Power BI 如何匹配角色 四、下载 Power BI Desktop 五、登录到 Power BI 服务 六、Power BI的优势 6.1 发展潜力巨大,前景广阔 6.2 可连接的数据来源多,数据量大 6.3 软件更新频率高 6.4 可为…

飞凌嵌入式邀您共聚2023慕尼黑上海电子展

2023慕尼黑上海电子展(electronica China)将于7月11日~13日在国家会展中心(上海)盛大召开。本届展会将展示最新的电子技术与应用,涵盖了半导体、嵌入式系统、电源、电池、测试仪器、智能制造、电子设计自动化等众多领域…

【历史上的今天】7 月 7 日:C# 发布;Chrome OS 问世;《仙剑奇侠传》发行

整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来。 今天是 2023 年 7 月 7 日,在 1927 年的今天,互联网发展的早期创新者格伦卡勒(Glen Culler)出生;卡勒是 Culler-Fri…

如何洞察 .NET程序 非托管句柄泄露

一:背景 1. 讲故事 很多朋友可能会有疑问,C# 是一门托管语言,怎么可能会有非托管句柄泄露呢? 其实一旦 C# 程序与 C 语言交互之后,往往就会被后者拖入非托管泥潭,让我们这些调试者被迫探究 非托管领域问题…

第二章:安装VM+CentOS7安装+JDK及tomcat安装+安装mysql

目录 1. 安装VMWare 2. centos7安装 2.1 常见问题 3. 查看、设置IP地址 4. 关机与重启 5. 切换为国内源 6. Linux下的目录结构 7. JDK及tomcat安装 7.1 将压缩包上传到linux 7.2 安装JDK 7.3 安装Tomcat 8. 安装mysql 8.1 离线安装 8.2 在线安装 1. 安装VMWare 注意…

CentOS8.5 环境下部署 vsftpd

目录 前言安装vsftpd验证是否安装vsftpd安装vsftpd:操作vsftpd:vsftpd.conf配置创建用户添加端口安全组验证ftp搭建是否成功 前言 在物联网项目中,我们会经常使用到ftp服务器,今天我们就来实现一下centos8.5环境下部署vsftpd的搭建…

Buffer源码

介绍 首先 Buffer 是一个能存储基本数据类型的容器(除了 Boolean 类型),从 java.nio 包的继承结构就能看出来。 Java中的Buffer类是一个抽象类。Buffer类提供了一种将数据存储在内存中的方式,并提供了一些操作数据的方法。Buffer…

原型模式:如何最快速地clone一个HashMap散列表?

我们还像学习建造者模式一样 思考 什么是原型模式?主要解决哪些问题? 如果对象的创建成本比较大,而同一个类的不同对象之间差别不大(大部分字段都相同),在这种情况下,我们可以利用对已有对象…

5 类型转换

类型转换是变量与变量之间的,变量与常量之间是赋值。 5.1 自动类型转换 小转大。如下图所示,注意,byte不能自动转为char类型,因为类型不匹配,但是可以通过强转来转。 代码如下: byte a 10;int b a; 5.2…

测试流程实战(1)

目录: 测试流程梳理业务架构分析实战测试用例管理实战Bug 录入与管理实战如何写 Bug 报告编写 Bug 报告 1.测试流程梳理 2.业务架构分析实战 使用 plantuml 完成登录流程时序图plantuml 官网:使用简单的文字描述画UML图的开源工具。plantuml 在线绘图…

【HDC.Cloud 2023】华为开发者大会2023来了!这份PaaS参会指南请查收!

了不起的开发者们,我们来啦! 7月7日,华为开发者大会2023 ( Cloud )将拉开帷幕 PaaS诚邀您参加这场不容错过的年度开发者盛会,让我们一起开启探索之旅。 我们将为开发者们提供PaaS生态资源工具、学习成长、分享交流、生态实践等…

Docker 安装Flowable-ui

查询镜像 docker search flowable-ui 拉取镜像 docker pull flowable/flowable-ui 使用默认数据库(默认H2数据库) docker run --name flowable-ui \ -p 8080:8080 \ -d --restartalways \ flowable/flowable-ui 使用MySQL数据库 docker run --name…

Windows环境Jmeter调优

在windows环境下搭建jmeter的压测实验环境,需要对操作系统默认的一些个参数进行设置,以提高并发能力。特别是作为压力机的时候。 Socket 编程时,单机最多可以建立多少个 TCP 连接,受到操作系统的影响。 Windows 下单机的TCP连接数…

simulink while/if/switch case

目录 while if Switch case while 循环设置100次 if Switch case 子模块可以用法和if一样

vue3混入mixins

Vue中混入的作用是分发组建中可复用的功能 新建mixins文件夹,新建mixins.ts文件 import { ref } from vue;export default function () {const num ref(0);const fav ref(false);const fvbtn () > {num.value 1;fav.value true;setTimeout(() > {fav.va…

六西格玛在服务业的案例:如何通过过程改进提高客户满意度?

六西格玛是一种质量管理方法,旨在通过减少缺陷和提高效率用以改善业务流程。在服务行业,六西格玛可以帮助企业提高客户满意度,缩短服务周期,降低成本。下面张驰咨询给大家分享一个服务行业的六西格玛案例。 1、背景介绍 这家服务…

Docker学习笔记26

Docker stack应用: 1)Docker 层级关系中的最高层次——stack,一个stack就是一组有关联的服务的组合,可以一起编排,一起管理。 早期,使用service来发布服务。但是service每次只能发布一个service。 yaml可…

(Windows版)PostgreSQL - TimescaleDB插件的2种安装方法

一:下载pgsql相对应的timescaledb插件包 下载地址:https://github.com/timescale/timescaledb/releases/tag/2.10.1 二:开始安装 注意:在安装前,先关闭PostgreSQL 服务 方法一 1.【控制面板\系统和安全\管理工具\…

手把手教-单片机和w5500模块基于rt-thread中wiznet软件包的使用

一、开发环境 硬件:stm32f407野火开发板,w5500模块 软件:rt-thread操作系统,wiznet软件包,基于正点原子stm32f407的bsp包(需要根据实际修改系统时钟) 引脚连接方式: 单片机引脚&…

镀金积分球——激光红外功率测量

中波红外激光作为干扰光源,可对红外导引头及红外观瞄设备实施压制式干扰,激光器远场功率密度分布是评价其作战效能的重要指标。通用的激光功率测量设备多基于近场,并且因接收口径有限,只能检测到很小特定区域内的激光功率&#xf…