Vite 的插件系统是其最强大的功能之一,允许开发人员扩展和自定义构建管道。无论您需要转换文件类型、注入构建时常量还是与其他工具集成,Vite 插件 API 都可以让您完全控制。
了解Vite的插件系统
Vite 插件是具有钩子函数的对象,在构建生命周期的特定点执行。插件分三个阶段运行:服务(开发服务器)、构建(生产)和 SSR。一个基本的插件如下所示:
import type { Plugin } from 'vite';
export function myPlugin(): Plugin {
return {
name: 'my-plugin',
config(config) {
return config;
},
transform(code, id) {
if (id.endsWith('.custom')) {
return { code: `export default ${JSON.stringify(code)}`, map: null };
}
},
};
}
调试需要 name 属性。 enforce: 'pre' 或 'post' 控制相对于其他插件的执行顺序。
汇总兼容性
Vite 的插件接口扩展了 Rollup 的接口,这意味着大多数 Rollup 插件可以开箱即用地与 Vite 配合使用。共享挂钩包括 resolveId、load、transform 和 buildEnd。 Vite 特定的钩子添加了开发服务器功能:
| 钩 | 目的 | 相 |
|---|---|---|
| 占位符_0 | 解析前修改Vite配置 | 服务+构建 |
| 占位符_0 | 阅读最终解决的配置 | 服务+构建 |
| 占位符_0 | 扩展开发服务器 | 只提供 |
| 占位符_0 | 自定义 HMR 行为 | 只提供 |
将 Rollup 插件移植到 Vite 时,请确保它不会在开发服务器上下文中错误地使用 Rollup 特定的 API,例如 this.emitFile 。
虚拟模块
虚拟模块仅在构建时存在,由插件代码而不是文件系统文件生成:
const VIRTUAL_MODULE = 'virtual:config';
export function configPlugin(): Plugin {
return {
name: 'config-plugin',
resolveId(id) {
if (id === VIRTUAL_MODULE) return '\0' + VIRTUAL_MODULE;
},
load(id) {
if (id === '\0' + VIRTUAL_MODULE) {
const config = { apiUrl: process.env.API_URL };
return `export default ${JSON.stringify(config)}`;
}
},
};
}
\0 前缀是用于标记已解析虚拟模块的 Rollup 约定。用例包括注入 polyfill、提供构建时常量以及从配置文件生成代码。
HMR 集成
热模块更换可保持快速的开发体验。 handleHotUpdate 挂钩允许您自定义哪些模块无效:
handleHotUpdate({ server, modules, timestamp }) {
if (modules.every(m => m.url.includes('node_modules'))) {
return [];
}
server.ws.send({
type: 'custom',
event: 'custom-update',
data: { timestamp },
});
return modules;
}
返回一个空数组以抑制 HMR,或返回一个过滤列表以进行粒度更新而不是完全重新加载。
测试与发布
使用 Vite 的编程 API 集成测试您的插件:
import { build } from 'vite';
const result = await build({
plugins: [testPlugin({ option: 'value' })],
logLevel: 'silent',
});
发布时,请遵循 vite-plugin-* 命名约定,将 vite 列为对等依赖项,并包含 TypeScript 声明。在 CI 中跨多个 Vite 版本进行测试,以便及早发现重大更改。
Vite 的插件 API 设计精良、简单、强大。从简单的转换开始,探索用于构建时代码生成的虚拟模块,并利用 HMR 挂钩来获得精美的开发体验。

