vite-inset-loader
AIGC: Label: "1" ContentProducer: 001191440300708461136T1XGW3 ProduceID: d42406d914a5c4fb8e471f3edd5c98cd_6ef821d3ac1511f18f50525400aeaaa3 ReservedCode1: g3YaCB4ch4bUqO9mJ6sd73PZ1yDkGB/tU77sknCmYbYWhfJrbSvRSzEYRVut7UFJ4jRmqy0m9BL/cBBhIb4svGcuBTv/uLDthLOholac95AWbPqctkOCEpsOlCnnWBM8XJQiSOZCPsIno/Z4HPmSROLIiDW/2YmC8dxGdf6i2Rqvc9F2pqS/39ADgnU= ContentPropagator: 001191440300708461136T1XGW3 PropagateID: d42406d914a5c4fb8e471f3edd5c98cd_6ef821d3ac1511f18f50525400aeaaa3 ReservedCode2: g3YaCB4ch4bUqO9mJ6sd73PZ1yDkGB/tU77sknCmYbYWhfJrbSvRSzEYRVut7UFJ4jRmqy0m9BL/cBBhIb4svGcuBTv/uLDthLOholac95AWbPqctkOCEpsOlCnnWBM8XJQiSOZCPsIno/Z4HPmSROLIiDW/2YmC8dxGdf6i2Rqvc9F2pqS/39ADgnU=
vite-inset-loader
一个专为 UniApp(Vue3 + Vite)设计的编译期注入插件集合,在 SFC 模板编译前向指定页面插入自定义组件标签。现提供两个入口(互斥,二选一):
- UniViteRootInjector(推荐):高性能、类型友好,支持按页面/按需注入与自动路由类型生成。
- UniViteInsetLoader(兼容):沿用旧版 vite-inset-loader 的 pages.json 驱动注入方式。
文档入口:
兼容性
- Vite 版本:
>= 5.0.0(peerDependencies已声明vite >=5.0.0)。当前实现使用 Vite 5 兼容的函数形式transform(code, id),在 Vite 5/6/7/8 下均可用。 - uni-app 约束:
@dcloudio/vite-plugin-uni目前固定依赖vite ^5.2.8(见其 peerDependencies),因此 uni-app 项目请使用 Vite 5(推荐 ^5.2.8,实测 5.4.21 可用)。Vite 8 的{ filter, handler }对象形式 transform 与 Rust 侧过滤能力被有意保留为注释说明,避免破坏 Vite 5 兼容。 - Node.js:
>= 20.19.0。
安装
pnpm add vite-inset-loader -D
# 或
npm i vite-inset-loader -D
# 或
yarn add vite-inset-loader -D
最佳使用位置(重要)
参考 Vite 5 官方文档-插件 API 中的插件顺序模型:
Alias -> enforce:'pre' 用户插件 -> Vite 核心插件 -> 普通用户插件 -> Vite 构建插件 -> enforce:'post' 用户插件
本套插件已通过内部 enforce: 'pre' 强制定位到「Vite 核心插件」之前执行:
- 保证拿到未被 SFC 编译链(如 @vitejs/plugin-vue)转换过的原始 .vue 源码做模板注入,注入结果稳定、不受其他插件改写影响;
- 避免对各平台已被插件链预处理过的中间代码做无效的
@vue/compiler-sfc解析,降低无效计算。
因此配置时无需手动写 enforce,只需要:
UniViteRootInjector/UniViteInsetLoader放在plugins数组首位(语义上表达"最先处理",与 enforce:'pre' 一致,便于他人阅读);- 请勿放在
uni()之后构建类插件之后。
推荐写法:
export default defineConfig({
plugins: [
UniViteRootInjector({ /* ... */ }), // 首位
uni(), // 再加载 uni 官方插件
],
});
两个插件的 vite.config.ts 完整示例见下文。
demo
插件入口(二选一)
| 入口函数 | 适用场景 | 特性 | 性能 |
|---|---|---|---|
| UniViteRootInjector(推荐) | 需要灵活注入、类型提示、按需配置 | 缓存 pages.json、按需注入、自动生成路由类型 | ⭐️⭐️⭐️⭐️⭐️ |
| UniViteInsetLoader | 兼容旧版行为、沿用 pages.json 的标签注入 | 不改动旧配置、快速接入 | ⭐️⭐️⭐️ |
注意:两个入口不能同时启用。若在同一 Vite 配置中同时使用,会抛出互斥错误。
使用 UniViteRootInjector(推荐)
import { defineConfig } from 'vite';
import uni from '@dcloudio/vite-plugin-uni';
import { UniViteRootInjector } from 'vite-inset-loader';
import { resolve } from 'node:path';
// 若配置 dts,请在项目中显式引用生成的类型
import type { Path } from './types/auto-page.d';
const components = {
privacyModal: '<privacyModal></privacyModal>',
message: '<GyMessage ref="messageRef"></GyMessage>',
dialog: '<GyDialog ref="dialogRef"></GyDialog>',
messageBox: '<wd-message-box></wd-message-box>',
toast: '<wd-toast />',
} as const;
export default defineConfig({
plugins: [
// 最佳位置:plugins 数组首位(插件内部已 enforce:'pre')
UniViteRootInjector<Path, typeof components>({
dts: resolve(__dirname, 'types/auto-page.d.ts'),
components,
insertPos: {
mode: 'GLOBAL',
exclude: ['login' as Path], // Path 类型:pages/login/index -> login
handlePos: [
{ page: 'home' as Path, insert: ['message'] }, // Path 类型:pages/home/index -> home
{ page: 'sub_initiateEvaluation' as Path, insert: ['toast'] }, // 分包:subPackages/sub/initiateEvaluation/index -> sub_initiateEvaluation
],
},
}),
uni(),
],
});
RootInjector 配置项(节选)
- dts: 路由类型文件生成路径,缺省生成到默认位置
- components: 组件别名到组件字符串的映射,支持类型推断
- insertPos: 注入策略配置
- mode: 'GLOBAL'(全局模式)
- exclude: Path[] - 排除的页面路径,使用 Path 类型枚举值
- 主包页面:
pages/home/index→home - 分包页面:
subPackages/sub/initiateEvaluation/index→sub_initiateEvaluate
- 主包页面:
- handlePos: 页面特定配置,其中 page 参数为 Path 类型枚举值(生成规则同上)
- includes/watchFile: 可选的包含与监听配置
使用 UniViteInsetLoader(兼容模式)
import { defineConfig } from 'vite';
import uni from '@dcloudio/vite-plugin-uni';
import { UniViteInsetLoader } from 'vite-inset-loader';
export default defineConfig(() => ({
plugins: [
UniViteInsetLoader({ include: 'src' }), // 最佳位置:plugins 数组首位
uni(),
],
}));
viteInsetLoader 方法配置项
| 属性 | 说明 | 类型 | 默认值 | 必填 |
|---|---|---|---|---|
| include | 过滤需要插入组件的目录路径(错误路径将导致不生效) | string | string[] | 'src' | 否 |
pages.json 配置(用于 InsetLoader)
insetLoader 依赖 pages.json 中的配置来注入标签:
{
"insetLoader": {
"config": {
"message": "<GyMessage ref='messageRef'></GyMessage>",
"dialog": "<GyDialog ref='dialogRef'></GyDialog>"
},
"label": ["message", "dialog"],
"package": {
"label": "span",
"options": {
"class": "dev-style",
"style": { "font-size": "24px" },
"data-attr": "content"
}
}
}
}
页面级覆盖示例(优先级高于全局配置):
{
"pages": [
{
"path": "pages/home/index",
"style": {
"label": ["message"],
"package": {
"label": "span",
"options": {
"class": "dev-style",
"style": { "font-size": "24px" },
"data-attr": "123468"
}
}
}
}
]
}
注册全局组件(仅 InsetLoader 场景)
import { createSSRApp } from 'vue';
import App from './App.vue';
import GyMessage from './components/GyMessage/index.vue';
export const createApp = () => {
const app = createSSRApp(App);
app.component('GyMessage', GyMessage); // 需与 pages.json 的 config 别名匹配
return { app };
};
性能说明
插件在初始化(buildStart)阶段完成所有可下沉的预计算,transform 热路径仅做 O(1) 查询,已针对 Vite 5 场景做如下优化:
- hook 顺序:内部
enforce: 'pre',在任何 SFC 编译链之前拿到原始 .vue 源码,避免对已转换中间代码做无效 parse。 - 路由 O(1) 索引:初始化时构建
绝对路径 -> route的routeMap(Map),transform 内一次routeMap.get命中,取代逐文件字符串替换/线性扫描。 - 注入 DOM 预编译:初始化时对每个页面调用一次
getInsertLabelDom生成注入字符串labelCode并缓存,热路径直接复用,零重复拼接。 - 快速短路:transform 开头用单一正则
/\.vue$/过滤(同 Vite 6.3+ filter 语义),非 .vue 文件/未命中的组件文件直接return null(不返回{code,map},表示未变更,更快)。 - sourcemap 轻量化:
hires: false+includeContent: false,降低大项目 sourcemap 生成成本。 - 死代码与依赖瘦身:移除未使用依赖(chokidar/debug/vue-loader 等)与死代码(routes-type-generate 326 行 -> 35 行)。
提示:Vite 6.3+/8(Rolldown)支持
{ filter, handler }对象形式 transform,让引擎在 Rust 侧直接过滤非 .vue 文件以进一步减少跨进程调用;但因 uni-app 官方插件固定 vite ^5.2.8,本插件采用函数形式以全版本兼容。
常见问题
- 两个入口不能同时使用:内部会检测并抛出错误,用任意一个即可。
- RootInjector 性能更好:更适合页面较多或注入规则复杂的项目。
- 仅命名导出:从 v1.0.10 起包只提供命名导出(不再有默认导出)。
- 安装出现 vite peer 冲突:确认项目 vite 版本为 ^5.2.x(本包 peer 要求
vite >=5.0.0,但 uni-app 官方插件要求 ^5.2.8,请以 uni 官方为准)。
进一步阅读
- UniViteRootInjector 使用与配置(推荐):./docs/UniViteRootInjector.md
- UniViteInsetLoader 使用与配置(兼容):./docs/UniViteInsetLoader.md
致谢
vite-inset-loader的灵感来源于vue-inset-loader(早期适配 Webpack + Vue2)。本项目在其基础上适配了 Vite + Vue3 并进行了能力扩展与性能优化。
欢迎提出你的建议与 PR:GitHub 仓库 (内容由AI生成,仅供参考)
Related Packages
create-uni-app-tailwindcss
Create a uni-app project with Vite, Vue 3, Tailwind CSS, and weapp-tailwindcss.
1,270
335
@uni_toolkit/vite-plugin-component-config
一个用于 UniApp 项目的 Vite 插件,用于处理 Vue 文件中的 `<component-config>` 标...
5,870
30
Version History
| Version | Released | License |
|---|---|---|
| 2.0.2 | MIT | |
| 2.0.1 | MIT | |
| 2.0.0 | MIT | |
| 1.0.10 | MIT | |
| 1.0.9 | MIT | |
| 1.0.8 | MIT | |
| 1.0.7 | MIT | |
| 1.0.6 | MIT | |
| 1.0.5 | MIT | |
| 1.0.4 | MIT | |
| 1.0.3 | MIT | |
| 1.0.2 | MIT | |
| 1.0.1 | MIT | |
| 1.0.0 | MIT |