webpack plugin

1、基本写法及使用

这里用到 emit 钩子 及make 钩子,前者是串行后者是并行

/***  1.webpack加载webpack.config.js中所有配置,此时就会new TestPlugin(),执行插件的constructor2.webpack创建compiler对象3.遍历所有plugins中插件,调用插件的apply方法4.执行剩下编译流程《触发各个hooks事件)*/class TestPlugin {constructor() {console.log('testPlugin-constructor');}apply(compiler) {console.log('testPlugin-apply');// 由文档可知,environment是同步钩子,所以需要使用tap注册compiler.hooks.environment.tap("TestPlugin",() => (console.log("TestPlugin environment")))// 由文档可知,emit是异步串行钩子 AsyncSeriesHook// 串行则顺讯执行compiler.hooks.emit.tap("TestPlugin", (compilation) => {console.log("TestPlugin emit 111");})compiler.hooks.emit.tapAsync("TestPlugin", (compilation, callback) =>{setTimeout(() => {console.log("Testplugin emit 222");callback();}, 2000)})compiler.hooks.emit.tapPromise("TestPlugin", (compilation) => {return new Promise((resolve) => {setTimeout(() => {console.log("TestPlugin emit 333"); resolve();},1000);})})// 由文档可知,make是异步并行钩子 AsyncParallelHookcompiler.hooks.make.tapAsync("TestPlugin", (compilation, callback) => {compilation.hooks.seal.tap("TetsPlugin", ()=>{console.log("TestPlugin seal");})setTimeout(() => {console.log("Testplugin make 111");callback();}, 3000);})compiler.hooks.make.tapAsync("TestPlugin", (compilation, callback) => {setTimeout(() => {console.log("Testplugin make 222");callback();}, 1000);})compiler.hooks.make.tapAsync("TestPlugin", (compilation, callback) => {setTimeout(() => {console.log("Testplugin make 333");callback();}, 2000);})}
}
module.exports = TestPlugin

webpack.config.js中的配置

// 引入插件
const  TestPlugin  = require('./plugins/test-plugin')// 使用插件
new TestPlugin()

打印结果

2、BannerPlugin

class BannerWebpackPlugin {constructor(options = {}) {this.options = options;}apply(compiler) {// 在资源输出之前触发compiler.hooks.emit.tap("BannerWebpackPlugin", (compilation) => {// debugger;const extensions = ["css", "js"];// 1. 获取即将输出的资源文件:compilation.assets// 2. 过滤只保留js和css资源const assets = Object.keys(compilation.assets).filter((assetPath) => {// 将文件名切割 ['xxxx', 'js'] ['xxxx', 'css']const splitted = assetPath.split(".");// 获取最后一个文件扩展名const extension = splitted[splitted.length - 1];// 判断是否保护return extensions.includes(extension);});const prefix = `/*
* Author: ${this.options.author}
*/
`;// 3. 遍历剩下资源添加上注释// console.log(assets);assets.forEach((asset) => {// 获取原来内容const source = compilation.assets[asset].source();// 拼接上注释const content = prefix + source;// 修改资源compilation.assets[asset] = {// 最终资源输出时,调用source方法,source方法的返回值就是资源的具体内容source() {return content;},// 资源大小size() {return content.length;},};});});}
}module.exports = BannerWebpackPlugin;

3、CleanWebpackPlugin

class CleanWebpackPlugin {apply(compiler) {// 2. 获取打包输出的目录const outputPath = compiler.options.output.path;const fs = compiler.outputFileSystem;// 1. 注册钩子:在打包输出之前 emitcompiler.hooks.emit.tap("CleanWebpackPlugin", (compilation) => {// 3. 通过fs删除打包输出的目录下的所有文件this.removeFiles(fs, outputPath);});}removeFiles(fs, filepath) {// 想要删除打包输出目录下所有资源,需要先将目录下的资源删除,才能删除这个目录// 1. 读取当前目录下所有资源const files = fs.readdirSync(filepath);// console.log(files); // [ 'images', 'index.html', 'js' ]// 2. 遍历一个个删除files.forEach((file) => {// 2.1 遍历所有文件,判断是文件夹还是文件const path = `${filepath}/${file}`;const fileStat = fs.statSync(path);// console.log(fileStat);if (fileStat.isDirectory()) {// 2.2 是文件夹,就得删除下面所有文件,才能删除文件夹this.removeFiles(fs, path);} else {// 2.3 是文件,直接删除fs.unlinkSync(path);}});}
}module.exports = CleanWebpackPlugin;

4、AnalyzeWebpackPlugin

class AnalyzeWebpackPlugin {apply(compiler) {compiler.hooks.emit.tap("AnalyzeWebpackPlugin", (compilation) => {// 1. 遍历所有即将输出文件,得到其大小/*将对象变成一个二维数组:对象:{key1: value1,key2: value2 }二维数组:[[key1, value1],[key2, value2]]*/const assets = Object.entries(compilation.assets);/*md中表格语法:| 资源名称 | 资源大小 || --- | --- || xxx.js | 10kb |*/let content = `| 资源名称 | 资源大小 |
| --- | --- |`;assets.forEach(([filename, file]) => {content += `\n| ${filename} | ${Math.ceil(file.size() / 1024)}kb |`;});// 2. 生成一个md文件compilation.assets["analyze.md"] = {source() {return content;},size() {return content.length;},};});}
}module.exports = AnalyzeWebpackPlugin;

生成md文件

5、InlineChunkWebpackPlugin

 让 小的js 文件直接内联到 html中

const HtmlWebpackPlugin = require("safe-require")("html-webpack-plugin");class InlineChunkWebpackPlugin {constructor(tests) {this.tests = tests;}apply(compiler) {compiler.hooks.compilation.tap("InlineChunkWebpackPlugin", (compilation) => {// 1. 获取html-webpack-plugin的hooksconst hooks = HtmlWebpackPlugin.getHooks(compilation);// 2. 注册 html-webpack-plugin的hooks -> alterAssetTagGroupshooks.alterAssetTagGroups.tap("InlineChunkWebpackPlugin", (assets) => {// 3. 从里面将script的runtime文件,变成inline scriptassets.headTags = this.getInlineChunk(assets.headTags, compilation.assets);assets.bodyTags = this.getInlineChunk(assets.bodyTags, compilation.assets);});// 删除runtime文件hooks.afterEmit.tap("InlineChunkWebpackPlugin", () => {// 3. 从里面将script的runtime文件,变成inline scriptObject.keys(compilation.assets).forEach((filepath) => {if (this.tests.some((test) => test.test(filepath))) {delete compilation.assets[filepath];}});});});}getInlineChunk(tags, assets) {/*目前:[{tagName: 'script',voidTag: false,meta: { plugin: 'html-webpack-plugin' },attributes: { defer: true, type: undefined, src: 'js/runtime~main.js.js' }},]修改为:[{tagName: 'script',innerHTML: runtime文件的内容closeTag: true },]*/return tags.map((tag) => {if (tag.tagName !== "script") return tag;// 获取文件资源路径const filepath = tag.attributes.src;if (!filepath) return tag;if (!this.tests.some((test) => test.test(filepath))) return tag;return {tagName: "script",innerHTML: assets[filepath].source(),closeTag: true,};});}
}module.exports = InlineChunkWebpackPlugin;

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

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

相关文章

灵活运用Vue 3中的setup函数—深入解析Composition API

新建项目,项目主入口为App.vue(主组件),新建child.vue(子组件)。 1.1 setup 执行 时机问题 1.在主组件里引入子组件和ref: import {ref} from vue import child from ./components/child.vue2…

HTML实现简易计算器

随便写的&#xff0c;可能有bug&#xff0c;可以在评论区指出哈。 HTML代码&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>AI简易计算器</title> </head> <body> <table id"c…

【小黑送书—第九期】>>重磅!这本30w人都在看的Python数据分析畅销书:更新了!

想学习python进行数据分析&#xff0c;这本《利用python进行数据分析》是绕不开的一本书。目前该书根据Python3.10已经更新到第三版。 Python 语言极具吸引力。自从 1991 年诞生以来&#xff0c;Python 如今已经成为最受欢迎的解释型编程语言。 pandas 诞生于2008年。它是由韦…

Mysql中自增主键是如何工作的

自增主键的特点是当表中每新增一条记录时&#xff0c;主键值会根据自增步长自动叠加&#xff0c;通常会将自增步长设置1&#xff0c;也就是说自增主键值是连续的。那么MySQL自增主键值一定会连续吗&#xff1f;今天这篇文章就来说说这个问题&#xff0c;看看什么情况下自增主键…

postman设置接口关联这样做,薪资直接涨3k

postman设置接口关联 在实际的接口测试中&#xff0c;后一个接口经常需要用到前一个接口返回的结果&#xff0c; 从而让后一个接口能正常执行&#xff0c;这个过程的实现称为关联。 在postman中实现关联操作的步骤如下&#xff1a; 1、利用postman获取上一个接口指定的返回值…

kubernetes资源管理

kubernetes资源管理 文章目录 kubernetes资源管理1.资源管理介绍2.YAML语言介绍3.资源管理方式3.1 命令式对象管理3.2 命令式对象配置3.3 声明式对象配置扩展&#xff1a;kubectl在node节点上运行 1.资源管理介绍 在kubernetes中&#xff0c;所有的内容都抽象为资源&#xff0…

c语言编程(模考3)统计字符串中数字字符的个数

统计字符串中数字字符的个数 #include<stdio.h> int main(){char inputString[100];int digitCount 0;printf("请输入一个字符串&#xff1a;");scanf("%s",inputString);for(int i0;inputString[i]!\0;i){if (inputString[i]>0&&inpu…

jQuery的学习(一篇文章齐全)

目录 Day29 jQuery 1、jQuery介绍 2、jQuery的选择器 2.1、直接查找 2.2、导航查找 3、jQuery的绑定事件 案例1&#xff1a;绑定取消事件 案例2&#xff1a;模拟事件触发 4、jQuery的操作标签 tab切换案例jQuery版本&#xff1a; 案例1&#xff1a; 案例2&#xff…

Thread的常用方法

一&#xff0c;常用方法 二&#xff0c;案例 父类&#xff1a; package ThreadLianXi;import ThreadLianXi.ZhiLeiA;public class Name {public static void main(String[] args)throws Exception{Thread t1 new ZhiLeiA("1号");//修改名字t1.setName("1号&quo…

中国最常用的制作报表的软件有哪些?

​随着信息化时代的浪潮席卷而来&#xff0c;报表制作软件已经成为了企业管理中的得力助手。在中国的大地上&#xff0c;有许多优秀的报表制作软件&#xff0c;而本文将为您揭示五位佼佼者&#xff0c;其中更以VeryReport报表软件为首选。 编辑搜图 请点击输入图片描述&#x…

华为昇腾开发板共享Windows网络上网的方法

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> 具体参考文章&#xff1a;linux(内网&#xff09;通过window 上网。具体是两步&#xff1a;一是在windows上设置internet连接共享。二是打开Atlas 200I D…

【性能测试学习】2023最有效的7大性能测试技术(建议收藏)

进入互联网时代&#xff0c;性能测试显得越来越重要&#xff0c;移动应用、web应用和物联网应用都需要进行性能测试和性能调优&#xff0c;而进行性能和负载测试会产生了大量的数据&#xff0c;这些数据难以分析。除了数据分析&#xff0c;我们还会遇到其它一些困难和挑战。 今…

win10 eclipse安装教程

前言&#xff1a;安装eclipse之前必须安装JDK&#xff0c;JDK是编译环境&#xff0c;eclipse是集成开发平台。 一、JDK的安装 Java Development Kit 简称 JDK (一). 官方下载地址&#xff1a; Java Archive Downloads - Java SE 8u211 and later (oracle.com) 找到&#xf…

2020年计网408

第33题 下图描述的协议要素是&#xff08; &#xff09;。I. 语法 II. 语义 III. 时序 A. 仅 I B. 仅 II C. 仅 III D. I、II 和 III 本题考察网络协议三要素的相关知识。 网络协议的三要素分别是语法、语义、同步&#xff08;时序&#xff09;。语法&#xff1a;定义收发双…

10月起个税系统升级,3个月个税零申报将收到提示

近日&#xff0c;自然人电子税务局扣缴端升级了&#xff0c;升级后对于工资薪金收入连续三个月为零的纳税人&#xff0c;系统会自动出现以下提示。这个提示主要为了避免企业长期对已经离职的员工进行零申报&#xff0c;导致数据不准确和资源浪费。HR在申报个税时&#xff0c;一…

OSG文字-渐变文字(4)

渐变文字(osgText::FadeText类)继承自osgText::Text类继承关系图如图9-6所示 图9-6 osgText::FadeText的继承关系图 从继承关系图中可以看出&#xff0c;它继承自osgText::Text类&#xff0c;因此&#xff0c;它具备一般文字属性的设置方法这里不再重复说明。创建渐变文字与一般…

​软考-高级-系统架构设计师教程(清华第2版)【第14章 云原生架构设计理论与实践(P496~526)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第14章 云原生架构设计理论与实践&#xff08;P496~526&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

[点云分割] 区域增长分割

效果&#xff1a; 原始数据 分割结果 代码&#xff1a; #include <iostream> #include <vector> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> // 各种点云数据类型 #include <pcl/search/search.h> #include <pcl/search/kdtr…

《C++ Primer》第9章 顺序容器(一)

参考资料&#xff1a; 《C Primer》第5版《C Primer 习题集》第5版 C 中的容器可以分为 3 类&#xff1a;顺序容器、关联容器、无序关联容器。 9.1 顺序容器概述&#xff08;P292&#xff09; 所有顺序容器都提供了快速顺序访问的能力&#xff0c;但在以下方面的性能有所不…

【考研】数据结构(更新到双链表)

声明&#xff1a;所有代码都可以运行&#xff0c;可以直接粘贴运行&#xff08;只有库函数没有声明&#xff09; 线性表的定义和基本操作 基本操作 定义 静态&#xff1a; #include<stdio.h> #include<stdlib.h>#define MaxSize 10//静态 typedef struct{int d…