vite浅析插件
前言
最近使用 vite 在写项目时,遇到vue3
中给setup
添加name
的问题,本来是打算直接使用插件进行实现的,但是评论说是会有各种各样的问题,看了下vite
插件介绍后,下面来讲解 Vite 插件的基本概念。
Vite 和 Rollup
有了解过 Vite 的都知道,Vite 开发用的 ESBuild,而生产打包的时候使用的 Rollup进行打包,可能有人会有疑问,为什么生产不直接用 ESBuild 打包而是用 Rollup,对此 Vite 官方是这样回复的:
虽然 esbuild
快得惊人,并且已经是一个在构建库方面比较出色的工具,但一些针对构建 应用 的重要功能仍然还在持续开发中 —— 特别是代码分割和 CSS 处理方面。就目前来说,Rollup 在应用打包方面更加成熟和灵活。尽管如此,当未来这些功能稳定后,也不排除使用 esbuild
作为生产构建器的可能。
可以理解为 Vite 用 Esbuild 来干活,干完活就不用它了,换成 Rollup 进行打包。
Vite 之所以能开发和生产使用两套不同的构建工具,是因为他在dev
环境下,其实是通过插件容器,除了使用 Vite 独有特性的插件,其他插件会进行模拟 Rollup 插件行为,等到打包的时候,会将这一块替换成 Rollup 打包,所以其实不管是开发环境还是生产环境其实共享的同一套 Rollup 插件机制,Vite 插件 相当于是对 Rollup 插件 做了一层兼容,或者换一个说法,Vite 插件对 Rollup 插件做了扩展,加上了一些 Vite 独有的属性。
Vite 插件概念
命名规范
如不使用 Vite 独有特性,可当做兼容 Rollup 的插件,推荐以推荐使用 Rollup 插件名称约定,反之,推荐以 vite-plugin-
开头,如果专属于某个框架,推荐格式:
vite-plugin-vue-
前缀作为 Vue 插件vite-plugin-react-
前缀作为 React 插件
插件结构
一般插件结构由 name、enforce 和钩子组成。
- name:即插件名字。
- enforce: 通过该属性来调整插件加载顺序,可选值:
pre | post
- 钩子:不同状态下对应的处理函数,类似于生命周期。
插件加载顺序
插件结构中 enforce属性可调整插件加载顺序,Vite 插件加载顺序如下:
- Alias
- 带有
enforce: 'pre'
的用户插件 - Vite 核心插件(解析 vue 文件等)
- 没有 enforce 值的用户插件
- Vite 构建用的插件
- 带有
enforce: 'post'
的用户插件 - Vite 后置构建插件(最小化,manifest,报告)
这里借用一张 rollup 的执行顺序:
Vite 插件钩子
通用钩子
服务器启动钩子:
options
options 钩子主要是获取 Rollup 的配置,由于 vite 开发的时候使用的是 EsBuild,所以开发环境下该属性为空,主要包含一些使用的 plugin,input入口文件等。
示例代码:
export function testPlugin() {
return {
//插件名字
name: "vite-plugin-test",
options(options) {
//可设置options.input修改入口文件
console.log(options);
},
};
}
buildStart
buildStart 钩子执行顺序在options钩子后,主要是获取options钩子配置后的Rollup 配置和一些默认值,这个钩子开发和生产环境值都存在,不同于options,通过该钩子可以清楚看到Vite 开发环境下对Rollup做的兼容模拟。
示例代码:
export function testPlugin() {
return {
//插件名字
name: "vite-plugin-test",
buildStart(options) {
console.log(options);
},
};
}
开发环境下:
生产环境时:
加载模块请求时钩子:
resolveId
resolveId 钩子可以获取文件路径,在该钩子下可以对文件路径进行重写或其他操作。
设置 enforce 不同值所打印的也不同哦
示例代码:
export function testPlugin() {
return {
//插件名字
name: "vite-plugin-test",
resolveId(id) {
console.log(id);
},
};
}
load
load 钩子可拦截文件读取,模块引入读取操作,参数和resolveId 钩子类似,如需替换模块读取内容,返回对应code
和map
即可。
示例代码:
export function testPlugin() {
return {
//插件名字
name: "vite-plugin-test",
load(id) {
console.log(id);
if (id === "xxxx") {
return {
code: "<template>xxxxx</template>",
map: "",
};
}
},
};
}
transform
transform 钩子可以转换单个模块对应的代码,和 load 钩子不同的是,他有两个参数,code
和id
,这里的id
和上面一样,这个code
就是他对应的代码 ,简单情况下可直接修改 code
去实现,复杂情况还是需要通过解析工具去解析 vue。给setup加name
就是用这个钩子实现的,这个在下一篇详细讲解。
这里注意,enforce 设置的不同会导致 code 不同,如设置成 pre 这是编译前源代码,为空或 post 则是编译后的代码。
示例代码:
export function testPlugin() {
return {
//插件名字
name: "vite-plugin-test",
transform(code, id) {
if (id.includes("HelloWorld")) {
console.log(code);
}
console.log(id);
},
};
}
pre:
空或 post:
服务器关闭钩子:
buildEnd
buildEnd 钩子是打包代码生成之前触发的钩子,仅在生产环境生效。
示例代码:
export function testPlugin() {
return {
//插件名字
name: "vite-plugin-test",
buildEnd() {},
};
}
closeBundle
closeBundle 钩子是打包后最后执行的钩子,他和buildEnd的区别是,它是打包代码生成后触发的钩子。
示例代码:
export function testPlugin() {
return {
//插件名字
name: "vite-plugin-test",
closeBundle() {},
};
}
Vite 独有钩子(以下钩子会被 Rollup 忽略)
config
config 钩子是解析 Vite 默认配置前钩子,它返回了 Vite 的一些默认配置,可以在这里修改配置,它有两个参数,第一个参数config
是 Vite 的基本配置,第二个参数包括当前mode
和command
示例代码:
export function testPlugin() {
return {
//插件名字
name: "vite-plugin-test",
config: (config, { mode, command }) => {
console.log(config);
console.log(mode);
console.log(command);
},
};
}
configResolved
configResolved 钩子是解析 Vite 默认配置后钩子,返回的是最终的 Vite 配置(自定义配置合并后的),可用于获取当前的一些配置,根据不同配置做不同的事情。
示例代码:
export function testPlugin() {
return {
//插件名字
name: "vite-plugin-test",
configResolved(config) {
console.log(config);
},
};
}
configureServer
configureServer 是配置开发服务器钩子,仅在开发环境下才会执行,他会返回当前开发服务器的配置。
示例代码:
export function testPlugin() {
return {
//插件名字
name: "vite-plugin-test",
configureServer(config) {
console.log(config);
},
};
}
configurePreviewServer
configurePreviewServer钩子和configureServer类似,但是configurePreviewServer是预览服务器,仅在执行npm run preview
时触发该钩子。
示例代码:
export function testPlugin() {
return {
//插件名字
name: "vite-plugin-test",
configureServer(config) {
console.log(config);
},
};
}
transformIndexHtml
transformIndexHtml钩子主要是操作index.html
文件,它会返回当前的html
文件,修改index.html
的title
就可以在该钩子中修改。
示例代码:
export function testPlugin() {
return {
//插件名字
name: "vite-plugin-test",
transformIndexHtml(html) {
console.log(html);
},
};
}
handleHotUpdate
handleHotUpdate 钩子主要是热更新钩子,这里就略过。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南