Vite Plugin 开发完全指南
作者:兆子龙
本篇文章详细介绍了Vite插件开发,涵盖VitePlugin基础使用、核心钩子详解、Rollup环插件应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
一、第一个 Vite Plugin
1.1 创建基础 Plugin
// plugins/vite-plugin-example.js
export default function examplePlugin() {
return {
name: 'vite-plugin-example',
config(config) {
console.log('config hook');
return {
define: {
__PLUGIN_VERSION__: '"1.0.0"'
}
};
},
configResolved(config) {
console.log('configResolved hook');
},
transform(code, id) {
console.log('transform:', id);
return code;
}
};
}
1.2 在 Vite 配置中使用
// vite.config.js
import { defineConfig } from 'vite';
import examplePlugin from './plugins/vite-plugin-example';
export default defineConfig({
plugins: [
examplePlugin()
]
});
二、核心钩子详解
2.1 config 和 configResolved
export default function configPlugin() {
return {
name: 'config-plugin',
config(config, { command, mode }) {
console.log('Command:', command); // 'serve' or 'build'
console.log('Mode:', mode); // 'development' or 'production'
// 修改配置
return {
server: {
port: 3000
},
build: {
outDir: 'dist'
}
};
},
configResolved(config) {
// 读取最终配置
console.log('Final config:', config);
}
};
}
2.2 configureServer 开发服务器
export default function devServerPlugin() {
return {
name: 'dev-server-plugin',
configureServer(server) {
// 添加中间件
server.middlewares.use((req, res, next) => {
console.log('Request:', req.url);
next();
});
// 自定义路由
server.middlewares.use('/api/hello', (req, res) => {
res.end('Hello from Vite Plugin!');
});
// 监听 WebSocket 事件
server.ws.on('connection', (ws) => {
ws.send('Welcome!');
});
}
};
}
2.3 transformIndexHtml 转换 HTML
export default function htmlPlugin() {
return {
name: 'html-plugin',
transformIndexHtml(html) {
return html.replace(
'<head>',
`<head>
<meta name="plugin-version" content="1.0.0">
`
);
}
// 或者返回对象
transformIndexHtml(html) {
return {
html,
tags: [
{
tag: 'script',
attrs: { src: '/custom-script.js' },
injectTo: 'head'
}
]
};
}
};
}
三、Rollup 钩子在 Vite 中的应用
3.1 resolveId 解析模块
export default function resolvePlugin() {
return {
name: 'resolve-plugin',
resolveId(source, importer) {
if (source === 'virtual:my-module') {
// 标记为虚拟模块
return '\0virtual:my-module';
}
return null; // 让其他插件处理
}
};
}
3.2 load 加载模块
export default function loadPlugin() {
return {
name: 'load-plugin',
load(id) {
if (id === '\0virtual:my-module') {
return `
export const message = 'Hello from virtual module!';
export const version = '1.0.0';
`;
}
return null;
}
};
}
3.3 transform 转换代码
export default function transformPlugin() {
return {
name: 'transform-plugin',
transform(code, id) {
// 只处理 .js 文件
if (!id.endsWith('.js')) return;
// 简单的代码转换
const transformedCode = code.replace(
/console\.log\(/g,
'console.log("[Plugin] "'
);
return {
code: transformedCode,
map: null // sourcemap
};
}
};
}
四、实战案例一:虚拟模块
4.1 创建虚拟模块 Plugin
// plugins/vite-plugin-virtual.js
export default function virtualModulePlugin() {
const virtualModuleId = 'virtual:env-info';
const resolvedVirtualModuleId = '\0' + virtualModuleId;
return {
name: 'vite-plugin-virtual',
resolveId(id) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId;
}
},
load(id) {
if (id === resolvedVirtualModuleId) {
return `
export const NODE_ENV = '${process.env.NODE_ENV || 'development'}';
export const VERSION = '${process.env.npm_package_version || '1.0.0'}';
export const BUILD_TIME = '${new Date().toISOString()}';
`;
}
}
};
}
4.2 使用虚拟模块
// src/main.js
import { NODE_ENV, VERSION, BUILD_TIME } from 'virtual:env-info';
console.log('Environment:', NODE_ENV);
console.log('Version:', VERSION);
console.log('Build Time:', BUILD_TIME);
五、实战案例二:处理自定义文件
5.1 处理 .yaml 文件
// plugins/vite-plugin-yaml.js
import yaml from 'js-yaml';
export default function yamlPlugin() {
return {
name: 'vite-plugin-yaml',
transform(code, id) {
if (id.endsWith('.yaml') || id.endsWith('.yml')) {
try {
const data = yaml.load(code);
return {
code: `export default ${JSON.stringify(data)};`
};
} catch (e) {
this.error(e.message);
}
}
}
};
}
5.2 使用 YAML 文件
# config.yaml app: name: My App version: 1.0.0 database: host: localhost port: 5432
import config from './config.yaml'; console.log(config.app.name); console.log(config.database.port);
六、实战案例三:热更新处理
6.1 自定义 HMR
// plugins/vite-plugin-hmr.js
export default function hmrPlugin() {
return {
name: 'vite-plugin-hmr',
handleHotUpdate({ file, server, modules }) {
console.log('File changed:', file);
// 自定义更新逻辑
if (file.endsWith('.special')) {
server.ws.send({
type: 'custom',
event: 'special-update',
data: { file }
});
return []; // 不触发默认更新
}
return modules; // 默认行为
}
};
}
6.2 客户端接收 HMR
// src/hmr-client.js
if (import.meta.hot) {
import.meta.hot.on('special-update', (data) => {
console.log('Special update:', data);
// 自定义更新处理
});
}
七、插件开发技巧
7.1 区分开发与生产环境
export default function envPlugin() {
let isDev;
return {
name: 'env-plugin',
configResolved(config) {
isDev = config.command === 'serve';
},
transform(code, id) {
if (isDev) {
// 开发环境逻辑
return code + '\nconsole.log("Dev only");';
} else {
// 生产环境逻辑
return code;
}
}
};
}
7.2 插件排序
// vite.config.js
export default defineConfig({
plugins: [
pluginA(), // 先执行
pluginB(), // 后执行
]
});
// 使用 enforce
export default function plugin() {
return {
name: 'my-plugin',
enforce: 'pre', // 'pre' | 'post' | undefined
};
}
八、调试与测试
8.1 调试 Plugin
// 使用 debug
import createDebug from 'debug';
const debug = createDebug('vite-plugin-example');
export default function debugPlugin() {
return {
name: 'debug-plugin',
transform(code, id) {
debug('Transforming:', id);
return code;
}
};
}
8.2 测试 Plugin
// test/plugin.test.js
import { createServer } from 'vite';
import myPlugin from '../index.js';
test('plugin works', async () => {
const server = await createServer({
plugins: [myPlugin()]
});
// 测试逻辑
await server.close();
});
九、最佳实践
- 命名规范:使用
vite-plugin-前缀 - TypeScript:使用 TS 开发,提供类型
- 文档:完善的 README
- 测试:提供单元测试
- 兼容性:考虑不同 Vite 版本
到此这篇关于Vite Plugin 开发完全指南的文章就介绍到这了,更多相关Vite Plugin 开发内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章:
- Vue3+Vite项目中引入pinia和pinia-plugin-persistedstate的方法代码
- Vite使用unplugin-auto-import实现vue3中的自动导入
- 3分钟搞定vite项目(vue/react)使用vite-plugin-pwa配置为pwa应用
- vue3项目导入异常Error:@vitejs/PLUGIN-vue requires vue (>=3.2.13)解决办法
- vue3+vite使用vite-plugin-svg-icons插件显示本地svg图标的方法
- Vite处理html模板插件之vite-plugin-html插件使用
- 解决vue3+vite配置unplugin-vue-component找不到Vant组件
- vite打包优化vite-plugin-compression的使用示例详解
- vue3+vite多项目多模块打包(基于vite-plugin-html插件)
- 在 Vite项目中使用插件 @rollup/plugin-inject 注入全局 jQuery的过程详解
- vue3+vite引入插件unplugin-auto-import的方法
