Vite 插件开发:打造自己的构建工具链

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 倍。