当前位置: 首页 > news >正文

手写一个webpack插件(plugin)

熟悉 vue 和 react 的小伙伴们都知道,在执行过程中会有各种生命周期钩子,其实webpack也不例外,在使用webpack的时候,我们有时候需要在 webpack 构建流程中引入自定义的行为,这个时候就可以在 hooks 钩子中添加自己的方法。

创建插件

webpack 加载 webpack.config.js 中所有配置,此时 webpack 创建 compiler 对象,遍历所有 plugins 中插件,调用插件的 apply 方法,执行剩下编译流程(触发各个 hooks 事件),具体使用什么钩子和钩子是同步还是异步,请移步compiler 钩子

  1. 创建一个 JavaScript 命名函数或 JavaScript 类
  2. 在插件函数的 prototype 上定义一个 apply 方法
  3. 绑定到 webpack 自身的事件钩子上
  4. 导出这个JavaScript 命名函数或 JavaScript 类
  5. 在 webpack.config.js 文件中引入并调用方法

自定义 banner-webpack-plugin

自定义 banner-webpack-plugin 插件,该插件会在每一个打包后的 js 、css 文件第一行添加注释,先看效果图。
Snipaste_2023-05-22_21-09-41.png

  • 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,先看效果图。
Snipaste_2023-05-01_15-46-05.png

// 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(),],
};
http://www.lryc.cn/news/93329.html

相关文章:

  • jvm常见面试题
  • TF-A 项目的长期支持介绍
  • 企业电子招标采购系统源码java 版本 Spring Cloud + Spring Boot
  • 7.Mysql 事务底层
  • 15.DIY可视化-拖拽设计1天搞定主流小程序-分类联动文章列表实时刷新
  • 【SpringCloud】二、服务注册发现Eureka与负载均衡Ribbon
  • 图形学实验(完整文件见上传)
  • Spark大数据处理学习笔记(3.2.1)掌握RDD算子
  • lammps初级:石墨烯、金属材料、纳米流体、热传导、多成分体系、金属、半导体材料的辐照、自建分子力场、MOFS、H2/CO2混合气体等模拟
  • 【MarkerDown】CSDN Markdown之时序图sequenceDiagram详解
  • ReentrantLock实现原理-公平锁
  • 掌握Scala数据结构(2)MAP、TUPLE、SET
  • flutter:文件系统目录、文件读写
  • 计算机提示“找不到vcruntime140.dll,无法继续执行代码可”以这样子修复
  • 深度学习pytorch实战五:基于ResNet34迁移学习的方法图像分类篇自建花数据集图像分类(5类)超详细代码
  • Rust in Action笔记 第五章 深入理解数据
  • Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码
  • 2.4 逻辑代数的基本定理
  • 适用于 Linux 的 Windows 子系统wsl文档
  • C++特殊类的设计与类型转换
  • 如何通过关键词搜索API接口
  • 智驾域控新战争打响,谁在抢跑?
  • Android 13无源码应用去掉无资源ID的按钮
  • 【SCI征稿】中科院2区(TOP),正刊,SCIEEI双检,进化计算、模糊集和人工神经网络在数据不平衡中应用
  • Android Audio开发——AAudio基础(十五)
  • SDK接口远程调试【内网穿透】
  • Mybatis学习笔记二
  • 大屏数据可视化开源项目
  • 面试经典150题:数组/字符串合集
  • Java源文件的执行过程