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

Vite 插件开发实战:打造属于你的构建工具

一、为什么要学 Vite 插件开发在使用 Vite 的过程中你可能会遇到这些场景需要在构建时自动生成某些文件想要自定义模块解析逻辑需要在开发服务器中添加特定的 API 路由想要集成特定的代码检查或转换工具Vite 插件就是解决这些问题的钥匙Vite 插件 vs Rollup 插件Vite 的插件系统基于 Rollup但做了大量扩展特性Rollup 插件Vite 插件构建阶段✅ 支持✅ 支持开发服务器❌ 不支持✅ 支持HMR 热更新❌ 不支持✅ 支持配置解析❌ 不支持✅ 支持二、插件基础Hello WorldVite 插件本质上是一个对象或返回对象的函数包含name属性和各种钩子函数2.1 最简单的插件// my-first-plugin.js export default function myFirstPlugin() { return { name: my-first-plugin, // 配置解析时调用 config(config, { command }) { console.log( Vite 模式, command); // serve 或 build return { // 可以返回部分配置会与用户配置合并 base: command build ? /app/ : / }; }, // 构建开始时调用 buildStart() { console.log( 开始构建...); }, // 构建结束时调用 buildEnd() { console.log(✅ 构建完成); } }; }使用插件// vite.config.js import { defineConfig } from vite; import myFirstPlugin from ./my-first-plugin.js; export default defineConfig({ plugins: [myFirstPlugin()] });2.2 运行效果$ npm run dev Vite 模式 serve 开始构建... ✅ 构建完成 VITE v5.0.0 ready in 320 ms三、核心钩子详解Vite 提供了丰富的钩子函数覆盖了从配置解析到构建完成的整个生命周期。3.1 配置相关钩子export default function configPlugin() { return { name: config-plugin, // 1. config - 修改或扩展配置 config(userConfig, { command, mode }) { // command: serve | build // mode: development | production | 自定义 return { resolve: { alias: { : /src } } }; }, // 2. configResolved - 配置解析完成后 configResolved(resolvedConfig) { // 可以获取最终解析后的配置 console.log( 项目根目录, resolvedConfig.root); console.log( 运行模式, resolvedConfig.mode); } }; }3.2 开发服务器钩子这是 Vite 独有的Rollup 插件无法使用export default function serverPlugin() { return { name: server-plugin, // 配置开发服务器 configureServer(server) { // server 是 ViteDevServer 实例 // 添加自定义路由 server.middlewares.use(/api/health, (req, res, next) { res.end(JSON.stringify({ status: ok, time: Date.now() })); }); // 监听文件变化 server.watcher.on(change, (file) { console.log( 文件变化, file); }); }, // 配置预览服务器vite preview configurePreviewServer(server) { server.middlewares.use(/api/version, (req, res) { res.end(JSON.stringify({ version: 1.0.0 })); }); } }; }3.3 构建钩子Rollup 兼容export default function buildPlugin() { return { name: build-plugin, // 解析模块ID resolveId(source, importer) { if (source virtual-module) { return source; // 返回解析后的ID } }, // 加载模块内容 load(id) { if (id virtual-module) { return export const msg Hello from virtual module!; } }, // 转换代码 transform(code, id) { // 只对 .js 文件进行处理 if (id.endsWith(.js)) { // 简单的代码转换示例 return { code: code.replace(/console\\.log/g, console.debug), map: null // 可以返回 source map }; } } }; }3.4 完整生命周期图config → configResolved → configureServer ↓ (开发服务器运行中) ↓ buildStart → resolveId → load → transform ↓ (HMR 触发时重复) ↓ buildEnd → closeBundle四、实战案例案例 1自动生成环境信息文件开发中经常需要知道当前构建的时间、版本号等信息// plugins/build-info-plugin.js import { writeFileSync } from fs; import { resolve } from path; export default function buildInfoPlugin() { return { name: build-info, buildStart() { const info { version: process.env.npm_package_version || 1.0.0, buildTime: new Date().toISOString(), nodeEnv: process.env.NODE_ENV, platform: process.platform }; // 将信息写入 JSON 文件 const outputPath resolve(process.cwd(), public, build-info.json); writeFileSync(outputPath, JSON.stringify(info, null, 2)); console.log( 构建信息已生成); } }; }使用// vite.config.js import buildInfoPlugin from ./plugins/build-info-plugin.js; export default { plugins: [buildInfoPlugin()] };前端获取// App.vue 或任意 JS 文件 fetch(/build-info.json) .then(r r.json()) .then(info { console.log( 版本, info.version); console.log( 构建时间, info.buildTime); });案例 2Mock API 服务器开发时常用的 Mock 数据插件// plugins/mock-plugin.js import { readFileSync } from fs; import { resolve } from path; const mockData { /api/users: [ { id: 1, name: 张三, role: admin }, { id: 2, name: 李四, role: user } ], /api/posts: [ { id: 1, title: Hello Vite, content: Vite 真快 } ] }; export default function mockPlugin(options {}) { const { prefix /api, delay 500 } options; return { name: mock-server, configureServer(server) { server.middlewares.use((req, res, next) { // 只处理 API 请求 if (!req.url.startsWith(prefix)) { return next(); } // 模拟网络延迟 setTimeout(() { const data mockData[req.url]; if (data) { res.setHeader(Content-Type, application/json); res.end(JSON.stringify({ code: 0, data })); } else { res.statusCode 404; res.end(JSON.stringify({ code: 404, msg: Not Found })); } }, delay); }); } }; }使用// vite.config.js import mockPlugin from ./plugins/mock-plugin.js; export default { plugins: [ mockPlugin({ prefix: /api, delay: 300 // 模拟 300ms 延迟 }) ] };案例 3条件编译类似 #ifdef实现类似 C 语言的条件编译功能// plugins/conditional-compile-plugin.js export default function conditionalCompilePlugin(options {}) { const { env {} } options; return { name: conditional-compile, transform(code, id) { // 只对 JS/TS/Vue 文件处理 if (!/\\.(js|ts|vue)$/.test(id)) return; // 匹配 //#ifdef KEY ... //#endif const regex /\\/\\/\\s*#ifdef\\s(\\w)\\s*([\\s\\S]*?)\\/\\/\\s*#endif/g; return { code: code.replace(regex, (match, key, content) { // 如果环境变量存在且为真保留内容否则删除 return env[key] ? content : ; }), map: null }; } }; }使用// vite.config.js import conditionalCompile from ./plugins/conditional-compile-plugin.js; export default { plugins: [ conditionalCompile({ env: { DEBUG: process.env.NODE_ENV development, PRO_FEATURE: false } }) ] };源代码中function initApp() { //#ifdef DEBUG console.log(调试模式启动); console.log(配置信息, config); //#endif //#ifdef PRO_FEATURE loadProModules(); //#endif startApp(); }构建后DEBUGtrue, PRO_FEATUREfalsefunction initApp() { console.log(调试模式启动); console.log(配置信息, config); startApp(); }五、进阶技巧5.1 虚拟模块创建不对应真实文件的模块// plugins/virtual-module-plugin.js const virtualModuleId virtual:app-config; const resolvedVirtualModuleId \\0 virtualModuleId; export default function virtualModulePlugin() { return { name: virtual-module, resolveId(id) { if (id virtualModuleId) { return resolvedVirtualModuleId; } }, load(id) { if (id resolvedVirtualModuleId) { return export const appName My Awesome App; export const version ${process.env.npm_package_version}; export const features { darkMode: true, i18n: true }; ; } } }; }使用import { appName, version, features } from virtual:app-config; console.log(appName); // My Awesome App5.2 HMR 热更新支持让插件支持热更新export default function hmrPlugin() { return { name: hmr-plugin, handleHotUpdate({ server, modules, timestamp }) { // 自定义 HMR 处理逻辑 // 过滤特定模块 const filtered modules.filter(m !m.id.includes(node_modules)); console.log( 热更新模块, filtered.map(m m.id)); // 返回模块列表Vite 会继续处理 return filtered; } }; }5.3 插件排序控制插件执行顺序export default { plugins: [ { ...myPlugin(), enforce: pre // pre | post默认 normal } ] };六、发布你的插件6.1 插件项目结构vite-plugin-awesome/ ├── src/ │ └── index.js # 插件入口 ├── package.json ├── README.md └── LICENSE6.2 package.json 配置{ name: vite-plugin-awesome, version: 1.0.0, description: An awesome Vite plugin, main: dist/index.js, module: dist/index.mjs, types: dist/index.d.ts, files: [dist], scripts: { build: rollup -c, prepublishOnly: npm run build }, peerDependencies: { vite: ^4.0.0 || ^5.0.0 }, keywords: [vite, plugin, vite-plugin], license: MIT } 6.3 发布到 npm6.3 发布到 npmnpm login npm publish七、常用插件推荐插件功能vitejs/plugin-vueVue 单文件组件支持vitejs/plugin-reactReact Fast Refreshvite-plugin-pwaPWA 支持unplugin-auto-import自动导入 APIvite-plugin-svg-iconsSVG 图标雪碧图vite-plugin-mockMock 数据服务八、总结Vite 插件开发并不复杂核心要点✅必须掌握插件基本结构name hooks常用钩子config、transform、configureServer虚拟模块的使用✅进阶技能HMR 热更新处理开发服务器中间件构建流程控制✅最佳实践插件选项设计要灵活提供详细的文档和示例处理好错误边界

相关文章:

Vite 插件开发实战:打造属于你的构建工具

一、为什么要学 Vite 插件开发?在使用 Vite 的过程中,你可能会遇到这些场景:需要在构建时自动生成某些文件想要自定义模块解析逻辑需要在开发服务器中添加特定的 API 路由想要集成特定的代码检查或转换工具Vite 插件就是解决这些问题的钥匙&a…...

从Jupyter到VSCode:我的Julia数据分析环境搭建踩坑全记录

从Jupyter到VSCode:Julia数据分析环境迁移实战指南 当数据分析项目从简单的探索性阶段进入复杂建模时,许多研究者都会面临工具升级的挑战。作为一名长期使用Jupyter Notebook进行快速原型开发的用户,我最近在一个人口统计预测项目中深刻体会到…...

手把手教你用Simulink Counter模块实现0-15循环计数(含复位与触发配置详解)

深入掌握Simulink Counter模块:从基础配置到高级触发技巧 在工程仿真和数字系统设计中,计数器是最基础也最关键的组件之一。Simulink作为业界领先的建模与仿真平台,提供了高度优化的Counter模块,能够满足从简单计数到复杂触发逻辑…...

Steam成就管理神器:5分钟快速上手SAM完整指南

Steam成就管理神器:5分钟快速上手SAM完整指南 【免费下载链接】SteamAchievementManager A manager for game achievements in Steam. 项目地址: https://gitcode.com/gh_mirrors/st/SteamAchievementManager 你是否曾经因为游戏bug而无法解锁本该获得的成就…...

2000-2024年 地级市新型数字基础设施水平数据(+代码+文献)

01、数据简介 新型数字基础设施以“新基建”为基石,借助信创云与四中台搭建城市级数字底座,为城市提供便捷数字化服务,有力推动城市全领域数字化转型,其建设水平对经济社会发展意义重大,因而受到地方政府的高度关注。…...

ZYNQ PS端Cache一致性的实战解析与优化策略

1. ZYNQ PS端Cache一致性问题的本质 第一次在ZYNQ上做双核通信时,我遇到了一个诡异的现象:CPU0明明已经更新了共享内存的数据,但CPU1读取到的却总是旧值。这种"见鬼"的问题折腾了我整整两天,最后发现元凶竟是Cache一致性…...

Intv_AI_MK11 Visio图表智能生成:根据文本描述自动创建系统架构图

Intv_AI_MK11 Visio图表智能生成:根据文本描述自动创建系统架构图 1. 效果惊艳开场 想象一下,你正在会议室里讨论系统架构设计。突然有人问:"能不能把刚才说的架构画出来?"传统方式可能需要花半小时在Visio上手动绘制…...

别再乱选颜色了!用Seaborn的color_palette()函数,5分钟搞定数据可视化配色

别再乱选颜色了!用Seaborn的color_palette()函数,5分钟搞定数据可视化配色 上周帮同事Review代码时,看到他用Matplotlib画了这样一张柱状图:12个分类变量用了完全随机的RGB颜色,荧光粉配亮绿,还加了3D阴影效…...

HoRain云--ASP 变量

🎬 HoRain云小助手:个人主页 🔥 个人专栏: 《Linux 系列教程》《c语言教程》 ⛺️生活的理想,就是为了理想的生活! ⛳️ 推荐 前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!…...

2026 年企业数字化新基座:深度解析 ECShopX 与 ONEX OMS 开源生态

站在 2026 年的数字化分水岭,全球商业环境的不确定性迫使企业重新审视其技术基础设施的底层逻辑。过去,企业往往依赖闭源的商业软件或零散的代码片段来构建业务系统,但在数据安全、业务敏捷性和长期成本控制的多重压力下,“自主可…...

Ubuntu24.04 一站式部署 LightRAG:Miniconda 虚拟环境 + VLLM 全本地推理(LLM / 嵌入模型)保姆级教程|含全套避坑指南

前言 LightRAG 作为轻量级、高性能的 RAG 框架,在本地私有化部署场景中极具优势!本文基于Ubuntu24.04,通过Miniconda 虚拟环境隔离依赖,全程使用VLLM 作为统一推理引擎部署 LLM 大模型 + 嵌入(向量)模型,手把手完成 LightRAG 本地部署 + WebUI 可视化界面搭建。 本文会…...

ESXi 虚拟机与 QNAP NAS Virtualization Station 部署 Ubuntu 并安装 OpenClaw 完整指南

发布日期: 2026-04-13 标签: [OpenClaw, Ubuntu, ESXi, QNAP, NAS, 虚拟机, AI助手, 部署指南] 分类: [技术实践] 提要: 本文详细介绍了在ESXi虚拟机和QNAP NAS Virtualization Station上部署Ubuntu 24.04并完整安装配置OpenClaw AI助手平台的完整步骤。涵盖硬件要求、系统安装…...

Granite TimeSeries FlowState R1实战:基于SpringBoot的金融时序数据预测微服务

Granite TimeSeries FlowState R1实战:基于SpringBoot的金融时序数据预测微服务 最近和几个做金融科技的朋友聊天,他们都在头疼同一个问题:面对海量的股票价格、交易量这些时序数据,怎么才能快速、准确地预测未来几天的走势&…...

VMware虚拟机中体验PyTorch:Ubuntu系统安装与GPU穿透配置指南

VMware虚拟机中体验PyTorch:Ubuntu系统安装与GPU穿透配置指南 1. 前言:为什么选择虚拟机学习PyTorch 对于刚接触深度学习的开发者来说,直接在物理机上安装PyTorch环境可能会遇到各种依赖冲突和配置问题。使用虚拟机可以创建一个隔离的学习环…...

EVA-01效果展示:Qwen2.5-VL-7B解析分层PSD设计稿,输出图层语义与修改建议

EVA-01效果展示:Qwen2.5-VL-7B解析分层PSD设计稿,输出图层语义与修改建议 1. 引言:当视觉大模型遇上设计稿 想象一下这个场景:你收到一个复杂的PSD设计稿,里面有几十个图层,每个图层叫什么名字的都有——…...

Ostrakon-VL 多风格图像描述效果PK:写实、诗歌与营销文案

Ostrakon-VL 多风格图像描述效果PK:写实、诗歌与营销文案 1. 开场:AI也能玩转多风格图像描述 想象一下,当你看到一张美丽的风景照片时,AI不仅能告诉你画面里有什么,还能用写实报告、古典诗歌或电商文案三种完全不同的…...

Stable Yogi Leather-Dress-Collection 性能调优指南:Linux环境下GPU显存与算力监控

Stable Yogi Leather-Dress-Collection 性能调优指南:Linux环境下GPU显存与算力监控 你是不是也遇到过这种情况?兴致勃勃地部署了Stable Yogi模型,准备大展身手生成一批皮革裙装设计图,结果刚跑起来,程序就卡住了&…...

Python的__complex__中的兼容库第三方

Python的__complex__兼容库探秘 在Python中,复数类型通过内置的complex类实现,但某些特殊场景下,开发者可能需要更灵活的复数操作或兼容性支持。这时,第三方兼容库便成为重要工具。它们不仅扩展了Python原生的复数功能&#xff0…...

SOONet开源大模型部署:支持Kubernetes编排,水平扩展视频处理吞吐

SOONet开源大模型部署:支持Kubernetes编排,水平扩展视频处理吞吐 1. 项目概述 SOONet是一个基于自然语言输入的长视频时序片段定位系统,它能够通过一次网络前向计算就精确定位视频中的相关片段。想象一下,你有一个小时的视频&am…...

基于Halcon与快速傅里叶变换的周期性纹理分离实战

1. 工业视觉检测中的周期性纹理难题 在布匹、金属板材等工业产品的表面检测中,周期性纹理就像一把双刃剑。一方面它是产品工艺特征的体现,另一方面又会掩盖真正的缺陷。我去年参与过一个金属盖板检测项目,客户提供的样品表面有规律的拉丝纹理…...

茉莉花插件终极指南:5分钟掌握Zotero中文文献管理

茉莉花插件终极指南:5分钟掌握Zotero中文文献管理 【免费下载链接】jasminum A Zotero add-on to retrive CNKI meta data. 一个简单的Zotero 插件,用于识别中文元数据 项目地址: https://gitcode.com/gh_mirrors/ja/jasminum 茉莉花(Jasminum)插…...

项目介绍 MATLAB实现基于ResidualTrend-Transformer 线性残差趋势模型(ResidualTrend)结合 Transformer 编码器进行多变量时间序列预测的详细项目实例

MATLAB实现基于ResidualTrend-Transformer 线性残差趋势模型(ResidualTrend)结合 Transformer 编码器进行多变量时间序列预测的详细项目实例 更多详细内容可直接联系博主本人 加v 我的昵称(nantangyuxi) 或者访问对应标题的完整博…...

Wan2.2-I2V-A14B部署教程:Windows WSL2环境下运行RTX 4090D镜像方案

Wan2.2-I2V-A14B部署教程:Windows WSL2环境下运行RTX 4090D镜像方案 1. 环境准备与快速部署 在开始之前,请确保你的Windows系统满足以下硬件要求: 显卡:RTX 4090D 24GB显存CPU:10核或更高内存:120GB或更…...

CHORD-X模型解析:从LSTM到Transformer的时序建模演进

CHORD-X模型解析:从LSTM到Transformer的时序建模演进 最近在分析一个视频理解项目时,我反复听到一个词:CHORD-X。这其实是一个挺有意思的系统,它专门用来理解视频里发生了什么,比如识别战术动作、分析球员跑位&#x…...

我在选域名服务时,慢慢开始关注这3个点

在前面几篇里,我更多是在整理域名本身的问题。但最近在实际操作的时候,发现:👉 选“在哪管理域名”,其实也挺重要的1. 一开始容易忽略的点最开始,我只是随便选了一个能用的方式。但后面才发现:&…...

互联网大厂Java求职面试实战:从Spring Boot到Kafka的技术问答解析

互联网大厂Java求职面试实战:从Spring Boot到Kafka的技术问答解析 场景背景 本次面试发生在一家互联网大厂,谢飞机作为面试者,面试官以严肃的态度针对Java全栈技术栈进行提问,涵盖从核心语言到微服务、消息队列等多领域技术。面试…...

通义灵码2.0隐藏技巧:用AI自动生成React组件文档的三种方法

通义灵码2.0隐藏技巧:用AI自动生成React组件文档的三种方法 在React项目开发中,组件文档的编写常常成为团队协作的瓶颈。传统的手动维护方式不仅耗时耗力,还容易出现文档与代码不同步的问题。通义灵码2.0作为新一代AI编程助手,其代…...

农业供应链:冷链物流与库存管理的优化

农业供应链:冷链物流与库存管理的优化 随着消费者对生鲜农产品品质要求的提高,农业供应链中的冷链物流与库存管理成为保障食品安全、减少损耗的关键环节。从田间到餐桌,如何通过技术和管理手段优化这一流程,不仅关系到企业效益&a…...

软件供应商管理中的绩效评估

软件供应商管理中的绩效评估:提升合作效能的关键 在数字化转型的浪潮中,企业越来越依赖外部软件供应商提供技术支持和解决方案。供应商的能力和服务质量直接影响企业的运营效率与成本控制。对软件供应商进行科学、系统的绩效评估,成为企业优…...

Rust高性能编程:Yi-Coder-1.5B所有权模型解析

Rust高性能编程:Yi-Coder-1.5B所有权模型解析 1. 引言 如果你刚开始学习Rust,可能会被所有权这个概念搞得有点懵。别担心,这很正常。Rust的所有权系统是它最独特的特性,也是保证内存安全的关键所在。今天我们就用Yi-Coder-1.5B这…...