Vite插件开发有例有举,准能会
vite 简介
官方: Vite 是一种新型的前端构建工具, 能够显著提升前端开发体验.
Vite 是 vue 的作者尤雨溪在开发 vue3.0 的时候开发的一个 基于原生ES-Module的前端构建工具; 主要对应的场景是开发模式, 是一个基于 Vue3 单文件组件的非打包开发服务器;
优势:
快速的冷启动, 不需要等待打包操作;即时的热模块更新, 替换性能和模块数量的解耦让更新飞起;真正的按需编译, 不再等待整个应用编译完成
劣势:
生态不及webpack, 加载器、插件不够丰富打包到生产环境时, vite 使用传统的 rollup(也可以自己手动安装webpack来)进行打包项目的开发浏览器要支持 ES Module, 与 CommonJS 模块不完全兼容
Vite 在插件设计上扩展了 Rollup 的插件接口, 必要的情况下, 通过阅读 Rollup 的插件文档, Vite 插件相对会容易很多.
兼容性注意: Vite 需要 Node.js 版本 >= 12.0.0. 然而, 有些模板需要依赖更高的 Node 版本才能正常运行, 当你的包管理器发出警告时, 请注意升级你的 Node 版本.
一、插件功能简述
下面是我要开发得插件信息:
背景: 实现H5代码在手机端实现热更新, 避免全量更新, 这就是fileInfoList中每个文件hash就是是否进行文件更新的唯一依据.
名称: vite-plugin-hot-hash
功能: 输出一个filesinfo.json的文件, 该文件和manifest.json不一样, filesinfo.json最终内容包含:
lastBuildTDate: 打包构建时间fileInfoList: 打包后所有文件路径, 大小, 以及每个文件独有的hash值支持自定义输出内容二、插件开发流程1.初始化工程mkdir vite-plugin-hot-hash cd vite-plugin-hot-hash复制代码2.初始化插件package.jsonnpm init -y复制代码3.安装必要依赖npm i -D vite typescript @types/node 复制代码typescript: ts开发, 更有助于插件后续的维护@types/node: 在node中使用typescript时, 用来加载所有的类型定义.4.安装 tsup
tsup 可以快速打包 typescript 库, 无需任何配置, 并且基于esbuild进行打包, 同时也可以快速生成ts类型, 打包 ts 文件速度是 tsc 的 100 多倍.详细介绍: 官方介绍
pnpm i tsup -D复制代码
修改package.json :
“scripts”: { “dev”: “tsup src/index.ts –watch”, “build”: “tsup src/index.ts –clean –dts –format cjs,esm”}复制代码在 dev 的情况下你可以进行打包并监听文件的改变进行打包, 可快速看到效果打包出口默认是 dist 文件夹, 并且默认是符合 commonJS 的 cjs 格式–format: 参数指定即可打包出 cjs, esm, iife 格式的文件–dts:打包附带类型定义文件–clean: 打包时需要清除上一次的打包–splitting: 默认情况下打包 esm 会进行代码分割, 但是 cjs 并不默认支持, 如果需要启用 cjs 代码分割需要加上5.创建 tsconfig.json{ “compilerOptions”: { “target”: “es2015”, “moduleResolution”: “node”, “strict”: false, “declaration”: true, “noUnusedLocals”: true, “esModuleInterop”: true, “outDir”: “dist”, “module”: “commonjs”, “lib”: [“ESNext”, “DOM”], “sourceMap”:false, }, “include”: [“./src”], “exclude”: [ “node_modules”, “dist” ]}复制代码6.项目目录结构├── dist # 最终打包生成的文件├── src # 源码| ├── index.ts # 插件入口 | └── utils | └── index.ts # 工具方法 ├── tsconfig.json├── package.json复制代码7.源码入口index.tsimport type { Plugin } from ‘vite’;export function HotHash(options?: Object): Plugin { let distPath = ”; return { name: ‘vite-plugin-hot-hash’, // 插件名称 enforce: ‘pre’, // pre 会较于 post 先执行 apply: ‘build’, // 标识插件在哪个时期工作(serve|build),默认都会调用 // 插件钩子(详细的钩子后面会简单介绍) outputOptions(opts) { distPath = opts.dir; // 获取最终打包生成的文件路径 }, // 构建完毕时执行, 解析获取dist文件下所有文件 closeBundle() { const fileJsonFile = path.join(distPath, ‘filesinfo.json’); const fileInfoList = []; readFile(distPath, distPath, fileInfoList); const json = { lastBuildTDate: formatDate(new Date()), fileInfoList, …options }; const text = JSON.stringify(json); writeFileSync(fileJsonFile, text); } }}/*** @readFile 递归读取文件夹下所有文件* @param distP 打包输出的文件路径* @param dirP 需要递归的文件夹* @param fileInfoList 所有读取到的文件列表*/function readFile(distP: string, dirP: string, fileInfoList: any[]) { readdirSync(dirP).forEach(filename => { const dirPath = path.join(dirP, filename); const isDir = statSync(dirPath).isDirectory(); if (isDir) { readFile(distP, dirPath, fileInfoList) return; } const content = readFileSync(dirPath); const hash = crypto.createHash(‘sha256’); hash.update(content); const hashContent = hash.digest(‘hex’); const filePath = relative(distP, dirPath); // 绝对路径 -> 相对路径 fileInfoList.push({ path: filePath, hash: hashContent, size: content.length, }); });}function relative(from, to) { const p = path.relative(from, to).replace(/\/g, ‘/’); if (/^[\w_]/.test(p)) { return ‘./’ + p; } return p;}复制代码
完整代码 : github.com/UU-GIT/vite… ⭐️ 欢迎 star ⭐️
三、本地调试1.打包插件npm run buid// 为了方便调式, 开发时可执行: npm run dev复制代码
来看看, 生成了哪些文件
dist├── index.mjs # esm├── index.d.ts # 类型定义└── index.js # cjs复制代码2.生成软连接
在当前目录执行npm link 在全局生成一个软连接,指向当前项目
3.项目注入
在自己vite项目中 执行:
npm link vite-plugin-hot-hash复制代码
然后我们可以看到 node_modules 中出现了vite-plugin-hot-hash符号链接.
4.项目配置
在Vite项目的vite.config.js配置文件中加入插件
import HotHash from ‘vite-plugin-hot-hash’; // import 方式(二选一)// const { HotHash } = require(‘vite-plugin-hot-hash’); // require方式(二选一)const { version } = require(‘./package.json’);export default defineConfig(({ mode }) => { retrun { plugins: [ …, HotHash({ version }), … ], }})复制代码5.项目打包验证npm run build复制代码
6.取消全局链接
当我们调试结束, 就可以解除软连接了, 可以在项目根目录下执行:
npm unlink vite-plugin-hot-hash复制代码四、插件发布1.注册账号
先去npm(www.npmjs.com/)注册账号
2.终端命令, 登录npm账号npm login复制代码
3.发布npm publish复制代码
五、插件钩子简介1.通用钩子
在开发中, Vite 开发服务器会创建一个插件容器来调用 Rollup 构建钩子:
服务器启动时被调用:
optionsbuildStart
每个传入模块请求时被调用:
resolveIdloadtransform
服务器关闭时被调用:
buildEndcloseBundle
详细说明及使用情况, 可查看rollup.js 文档说明: rollupjs.org/guide/en/
2.vite 独有钩子
详细说明及使用情况,可查看vite官方文档说明:
enforce : pre | post , pre 先执行;apply : build | serve , 指明调用模式config(config, { mode, command}) : 在解析 Vite 配置前调用. 钩子接收原始用户配置 和一个描述配置环境的变量, 包含正在使用的 mode 和 command.configResolved(config) : 在解析 Vite 配置后调用. 使用这个钩子读取和存储最终解析的配置. 当插件需要根据运行的命令做一些不同的事情时, 它也很有用.configureServer(server) : 用于配置开发服务器的钩子configurePreviewServer(server): 与 configureServer 相同但是作为预览服务器. 它提供了一个 connect 服务器实例及其底层的 http server.transformIndexHtml(html) : 转换 index.html 的专用钩子. 钩子接收当前的 HTML 字符串和转换上下文; * handleHotUpdate(ctx): 执行自定义 HMR 更新处理. 钩子接收一个带有以下签名的上下文对象: modules, read
源码地址: vite-plugin-hot-hash – github: github.com/UU-GIT/vite…⭐️ 欢迎 star ⭐️
参考
cn.vitejs.dev/guide/api-p…rollupjs.org/guide/en/