手写一个webpack插件(plugin)
熟悉 vue 和 react 的小伙伴们都知道,在执行过程中会有各种生命周期钩子,其实webpack也不例外,在使用webpack的时候,我们有时候需要在 webpack 构建流程中引入自定义的行为,这个时候就可以在 hooks 钩子中添加自己的方法。
创建插件
webpack 加载 webpack.config.js 中所有配置,此时 webpack 创建 compiler 对象,遍历所有 plugins 中插件,调用插件的 apply 方法,执行剩下编译流程(触发各个 hooks 事件),具体使用什么钩子和钩子是同步还是异步,请移步compiler 钩子
- 创建一个 JavaScript 命名函数或 JavaScript 类
- 在插件函数的 prototype 上定义一个 apply 方法
- 绑定到 webpack 自身的事件钩子上
- 导出这个JavaScript 命名函数或 JavaScript 类
- 在 webpack.config.js 文件中引入并调用方法
自定义 banner-webpack-plugin
自定义 banner-webpack-plugin 插件,该插件会在每一个打包后的 js 、css 文件第一行添加注释,先看效果图。
- emit 钩子是输出 asset 到 output 目录之前执行
- 获取即将输出的资源文件:compilation.assets
- 遍历 assets,只处理js和css资源,其他文件不处理
- 通过 content = entcompilation.assets[filename].source() 获取原来内容
- 拼接上注释 content = prefix + content
- 修改资源的 source 和 size
// plugins/banner-webpack-plugin.jsclass BannerWebpackPlugin {constructor(options = {}) {this.options = options;}apply(compiler) {// 在资源输出之前触发compiler.hooks.emit.tap("BannerWebpackPlugin", (compilation) => {const extensions = ["css", "js"];const prefix = `/** Author: ${this.options.author}* Build Time: ${new Date()}*/`;// 获取即将输出的资源文件:compilation.assetsfor (const filename in compilation.assets) {if (compilation.assets.hasOwnProperty(filename)) {// 将文件名进行切割const splitted = filename.split(".");// 获取文件扩展名const extension = splitted[splitted.length - 1];// 只处理js和css资源,其他文件不处理if (extensions.includes(extension)) {const asset = compilation.assets[filename];// 获取原来内容let content = asset.source();// 拼接上注释content = prefix + content;// 修改资源compilation.assets[filename] = {// 最终资源输出时,调用source方法,source方法的返回值就是资源的具体内容source: () => content,// 资源大小size: () => content.length,};}}}});}
}
module.exports = BannerWebpackPlugin;
调用 BannerWebpackPlugin
// config/webpack.config.js// 引入插件
const BannerWebpackPlugin = require('../plugins/banner-webpack-plugin');
module.exports = {plugins: [// 调用插件new BannerWebpackPlugin({author: "小小愿望",}),],
};
自定义 take-time-webpack-plugin
自定义 take-time-webpack-plugin 插件,该插件输出 “webpack 构建正在启动!”,打包完成后输出 webpack 构建已完成!总耗时 { time } ms,先看效果图。
// plugins/take-time-webpack-plugin.js// 一个命名的 Javascript 方法 或 JavaScript 类
class TakeTimeWebpackPlugin {time = 0;// 原型上需要定义 apply 的方法apply(compiler) {// 生命周期钩子函数,是由 compiler 暴露// 通过 compiler 获取 webpack 内部的钩子,获取 Webpack 打包过程中的各个阶段compiler.hooks.environment.tap("TakeTimeWebpackPlugin", (compilation) => {console.log("\x1B[36m", "webpack 构建正在启动!");this.time = new Date().getTime();});// 通过 compiler 获取 webpack 内部的钩子,获取 Webpack 打包过程中的各个阶段compiler.hooks.afterEmit.tapAsync("TakeTimeWebpackPlugin", (compilation, callback) => {const nowTime = new Date().getTime();this.time = nowTime - this.time;const str = `webpack 构建已完成!总耗时 ${this.time} ms`console.log("\x1B[32m", str);// 分为同步和异步的钩子,异步钩子在功能完成后,必须执行对应的回调callback();});}
}
module.exports = TakeTimeWebpackPlugin;
调用 TakeTimeWebpackPlugin
在 config/webpack.config.js 文件中引入并执行 TakeTimeWebpackPlugin
// config/webpack.config.js// 引入插件
const TakeTimeWebpackPlugin = require('../plugins/take-time-webpack-plugin');
module.exports = {plugins: [// 调用插件new TakeTimeWebpackPlugin(),],
};
相关文章:
手写一个webpack插件(plugin)
熟悉 vue 和 react 的小伙伴们都知道,在执行过程中会有各种生命周期钩子,其实webpack也不例外,在使用webpack的时候,我们有时候需要在 webpack 构建流程中引入自定义的行为,这个时候就可以在 hooks 钩子中添加自己的方…...
jvm常见面试题
0x01. 内存模型以及分区,需要详细到每个区放什么。 栈区: 栈分为java虚拟机栈和本地方法栈 重点是Java虚拟机栈,它是线程私有的,生命周期与线程相同。 每个方法执行都会创建一个栈帧,用于存放局部变量表࿰…...
TF-A 项目的长期支持介绍
引流关键词:Armv8-A, Armv9-A, Cortex-A, Cortex-A12, Cortex-A15, Cortex-A17, Cortex-A32, Cortex-A34, Cortex-A35, Cortex-A5, Cortex-A510, Cortex-A53, Cortex-A55, Cortex-A57, Cortex-A65, Cortex-A65AE, Cortex-A7, Cortex-A710, Cortex-A715, Cortex-A72, Cortex-A7…...
企业电子招标采购系统源码java 版本 Spring Cloud + Spring Boot
项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及…...
7.Mysql 事务底层
一、事务的基础知识 mysql中的事务 分为 显式事务 和 隐式事务。 1.1 显式事务 显式事务就是我们手动开启事务,并且提交事务比如: -- 开启事务 begin; -- 执行查询语句 select *from where id = 1 for update ; -- 提交事务 commit;1.2 隐式事务 在 MySQL 中,隐式事务是…...
15.DIY可视化-拖拽设计1天搞定主流小程序-分类联动文章列表实时刷新
分类联动文章列表实时刷新 本教程均在第一节中项目启动下操作 分类联动文章列表实时刷新前言需求一:功能实现:点击首页分类,对应分类内容显示到当前页一、清空原分类界面:二. 设置选项卡三:设定展示内容字段:1.跨页面复制:文章分类组件到分类![在这里插入图片描述](https://img…...
【SpringCloud】二、服务注册发现Eureka与负载均衡Ribbon
文章目录 一、Eureka1、服务提供者与消费者2、Eureka原理分析3、搭建Eureka4、服务注册5、模拟多服务实例启动6、服务的发现 二、Ribbon1、负载均衡的原理2、源码分析3、负载均衡策略4、饥饿加载 一、Eureka 1、服务提供者与消费者 服务提供者:一次业务中…...
图形学实验(完整文件见上传)
CRect rect; this->GetClientRect(rect); pDC->Ellipse(rect); // DDALineView.cpp : implementation of the CDDALineView class // #include “stdafx.h” #include “DDALine.h” #include “DDALineDoc.h” #include “DDALineView.h” #ifdef _DEBUG #define new…...
Spark大数据处理学习笔记(3.2.1)掌握RDD算子
该文章主要为完成实训任务,详细实现过程及结果见【http://t.csdn.cn/FArNP】 文章目录 一、准备工作1.1 准备文件1. 准备本地系统文件2. 把文件上传到 1.2 启动Spark Shell1. 启动HDFS服务2. 启动Spark服务3. 启动Spark Shell 二、掌握转换算子2.1 映射算子 - map()…...
lammps初级:石墨烯、金属材料、纳米流体、热传导、多成分体系、金属、半导体材料的辐照、自建分子力场、MOFS、H2/CO2混合气体等模拟
1 LAMMPS的基础入门——初识LAMMPS是什么?能干什么?怎么用? 1.1 LAMMPS在win10和ubuntu系统的安装及使用 1.2 in文件结构格式 1.3 in文件基本语法:结合实例,讲解in文件常用命令 1.4 data文件格式 1.5 LAMMPS常见错误解…...
【MarkerDown】CSDN Markdown之时序图sequenceDiagram详解
CSDN Markdown之时序图sequenceDiagram详解 序列图 sequenceDiagram参与者与组参与者 participant拟人符号 actor别名 as组 box 消息(连线)激活/失活 activate/deactivate备注 Note循环 loop备选 Alt并行 par临界区 critical中断 break背景高亮 rect注释 %%转义字符的实体代码序…...
ReentrantLock实现原理-公平锁
在ReentrantLock实现原理(1)一节中,我们了解了ReentrantLock非公平锁的获取流程,在本节中我们来看下ReentrantLock公平锁的创建以及锁管理流程 创建ReentrantLock公平锁 创建公平锁代码如下: ReentrantLock reentrantLock new ReentrantL…...
掌握Scala数据结构(2)MAP、TUPLE、SET
一、映射 (Map) (一)不可变映射 1、创建不可变映射 创建不可变映射mp,用键->值的形式 创建不可变映射mp,用(键, 值)的形式 注意:Map是特质(Scala里的trait,相当于Java里的interface&#…...
flutter:文件系统目录、文件读写
参考 参考:老孟 文件存储和网络请求 数据存储 Dart的 IO 库包含了文件读写的相关类,它属于 Dart 语法标准的一部分,所以通过 Dart IO 库,无论是 Dart VM 下的脚本还是 Flutter,都是通过 Dart IO 库来操作文件的。但…...
计算机提示“找不到vcruntime140.dll,无法继续执行代码可”以这样子修复
首先,对于那些不熟悉的人来说,vcruntime140.dll是一个关键文件,用于在Windows操作系统上运行使用C语言编写的大型应用程序。如果你正在运行或安装这样的应用程序,但找不到vcruntime140.dll文件,那么你的应用程序可能无…...
深度学习pytorch实战五:基于ResNet34迁移学习的方法图像分类篇自建花数据集图像分类(5类)超详细代码
1.数据集简介 2.模型相关知识 3.split_data.py——训练集与测试集划分 4.model.py——定义ResNet34网络模型 5.train.py——加载数据集并训练,训练集计算损失值loss,测试集计算accuracy,保存训练好的网络参数 6.predict.py——利用训练好的网…...
Rust in Action笔记 第五章 深入理解数据
如果希望看到f32类型的数转换成整型数字u32类型,需要在unsafe包裹下调用std::mem::transmute(data),因为在安全的Rust语法中没有把整型数据按照bit转换成浮点数据的实现,如果想要看到浮点数的二进制输出(通过{:b})&…...
Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码
Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码 最近在学习Cocos Creator,作为新手,刚刚开始学习Cocos Creator,刚刚入门,这里记录一下飞机大战小游戏实现。 https://wxaurl.cn/VEgRy2eTMyi 一 安装CocosDashBo…...
2.4 逻辑代数的基本定理
学习目标: 如果我要学习逻辑代数的基本定理,我会采取以下步骤: 1. 学习基本概念:首先,我会花时间了解逻辑代数的基本概念,如逻辑运算符(合取、析取、否定等)、真值表、逻辑等价性等…...
适用于 Linux 的 Windows 子系统wsl文档
参考链接:https://learn.microsoft.com/zh-cn/windows/wsl/ 鸟哥的Linux私房菜:http://cn.linux.vbird.org/ http://cn.linux.vbird.org/linux_basic/linux_basic.php http://cn.linux.vbird.org/linux_server/ 目录 安装列出可用的 Linux 发行版列出已…...
C++特殊类的设计与类型转换
特殊类的设计与类型转换 特殊类的设计请设计一个类,只能在堆上创建对象请设计一个类,只能在栈上创建对象请设计一个类,只能创建一个对象(单例模式) C的类型转换 特殊类的设计 请设计一个类,只能在堆上创建对象 通过new创建的类就…...
如何通过关键词搜索API接口
如果你是一位电商运营者或者是想要进行1688平台产品调研的人员,你可能需要借助API接口来获取你所需要的信息。在这篇文章中,我们将会讨论如何通过关键词搜索API接口获取1688的商品详情。 第一步:获取API接口的授权信息 在使用API接口前&…...
智驾域控新战争打响,谁在抢跑?
智能驾驶域控制器赛道,已经成为了时下最为火热的市场焦点之一。 最近,头部Tier1均胜电子公布了全球首批基于高通Snapdragon Ride第二代芯片平台的智能驾驶域控制器产品nDriveH,在这一赛道中显得格外引人注意。 就在不久之前,均胜…...
Android 13无源码应用去掉无资源ID的按钮
Android Wifionly项目,客户要求去掉谷歌联系人里的 手机联系人按钮 需求分析 无应用源码,只能通过系统侧去修改 首先通过 Android Studio 工具 uiautomatorviewer 获取父控件资源ID chip_group ,然后通过遍历获取子控件去掉目标按钮 --- a/frameworks/base/core/java/andr…...
【SCI征稿】中科院2区(TOP),正刊,SCIEEI双检,进化计算、模糊集和人工神经网络在数据不平衡中应用
【期刊简介】IF:8.0-9.0,JCR1区,中科院2区(TOP) 【检索情况】SCIE&EI 双检,正刊 【数据库收录年份】2004年 【国人占比】22.78%(期刊国际化程度高) 【征稿领域】进化计算、模…...
Android Audio开发——AAudio基础(十五)
AAudio 是一个自 Android O 引入的新的 Android C API。它主要是为需要低延迟的高性能音频应用设计的。应用程序通过直接从流中读取或向流中写入数据来与 AAudio 通信,但它只包含基本的音频输入输出能力。 一、AAudio概述 AAudio 在应用程序和 Android 设备上的音频输入输出之…...
SDK接口远程调试【内网穿透】
文章目录 1.测试环境2.本地配置3. 内网穿透3.1 下载安装cpolar内网穿透3.2 创建隧道 4. 测试公网访问5. 配置固定二级子域名5.1 保留一个二级子域名5.2 配置二级子域名 6. 使用固定二级子域名进行访问 转发自cpolar内网穿透的文章:Java支付宝沙箱环境支付࿰…...
Mybatis学习笔记二
目录 一、MyBatis的各种查询功能1.1 查询一个实体类对象1.2 查询一个List集合1.3 查询单个数据1.4 查询一条数据为map集合1.5 查询多条数据为map集合1.5.1 方法一:1.5.2 方法二: 二、特殊SQL的执行2.1 模糊查询2.2 批量删除2.3 动态设置表名2.4 添加功能…...
大屏数据可视化开源项目
一、DataGear —— 数据可视化项目 官网:DataGear - 开源免费的数据可视化分析平台 DataGear 是一款开源免费的数据可视化分析平台,数据可视化看板。 功能特性: 1、多种数据源,支持运行时接入任意提供 JDBC 驱动的数据库&#…...
面试经典150题:数组/字符串合集
新专栏,预计两个月写完吧,每天下班回来抽空做几道题。会把做题计划顺序记录下来,如果你有缘,刷到这个开篇序列,那就跟着文章去练题吧。初学者可以慢慢来 88. 合并两个有序数组 void merge(vector<int>& nums…...
电子政务网站建设ppt/金戈枸橼酸西地那非片
在很多实际项目中,有一类实际问题,就是将一些图层设置为可选和不可选,类似于地图背景是不能被选择的, 自己添加的一些图元(如GPS应用中的被监控车辆、最优化路径中的必须经过点)是可以选择和编辑的。 设置图层可不可以选择&#x…...
国内网站设计案例/google官方下载
本文系图技术在大型、复杂基础设施之中 SRE/DevOps 的实践参考,并以 OpenStack 系统之上的图数据库增强的运维案例为例,揭示图数据库、图算法在智能运维上的应用。本文所有示例代码开源。 最近,有些尚未使用过图技术、DevOps/Infra 领域的工程…...
企业网站的模块功能/青岛网站建设
打印出一个等腰三角形。 思路很容易:双重for循环处理。 难点在于如何控制等腰,让图形像个金字塔,可以想象一个矩形挖成等腰三角形 package com.math.forth;/**** 打印出一个等腰三角形。 思路很容易:双重for循环处理。 * 难点在于…...
web前端做音乐网站/网站优化排名方法有哪些
由于使用display:none来设置的隐藏,每次刷新后对应的id为filePicker的div的宽高都默认为1px,按钮当然没有反应,网上找了很多具体都说不要使用display:none,使用css样式来设置。以下语句即解决了此问题。 <style> #filePick…...
网站设计 导航条/西安网站seo诊断
Prometheus是继Kubernetes后第2个正式加入CNCF基金会的项目,容器和云原生领域事实的监控标准解决方案。在这次分享将从Prometheus的基础说起,学习和了解Prometheus强大的数据处理能力,了解如何使用Prometheus进行白盒和黑盒监控,以…...
大型网站制作流程/搜索网页内容
接着上篇《编写高效Excel VBA代码的最佳实践(一)》 尽可能少使用“.”,使用对象变量 在前面已经介绍过的对长对象引用使用对象变量以及使用With…End With等都是简化”.”的方法。因为在代码中的每个句点都表示至少一个(而且可能是多个)过程调用,而这些过…...