插件
Hooks


export default function vitePlugin() {
// 定义vite插件唯一id
const virtualFileId = '@my-virtual-plugin'
// 返回插件对象
return {
// 必须的,将会显示在 warning 和 error 中
name: 'vite-plugin',
// *以下钩子函数按照实际执行顺序排列*
/**
* config 可以在被解析之前修改 Vite 配置
* Vite独有钩子
* https://cn.vitejs.dev/guide/api-plugin.html#config
* @param config vite配置信息
* @param env 描述配置环境的变量
*/
config: (config, env) => ({}),
/**
* configResolved 解析 Vite 配置后调用,使用这个钩子读取和存储最终解析的配置
* Vite独有钩子
* https://cn.vitejs.dev/guide/api-plugin.html#configresolved
* @param config vite配置信息
*/
configResolved: config => ({}),
/**
* options 替换或操作传递给rollup.rollup()的选项
* 通用钩子
* https://rollupjs.org/guide/en/#options
* @param options rollup配置信息
*/
options: options => ({}),
/**
* configureServer 用于配置开发服务器
* Vite独有钩子
* https://cn.vitejs.dev/guide/api-plugin.html#configureserver
* @param server ViteDevServer配置信息
* https://cn.vitejs.dev/guide/api-javascript.html#vitedevserver
*/
configureServer: server => ({}),
/**
* buildStart 在每个rollup.rollup()构建时被调用
* 通用钩子
* https://rollupjs.org/guide/en/#buildstart
* @param options rollup配置信息
*/
buildStart: options => ({}),
/**
* 此时 Vite dev server is running
*/
/**
* transformIndexHtml 转换 index.html 的专用钩子
* Vite独有钩子
* https://cn.vitejs.dev/guide/api-plugin.html#transformindexhtml
* @param html html字符串
* @param ctx 转换上下文; 在开发期间会额外暴露ViteDevServer实例; 在构建期间会额外暴露Rollup输出的包
*/
transformIndexHtml: (html, ctx) => ({}),
/**
* resolveId 用户自定义解析器
* 通用钩子 会在每个传入模块请求时被调用
* https://rollupjs.org/guide/en/#resolveid
* @param source 源导入者 例子: import { foo } from '../bar.js', '../bar.js' 为source
* @param importer 导入者所在文件绝对路径
*/
resolveId: (source, importer) => ({}),
/**
* load 用户自定义加载器
* 通用钩子 会在每个传入模块请求时被调用
* https://rollupjs.org/guide/en/#load
* @param id 同resolveId source
*/
load: id => ({}),
/**
* transform 可以用来转换单个模块
* 通用钩子 会在每个传入模块请求时被调用
* https://rollupjs.org/guide/en/#transform
* @param code 模块代码
* @param id 同resolveId source
*/
transform: (code, id) => ({}),
/**
* buildEnd 在 Rollup 完成产物但尚未调用 generate 或 write 之前调用;也可以返回一个 Promise。如果在构建过程中发生错误,则将其传递给此钩子。
* 通用钩子
*/
buildEnd: () => ({}),
/**
* closeBundle 构建时被调用
* 通用钩子
*/
closeBundle: () => ({}),
}
}插件预设
plugins 也可以接受将多个插件作为单个元素的预设。这对于使用多个插件实现的复杂特性(如框架集成)很有用。该数组将在内部被扁平化(flatten)。
import frameworkDevtools from 'vite-plugin-framework-devtools'
import frameworkRefresh from 'vite-plugin-framework-refresh'
export default function framework(config) {
return [frameworkRefresh(config), frameworkDevTools(config)]
}import { defineConfig } from 'vite'
import framework from 'vite-plugin-framework'
export default defineConfig({
plugins: [framework()],
})强制插件排序
为了与某些 Rollup 插件兼容,可能需要强制修改插件的执行顺序
一个 Vite 插件可以额外指定一个 enforce 属性来调整它的应用顺序。enforce 的值可以是 pre 或 post。解析后的插件将按照以下顺序排列:
- Alias
- 带有
enforce: 'pre'的用户插件 - Vite 核心插件
- 没有 enforce 值的用户插件
- Vite 构建用的插件
- 带有
enforce: 'post'的用户插件 - Vite 后置构建插件(最小化,manifest,报告)
按需应用
默认情况下插件在开发 (serve) 和生产 (build) 模式中都会调用。如果插件在服务或构建期间按需使用,请使用 apply 属性指明它们仅在 'build' 或 'serve' 模式时调用:
import typescript2 from 'rollup-plugin-typescript2'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
{
...typescript2(),
apply: 'build',
},
],
})过滤与 include/exclude 模式
Vite 暴露了 @rollup/pluginutils 的 createFilter 函数,以支持 Vite 独有插件和集成使用标准的 include/exclude 过滤模式。
import type { FilterPattern, Plugin } from 'vite'
import { createFilter } from 'vite'
export interface Options {
include?: FilterPattern
exclude?: FilterPattern
}
export function vitePlugin(options: Options = {}): Plugin {
const { include, exclude } = options
const filter = createFilter(include || /\.[jt]sx$/, exclude)
return {
name: 'vite-plugin',
async transform(code, id, opt) {
if (filter(id)) {
// ...
}
},
}
}虚拟模块
虚拟模块是一种很实用的模式,使你可以对使用 ESM 语法的源文件传入一些编译时信息。
export default function myPlugin() {
const virtualModuleId = 'virtual:my-module'
const resolvedVirtualModuleId = `\0${virtualModuleId}`
return {
name: 'my-plugin', // 必须的,将会在 warning 和 error 中显示
resolveId(id) {
if (id === virtualModuleId)
return resolvedVirtualModuleId
},
load(id) {
if (id === resolvedVirtualModuleId)
return `export const msg = "from virtual module"`
},
}
}这使得可以在 JavaScript 中引入这些模块:
import { msg } from 'virtual:my-module'
console.log(msg)虚拟模块在 Vite(以及 Rollup)中都以 virtual: 为前缀,作为面向用户路径的一种约定。如果可能的话,插件名应该被用作命名空间,以避免与生态系统中的其他插件发生冲突。举个例子,vite-plugin-posts 可以要求用户导入一个 virtual:posts 或者 virtual:posts/helpers 虚拟模块来获得编译时信息。在内部,使用了虚拟模块的插件在解析时应该将模块 ID 加上前缀 \0,这一约定来自 rollup 生态。这避免了其他插件尝试处理这个 ID(比如 node 解析),而例如 sourcemap 这些核心功能可以利用这一信息来区别虚拟模块和正常文件。\0 在导入 URL 中不是一个被允许的字符,因此我们需要在导入分析时替换掉它们。一个虚拟 ID 为 \0{id} 在浏览器中开发时,最终会被编码为 /@id/__x00__{id}。这个 id 会被解码回进入插件处理管线前的样子,因此这对插件钩子的代码是不可见的。
请注意,直接从真实文件派生出来的模块,就像单文件组件中的脚本模块(如.vue 或 .svelte SFC)不需要遵循这个约定。SFC 通常在处理时生成一组子模块,但这些模块中的代码可以映射回文件系统。对这些子模块使用 \0 会使 sourcemap 无法正常工作。