Featured image of post Vite插件开发:从零到量产Featured image of post Vite插件开发:从零到量产

Vite插件开发:从零到量产

开发 Vite 插件的完整指南,涵盖插件 API、Rollup 兼容性、虚拟模块、HMR 集成、配置解析和发布到 npm。

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 配合使用。共享挂钩包括 resolveIdloadtransformbuildEnd。 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 挂钩来获得精美的开发体验。