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.json
npm 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.ts
import 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.注册账号
2.终端命令, 登录npm账号
npm login
3.发布
npm publish
五、插件钩子简介
1.通用钩子
在开发中, Vite
开发服务器会创建一个插件容器来调用 Rollup
构建钩子:
-
服务器启动时被调用:
- options
- buildStart
-
每个传入模块请求时被调用:
- resolveId
- load
- transform
-
服务器关闭时被调用:
- buildEnd
- closeBundle
详细说明及使用情况, 可查看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 ⭐️
参考
转载自:https://juejin.cn/post/7173858168865308685