认识loader和plugin

news2024/12/26 10:36:48

在 webpack 中,专注于处理 webpack 在编译过程中的某个特定的任务的功能模块,可以称为插件。它和 loader 有以下区别:
1loader 是一个转换器,将 A 文件进行编译成 B 文件,比如:将 A.less 转换为 A.css,单纯的文件转换过程。webpack 自身只支持 js 和 json 这两种格式的文件,对于其他文件需要通过 loader 将其转换为 commonJS 规范的文件后,webpack 才能解析到。
2plugin 是一个扩展器,它丰富了 webpack 本身,针对是 loader 结束后,webpack 打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听 webpack 打包过程中的某些节点,执行广泛的任务。
loader 的特征
loader是一个export出来的function。(来自官网的翻译)
loader 的作用以及使用
对于网页组成基础都是html,js,css,但是vue使用loader才能对代码进行转化成为基本的网页,而且loader可以对象项目起来优化作用,避免了以下的情况

image.png



常用的loader也有:
样式
1css-loader : 解析css文件中代码
2style-loader : 将css模块作为样式导出到DOM中
3less-loader : 加载和转义less文件
4sass-loader : 加载和转义sass/scss文件
脚本转换编译
1script-loader : 在全局上下文中执行一次javascript文件,不需要解析
2babel-loader : 加载ES6 代码后使用Babel转义为ES5后浏览器才能解析
Files文件
1url-loader : 多数用于加载图片资源,超过文件大小显示则返回data URL
2raw-loader : 加载文件原始内容(utf-8格式)
图片文件
1image-webpack-loader 对于图片的压缩加载
加载框架
1vue-loader : 加载和转义vue组件
plugin 的特征
webpack 插件有以下特征
●是一个独立的模块。
●模块对外暴露一个 js 函数。
●函数的原型 (prototype) 上定义了一个注入 compiler 对象的 apply 方法。
●apply 函数中需要有通过 compiler 对象挂载的 webpack 事件钩子,钩子的回调中能拿到当前编译的 compilation 对象,如果是异步编译插件的话可以拿到回调 callback。
●完成自定义子编译流程并处理 complition 对象的内部数据。
●如果异步编译插件的话,数据处理完成后执行 callback 回调。

1webpack 读取配置的过程中会先执行 new HelloPlugin(options) 初始化一个 HelloPlugin 获得其实例。
2初始化 compiler 对象后调用 HelloPlugin.apply(compiler) 给插件实例传入 compiler 对象。
3插件实例在获取到 compiler 对象后,就可以通过 compiler.plugin (事件名称, 回调函数) 监听到 Webpack 广播出来的事件。并且可以通过 compiler 对象去操作 Webpack。
事件流机制
webpack 本质上是一种事件流的机制,它的工作流程就是将各个插件串联起来,而实现这一切的核心就是 Tapable。
Webpack 的 Tapable 事件流机制保证了插件的有序性,将各个插件串联起来, Webpack 在运行过程中会广播事件,插件只需要监听它所关心的事件,就能加入到这条 webapck 机制中,去改变 webapck 的运作,使得整个系统扩展性良好。
Tapable 也是一个小型的 library,是 Webpack 的一个核心工具。类似于 node 中的 events 库,核心原理就是一个订阅发布模式。作用是提供类似的插件接口。方法如下:

我们来看下 Tapable

Tapable 为 webpack 提供了统一的插件接口(钩子)类型定义,它是 webpack 的核心功能库。webpack 中目前有十种 hooks,在 Tapable 源码中可以看到,他们是:

Tapable 还统一暴露了三个方法给插件,用于注入不同类型的自定义构建行为:
●tap:可以注册同步钩子和异步钩子。
●tapAsync:回调方式注册异步钩子。
●tapPromise:Promise 方式注册异步钩子。
webpack 里的几个非常重要的对象,Compiler, Compilation 和 JavascriptParser 都继承了 Tapable 类,它们身上挂着丰富的钩子。
编写一个插件
一个 webpack 插件由以下组成:
●一个 JavaScript 命名函数。
●在插件函数的 prototype 上定义一个 apply 方法。
●指定一个绑定到 webpack 自身的事件钩子。
●处理 webpack 内部实例的特定数据。
●功能完成后调用 webpack 提供的回调。
下面实现一个最简单的插件

然后在 webpack 的配置中注册使用就行,只需要在 webpack.config.js 里引入并实例化就可以了:

此时我们执行一下 npm run build 就能看到效果了

image.png


Compiler 对象 (负责编译)
Compiler 对象是webpack的编译对象。包含了当前运行 Webpack 的配置,包括 entry、output、loaders 等配置,这个对象在启动 Webpack 时被实例化,而且是全局唯一的。Plugin 可以通过该对象获取到 Webpack 的配置信息进行处理。
compiler 上暴露的一些常用的钩子:

image.png


更多
下面来举个例子

此时我们执行一下 npm run build 就能看到效果了

image.png


有一些编译插件中的步骤是异步的,这样就需要额外传入一个 callback 回调函数,并且在插件运行结束时执行这个回调函数

Compilation 对象
Compilation 对象代表了一次资源版本构建。当运行 webpack 开发环境中间件时,每当检测到一个文件变化,就会创建一个新的 compilation,从而生成一组新的编译资源。一个 Compilation 对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息,简单来讲就是把本次打包编译的内容存到内存里。Compilation 对象也提供了插件需要自定义功能的回调,以供插件做自定义处理时选择使用拓展。
简单来说,Compilation 的职责就是构建模块和 Chunk,并利用插件优化构建过程。
Compiler 代表了整个 Webpack 从启动到关闭的生命周期,而 Compilation 只是代表了一次新的编译,只要文件有改动,compilation 就会被重新创建。
Compilation 上暴露的一些常用的钩子:

image.png


更多
Compiler 和 Compilation 的区别
●Compiler 代表了整个 Webpack 从启动到关闭的生命周期
●Compilation 只是代表了一次新的编译,只要文件有改动,compilation 就会被重新创建。
手写插件 1:文件清单
在每次 webpack 打包之后,自动产生一个一个 markdown 文件清单,记录打包之后的文件夹 dist 里所有的文件的一些信息。
思路:
1.通过 compiler.hooks.emit.tapAsync() 来触发生成资源到 output 目录之前的钩子 2.通过 compilation.assets 获取文件数量 3.定义 markdown 文件的内容,将文件信息写入 markdown 文件内 4.给 dist 文件夹里添加一个资源名称为 fileListName 的变量 5.写入资源的内容和文件大小 6.执行回调,让 webpack 继续执行

手写插件 2:去除注释
思路:
1.通过 compiler.hooks.emit.tap() 来触发生成文件后的钩子 2.通过 compilation.assets 拿到生产后的文件,然后去遍历各个文件 3.通过 .source() 获取构建产物的文本,然后用正则去 replace 调注释的代码 4.更新构建产物对象 5.执行回调,让 webpack 继续执行

Plain Text复制代码

class RemoveCommentPlugin {

constructor(options) {

this.options = options

}

apply(compiler) {

compiler.hooks.emit.tap('RemoveComment', compilation = >{

for (const name in compilation.assets) {

if (name.endsWith('.js')) {

const contents = compilation.assets[name].source();

const reg = /("([^\\\"]*(\\.)?)*")|('([^\\\']*(\\.)?)*')|(\/{2,}.*?(\r|\n))|(\/\*(\n|.)*?\*\/)|(\/\*\*\*\*\*\*\/)/g;

const noComments = contents.replace(reg, function(word) {

// 去除注释后的文本

return /^\/{2,}/.test(word) || /^\/\*!/.test(word) || /^\/\*{3,}\//.test(word) ? '': word

})

compilation.assets[name] = {

source: () = >noComments,

size: () = >noComments.length,

};

}

}

});

}

}

module.exports = RemoveCommentPlugin


手写插件 3:去除不用的代码
思路:
1.通过 compiler.hooks.emit.tap() 来触发生成文件后的钩子 2.通过 compilation.assets 拿到生产后的文件,然后去遍历各个文件 3.通过 .source() 获取构建产物的文本,然后用正则去 replace 调注释的代码 4.更新构建产物对象 5.执行回调,让 webpack 继续执行

Plain Text复制代码

class RemoveCommentPlugin {

constructor(options) {

this.options = options

}

apply(compiler) {

compiler.hooks.emit.tap('RemoveComment', compilation => {

//去除/*environment*/开启以/*end environment*/结束的代码

// 例如:/*environment*/ console.log(hello world);/*end environment*/

for (const name in compilation.assets) {

if (name.endsWith('.js')) {

const contents = compilation.assets[name].source();

const reg = /\/\*environment\*\/([\s\S]*)\/\*end environment\*\//g;

const noComments = contents.replace(reg, '');

compilation.assets[name] = {

source: () => noComments,

size: () => noComments.length,

};

}

}

});

}

}

module.exports = RemoveCommentPlugin

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

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

相关文章

静态HTTP应用的性能优化技巧

在Web开发中,静态HTTP应用以其简单、快速和安全的特点受到了广泛欢迎。然而,随着Web应用的规模不断扩大,性能问题也日益突出。本文将为你介绍一些静态HTTP应用的性能优化技巧,让你的应用飞得更快、更稳定。 一、压缩文件 文件压…

报名众筹小程序系统源码:在线投票+众筹模式+完整的安装部署教程

随着互联网的普及和发展,众筹作为一种新型的融资方式,逐渐受到越来越多人的关注和认可。众筹不仅可以帮助个人或企业筹集资金,还可以促进创意的传播和实现。因此,开发一款具有在线投票和众筹功能的微信小程序,对于满足…

Java 多线程之线程安全集合

文章目录 一、概述二、List 接口线程安全实现类2.1 普通 List 变线程安全 List2.2 Vector2.3 CopyOnWriteArrayList 三、Map 接口线程安全实现类3.1 普通 Map 变线程安全 Map3.2 Hashtable3.3 ConcurrentHashMap3.4 ConcurrentSkipListMap 有序/跳表 四、Set 接口线程安全实现类…

【Jenkins】Centos环境安装Jenkins(通过rpm安装)

在Centos操作系统中通过rpm安装Jenkins 参考官网 https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos 1、下载安装Jdk17 下载安装 # 更新您的系统,不一定需要 # sudo yum -y update # 安装将用于下载 Java 17 二进制文件的 wget 命令行工具。 s…

Paper Reading: (ACRST) 基于自适应类再平衡自训练的半监督目标检测

目录 简介工作重点方法CropBankFBRAFFRTwo-stage Pseudo-label Filtering 实验与SOTA比较消融实验 简介 题目:《Semi-Supervised Object Detection with Adaptive Class-Rebalancing Self-Training》,AAAI’22, 基于自适应类再平衡自训练的半…

光栅化渲染:可见性问题和深度缓冲区算法

在前面第二章中,我们了解到,在投影点(屏幕空间中的点)的第三个坐标中,我们存储原始顶点 z 坐标(相机空间中点的 z 坐标): 当一个像素与多个三角形重叠时,查找三角形表面上…

几本学习中整理和面试的PDF,以及精选面试资料

今天和大家分享我在学习过程中整理的笔记,以及我在准备面试中,阅读的PDF,包括Spring Cloud学习手册、Docker学习手册、RabbitMQ学习手册、Spring 6手册、Maven手册、22w字面试手册等等,包括了大部分后端技术以及大部分高频面试题&…

【Maven】加载 Maven 项目报错 status code: 501, reason phrase: HTTPS Required (501)

问题描述 加载 Maven 项目报错,错误信息如下: status code: 501, reason phrase: HTTPS Required (501)尝试使用 -U 标记(强制更新快照)运行 Maven 导入原因分析 这个错误通常表示 Maven 在尝试从远程仓库下载依赖时遇到了 HTTPS 必需的错误。 解决方…

苹果电脑双开

1.第一步:在应用程序中找到微信 复制一个副本出来 2.第二步:打开复制的《微信副本》 右键打开 – 显示包内容 3.第三步:Contents - info.plist 后右键 打开方式 选择 文本编辑 4.第四步:找到查找和替换 这一段com.tencent.xinWeChat 后面是修改 com.tenc…

极新AIGC行业峰会 | 圆桌对话:探索中国AGI迭代之路

“AGI正处在一个巨大的研发范式革命的起点。” 整理 | 周梦婕 编辑 | 小白 出品|极新 2023年11月28日,极新AIGC行业峰会在北京东升国际科学院拉开帷幕,峰会上午的圆桌环节由凡卓资本合伙人王梦菲主持,深势科技战略副总裁何雯…

R语言对医学中的自然语言(NLP)进行机器学习处理(1)

什么是自然语言(NLP),就是网络中的一些书面文本。对于医疗方面,例如医疗记录、病人反馈、医生业绩评估和社交媒体评论,可以成为帮助临床决策和提高质量的丰富数据来源。如互联网上有基于文本的数据(例如,对医疗保健提供者的社交媒体评论),这些数据我们可…

Reactor线程模型详解

文章目录 传统的阻塞式 I/OReactor 模式单 Reactor 单线程单Reactor多线程主从Reactor多线程 在目前的线程模型中一种是传统阻塞的I/O模型,一种是Reactor线程模型。 传统的阻塞式 I/O 为了同时处理多个客户端的请求,服务端为每一个连接都会分配一个新的…

Freemarker基本语法与案例讲解

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《SpringBoot》。🎯🎯 &…

搭建消息时光机:深入探究RabbitMQ_recent_history_exchange在Spring Boot中的应用【RabbitMQ实战 二】

🎏:你只管努力,剩下的交给时间 🏠 :小破站 搭建消息时光机:深入探究RabbitMQ_recent_history_exchange在Spring Boot中的应用 引言前言第一:开启插件支持第二:springboot整合第三&am…

分类预测 | Matlab实现DBO-SVM蜣螂算法优化支持向量机的数据分类预测【23年新算法】

分类预测 | Matlab实现DBO-SVM蜣螂算法优化支持向量机的数据分类预测【23年新算法】 目录 分类预测 | Matlab实现DBO-SVM蜣螂算法优化支持向量机的数据分类预测【23年新算法】分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现DBO-SVM蜣螂算法优化支持向量机的…

基于FPGA的HDMI编码模块设计(包含工程源文件)

前文已经通过FPGA实现了TMDS视频编码的算法,也对单沿数据采样转双沿数据采样的ODDR原语做了详细讲解和仿真验证,本文将这些模块结合,设计出HDMI编码模块,在HDMI接口的显示器上显示一张图片。 1、整体思路 如图1所示,是…

大数据机器学习与深度学习——过拟合、欠拟合及机器学习算法分类

大数据机器学习与深度学习——过拟合、欠拟合及机器学习算法分类 过拟合,欠拟合 针对模型的拟合,这里引入两个概念:过拟合,欠拟合。 过拟合:在机器学习任务中,我们通常将数据集分为两部分:训…

Mybatis代理对象是如何生成的

Mybatis源码解析 - mapper代理对象的生成,你有想过吗,我们讲到了mybatis操作数据库的流程:先创建SqlSessionFactory,然后创建SqlSession,然后再创建获取mapper代理对象,最后利用mapper代理对象完成数据库的…

jmeter配置使用(mac)

前言 这篇文件就是一个笔记,非mac用户不用看了,我这是换了mac,要用jmeter的倒腾。 一、下载 二、使用步骤 1.解压 tgz格式的直接用tar命令就行 tar -zxvf 包名2.启动 一种是进入解压包的bin目录启动 这种方式启动的就是命令框不能关闭&am…

Python实现多种图像锐化方法:拉普拉斯算子和Sobel算子

Python实现多种图像锐化方法:拉普拉斯算子和Sobel算子 图像和视频逐渐成为人们生活中信息获取的重要来源,而图像和视频在传输过程中有很多因素可能造成图像模糊,比如不正确的聚焦会产生离焦模糊,景物和照相机的相对运动会造成运动…