Vite 插件开发:打造自己的构建工具链
Vite 的成功很大程度上归功于其灵活的插件系统。它兼容 Rollup 插件接口的同时,扩展了 Vite 特有的钩子用于开发服务器的增强。本文从零开发一个 Markdown 导入插件,深入理解插件机制。
插件的基本结构:
import { Plugin } from "vite";
export default function markdownPlugin(): Plugin {
return {
name: "vite-plugin-markdown",
// 解析 Markdown 文件的 import
async transform(code, id) {
if (!id.endsWith(".md")) return null;
const html = await renderMarkdown(code);
return {
code: `export default ${JSON.stringify(html)}`,
map: null,
};
},
// 开发服务器热更新
handleHotUpdate({ file, server }) {
if (file.endsWith(".md")) {
server.ws.send({ type: "full-reload" });
}
},
};
}
虚拟模块是 Vite 插件的强大特性:
export default function virtualRoutesPlugin(): Plugin {
const virtualId = "virtual:routes";
return {
name: "vite-plugin-virtual-routes",
resolveId(id) {
if (id === virtualId) return "\0" + virtualId;
},
async load(id) {
if (id !== "\0" + virtualId) return null;
const pages = await glob("./src/pages/**/*.{tsx,jsx}");
const imports = pages.map((p, i) =>
`import Page${i} from "${p}";`
).join("\n");
return `${imports}\nexport const routes = [${pages.map((p, i) =>
`{ path: "${toRoute(p)}", component: Page${i} }`
).join(",")}];`;
},
};
}
我们基于这个思路开发了团队的组件文档插件,它可以自动扫描组件目录、提取 Props 类型信息、生成 Storybook 风格的文档页面。配合 HMR,组件开发效率提升了 3 倍。