认识loader和plugin

在 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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IDEA之设置项目包的结构层级为eclipse默认样式

idea默认项目包的结构层级如下: 想修改成eclipse默认的那种样式,设置步骤如下: 1.点击下图中红框图标进行设置 2.选择 Tree Appearance,取消勾选 Compact Middle Packages 3.勾选红框里的两个选项,Flatten Packages 和 Hide Empty Middle Pa…

HTML插入视频和音频(详解)

📍文章目录📍 🧀一,简介🧀二,视频(video)🍧1,普通的视频插入🍧2,在html5中嵌入视频网站视频 🧀三,音频(audio) 🧀一&#…

50mA、24V、超低 IQ、低压降稳压器

一、Description The TPS715 low-dropout (LDO) voltage regulators offer the benefits of high input voltage, low-dropout voltage, low-power operation, and miniaturized packaging. The devices, which operate over an input range of 2.5 V to 24 V, are stable wit…

Wordle 游戏实现 - 使用 C++ Qt

标题:Wordle 游戏实现 - 使用 C Qt 摘要: Wordle 是一款文字猜词游戏,玩家需要根据给定的单词猜出正确的答案,并在限定的次数内完成。本文介绍了使用 C 和 Qt 框架实现 Wordle 游戏的基本思路和部分代码示例。 引言:…

jmeter简单压测kafka

前言 这也是一个笔记,就是计划用jmeter做性能测试,但是这里是只要将数据放到kafka的topic里,后面查看下游业务处理能力。 一、方案 因为只要实现数据放到kafka,参考了下博友的方案,可行。 二、方案验证 详细过程就不…

CNN 卷积神经网络之 DenseNet 网络的分类统一项目(包含自定义数据集的获取)

1. DenseNet 网络介绍 本章实现的项目是DenseNet 网络对花数据集的五分类,下载链接: 基于迁移学习的 DenseNet 图像分类项目 DenseNet 网络是在 ResNet 网络上的改进,大概的网络结构如下: 1.1 卷积的简单介绍 图像识别任务主要…

计算机速成课Crash Course - 10. 早期的编程方式

今天继续计算机速成课Crash Course的系列讲解。 更多技术文章,关注公众号 “摸鱼IT” 锁定 -上午11点 - ,感谢大家关注、转发、点赞! 10. 早期的编程方式 前几集我们把重点放在计算机的原理,怎么从内存读写数据,执行…

js基础:函数、对象、WebAPIs-DOM

一、函数和对象 1、函数概述 🤖chatgpt:什么是函数?为什么要有函数? 函数是一种可重复使用的代码块,它们可以接受输入(参数)、执行特定的任务,并返回结果。 JavaScript中函数是非常…

鸿蒙OS应用开发之按钮组件(2)

前面学习了简单的按钮添加到程序里,并且使用了简单的布局排列来放置。其实按钮还有很多种形式,会在不同的场合来使用。 默认的按钮外形,跟前面例子的程序是一样的: 包含着图片的按钮: 不同外形的按钮:

Python编程进阶:轻松掌握多线程和多进程

大家好,今天我们将讨论如何利用Python执行多线程和多进程任务。它们提供了在单个进程或多个进程之间执行并发操作的方法,并行和并发执行可以提高系统的速度和效率。在讨论多线程和多进程的基础知识之后,我们还将讨论使用Python库实现它们的实…

利用poi实现将数据库表字段信息导出到word中

研发文档对于开发人员来说都不陌生了,而研发文档里重要的一部分就是表结构设计,需要我们在word建个表格把我们数据库中的表字段信息填进去,表多的话靠我们手动去填非常累人!!! 因此作为开发人员可不可以写…

计算机网络应用层(期末、考研)

计算机网络总复习链接🔗 目录 DNS域名服务器域名解析过程分类递归查询(给根域名服务器造成的负载过大,实际中几乎不用)迭代查询 域名缓存(了解即可)完整域名解析过程采用UDP服务 FTP控制连接与数据连接 电…

Flutter Dart FFI Pointer<Uint8>类型如何转成数组或String

前言 继上一次发布的 Flutter 直接调用so动态库,或调用C/C源文件内函数 内容,最终我选择了第二种方式,直接把整个 Native C 的项目源代码放进了 Flutter 工程里编译(放在iOS的目录是因为它不支持自定义源码路径,Andro…

Linux免密实现文件拷贝(建立机器之间的SSH密钥认证)

背景: 在之前的工作中,我需要在我的shell脚本中实现将机器A的文件拷贝至机器B,然后去执行一系列的操作。由于我将我想要执行的动作完全写入了shell脚本中,并且不想每次执行时都去输入密码,因此这里,我们需要…

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

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

HBase 高可用集群详细图文安装部署

目录 一、HBase 安装部署 1.1 Zookeeper 正常部署 1.2 Hadoop 正常部署 1.3 HBase 安装 1.4 HBase 的配置文件 1.4.1 hbase-env.sh 1.4.2 hbase-site.xml 1.4.3 regionservers 1.4.4 创建目录 1.5 HBase 远程发送到其他节点 1.6 HBase 服务的启动 1.6.1 单点…

Linux---创建、删除文件及目录命令

1. 创建、删除文件及目录命令的使用 命令说明touch 文件名创建指定文件mkdir 目录名创建目录(文件夹)rm 文件名或者目录名删除指定文件或者目录rmdir 目录名删除空目录 touch命令效果图: mkdir命令效果图: rm命令效果图: rm删除目录效果图 说明: rm命令想要删除目录需要加上…

CSS实现鼠标移动到图片上显示遮罩层效果

这是一张图片&#xff0c;我希望鼠标移动到上面的时候显示一个遮罩层&#xff0c;层级上有两个按钮&#xff0c;一个查看&#xff0c;一个删除 首先是要写一个大盒子包裹两个部分&#xff0c;一个是图片部分&#xff0c;一个是遮罩层部分&#xff0c;然后再用CSS样式控制 <e…

C# 提取PDF中指定文本、图片的坐标

获取PDF文件中文字或图片的坐标可以实现精确定位&#xff0c;这对于快速提取指定区域的元素&#xff0c;以及在PDF中添加注释、标记或自动盖章等操作非常有用。本文将详解如何使用国产PDF库通过C# 提取PDF中指定文本或图片的坐标位置&#xff08;X, Y轴&#xff09;。 ✍ 用于…

每日一练【最大连续1的个数 III】

一、题目描述 给定一个二进制数组 nums 和一个整数 k&#xff0c;如果可以翻转最多 k 个 0 &#xff0c;则返回 数组中连续 1 的最大个数 。 二、题目解析 本题同样是利用滑动窗口的解法。 首先进入窗口&#xff0c;如果是1&#xff0c;就直接让right&#xff0c;但是如果是…