给 Vite 项目创建一个自定义插件

前言

Vite 是一个前端构建工具,以其极快的开发服务器启动和模块热更新(HMR)功能而广受欢迎。它提供了灵活的插件系统,允许开发者扩展其功能。本文将带你一步步了解如何为 Vite 创建一个自定义插件,帮助你在项目中实现特定需求。

什么是 Vite 插件

Vite 插件是用于扩展 Vite 功能的自定义模块。它们可以在构建过程中执行特定任务,如转换代码、注入内容、优化性能等。

插件的作用和使用场景

Vite 插件的作用包括但不限于:

  • 文件解析和转换(如支持自定义文件类型)
  • 开发服务器功能扩展(如代理、Mock 数据)
  • 构建过程优化(如压缩、代码拆分)
  • 代码注入和替换

Vite 插件系统的优点

  • 灵活性:支持各种类型的插件,从简单的转换到复杂的编译器插件。
  • 易用性:通过简单的 API 即可创建和使用插件。
  • 性能:Vite 插件系统高效且性能优越。
  • Rollup Vite 插件扩展了设计出色的 Rollup 接口 所以相当数量的 Rollup 插件将直接作为 Vite 插件工作

设置开发环境 创建项目

  • 设置node 环境 我 node 版本采用的是16.20.2
  • 创建项目 我创建的是vue3 typescript 项目
kotlin 复制代码
npm init vite@latest
cd vite-project
npm i
npm run dev

vite 插件构建过程生命周期和 rollup 有点类似 参考下面图片

  • buildStart:构建开始前调用。

  • resolveId:解析模块路径时调用。

  • load:加载模块内容时调用。

  • transform:转换模块内容时调用。

  • buildEnd:构建结束后调用。

实现一个简单的插件

主要功能包含了2个 运行过程中文件内容替换 打包完成后将打包后的产物复制到其他目录

  • 在项目根目录创建文件 vite-plugin-files-diy.ts

这里 需要注意 用到了 node:fs 文件操作 所以需要安装 @types/node

css 复制代码
npm i --save-dev @types/node

vite-plugin-files-diy.ts 代码如下

vite-plugin-files-diy.ts 复制代码
import { ResolvedConfig } from 'vite'
import { createReadStream, createWriteStream, mkdirSync, existsSync } from 'node:fs';

// 自定义插件
export default function vitePluginFilesDiy() {
    let config: any = {}
    return {
        name: 'vite-plugin-files-diy', // 必须的 插件的名称,用于在警告和错误消息中标识插件。
        version: "1.0.0", //插件的版本,用于插件间通信场景。
        //apply: 'build', // 或 'serve' apply 属性指明它们仅在 'build' 或 'serve' 模式时调用
        configResolved(resolvedConfig: ResolvedConfig ) { //Vite 独有钩子 在解析 Vite 配置后调用。使用这个钩子读取和存储最终解析的配置。当插件需要根据运行的命令做一些不同的事情时,它也很有用。
            // 存储最终解析的配置
            config = resolvedConfig
        },
        // 在其他钩子中使用存储的配置
        transform(code:string, id: string) { //code 文件内容 id 是文件路径
            if (config.command === 'serve') {
                // dev: 由开发服务器调用的插件
                if (id.indexOf('.vue')>-1) {
                    const transformedCode = code.replace(/nnm/g, 'xxxxxxx');
                    return {
                        code: transformedCode,
                        map: null,
                    };
                }
            } else {
                // build: 由 Rollup 调用的插件
            }
        },
        async writeBundle() { //要在写入文件后修改文件
            //创建 newFile文件夹
            if (!existsSync('newFile')){
              await  mkdirSync('newFile') 
            }
            // 复制文件到 newFile 目录下
           await  createReadStream('./dist/index.html').pipe(createWriteStream(`./newFile/index.html`));

        }
        
    }
}

代码讲解-文件内容替换

  1. configResolved 钩子中 把运行的配置信息存储了下来
  2. transform 钩子中 用 config.command 判断环境 然后用id.indexOf 判断文件路径后缀为.vue的文件,再用正则替换代码内容 3.然后修改 components/HelloWorld.vue 内容

最终执行效果图如下

html 内容

js 输出

代码讲解-将打包后产物dist/index.html内容复制到newFile目录下

  1. writeBundlerollup 下面的钩子 ,仅在 bundle.write() 结束时调用,一旦所有文件都已写入开始执行 writeBundle钩子。rollup执行顺序可以参考下面图片

2. 利用 existsSync 判断文件夹是否存在着,不存在则 利用 mkdirSync 创建文件夹 newFile 3. 利用 createReadStream 读取文件流 后再利用pipe机制用 createWriteStream 写入文件流

当执行打包命令 npm run build 后 执行效果如下

总结

希望这篇文章能帮助你了解如何为 Vite 创建自定义插件。在平时开发难免遇到一些奇奇怪怪的需求,希望本篇文章能给你带来一些新的灵感,特别是代码注入、替换、转换、和性能优化、文件复制等操作。

相关推荐
吃杠碰小鸡32 分钟前
lodash常用函数
前端·javascript
emoji11111142 分钟前
前端对页面数据进行缓存
开发语言·前端·javascript
泰伦闲鱼1 小时前
nestjs:GET REQUEST 缓存问题
服务器·前端·缓存·node.js·nestjs
m0_748250031 小时前
Web 第一次作业 初探html 使用VSCode工具开发
前端·html
一个处女座的程序猿O(∩_∩)O1 小时前
vue3 如何使用 mounted
前端·javascript·vue.js
m0_748235951 小时前
web复习(三)
前端
AiFlutter1 小时前
Flutter-底部分享弹窗(showModalBottomSheet)
java·前端·flutter
麦兜*1 小时前
轮播图带详情插件、uniApp插件
前端·javascript·uni-app·vue
陈大爷(有低保)1 小时前
uniapp小案例---趣味打字坤
前端·javascript·vue.js
m0_748236581 小时前
《Web 应用项目开发:从构思到上线的全过程》
服务器·前端·数据库