修复 .uvue 页面路径残留问题
版本:1.4.1 | 协议:MIT | 依赖:Vite >=5.0.0 <9.0.0
写在前面
v1.4.1 是一个纯修复补丁,主题是:让 uni-app x 项目真正可用 .uvue 页面。
v1.4.0 为 generatePages / generateUni 引入了 includeExtensions 配置能力,但页面路径剥离逻辑与 SFC 模块识别仍停留在 .vue 时代——配置 .uvue 时,生成的 pages.json 里 path 残留扩展名导致页面无法识别,.uvue 页面里的 defineUniPage 宏调用也无法在构建时被移除。本次修复这两处,无新功能、无 Breaking Change。
本版重点:
能力 | 一句话说明 | 你需要做什么 |
|---|---|---|
pages.json 路径残留扩展名 | 按 | 升级后重新生成一次即可 |
| SFC script 识别兼容 | 无需配置,自动生效 |
generatePages / generateUni | 两插件共用 | 无感知 |
文档同步 |
| 无需配置 |
升级方式:修改 devDependencies 中版本号为 ^1.4.1。无 Breaking Change,1.x 用户可平滑升级。
一、修复一:pages.json 路径残留扩展名
1.1 背景
uni-app x 项目使用 .uvue 文件编写页面。配置:
generateUni({
pages: {
pagesDir: 'src/pages',
includeExtensions: ['.uvue'] // 启用 .uvue 页面扫描
}
})v1.4.0 之前这行配置形同虚设——生成的 pages.json 里出现:
{
"path": "pages/home/index.uvue", // ❌ 多了 .uvue
"name": "HomeIndex",
"style": { "navigationBarTitleText": "首页" }
}uni-app 按 pages/home/index.uvue 找页面,直接提示「页面不存在」。
1.2 根因
页面路径剥离逻辑写死了扩展名白名单(packages/core/src/plugins/generate/generatePages/helpers/scanner.ts):
const pagePath = relativePath.replace(/\.(vue|nvue)$/i, '')扫描层按 includeExtensions 过滤文件没有错(.uvue 能被扫到),但组装层只剥离 .vue / .nvue——正则要求末尾是 .vue / .nvue,.uvue 无法匹配,扩展名便残留进 path。
1.3 修复方式
改为按文件实际扩展名动态剥离:
用
path.extname取文件真实扩展名,命中includeExtensions列表(忽略大小写、容忍前导点)才剥离未配置
includeExtensions时回退原.vue/.nvue行为,兼容既有项目
场景 | 此前 | 现在 |
|---|---|---|
|
|
|
未配置 |
|
|
同一定理由此可正确处理任意自定义扩展名(.tsx / .mjs 等),不再局限于 .vue 家族。
1.4 验证
实测 6 组场景:.uvue 单配、默认 .vue、混合 ['.vue','.uvue']、自定义 .tsx 等,输出路径均正确;未配置时行为与旧版完全一致。
二、修复二:.uvue 页面 defineUniPage 宏未剥离
2.1 根因
generatePages / generateUni 的 transform 钩子负责两件事:拦截 <route-config> 虚拟模块、剥离 defineUniPage 宏调用。后者是否执行取决于对「Vue SFC script 模块」的识别:
return id.includes('.vue') && /[?&]type=script/.test(id).uvue 页面的 script 虚拟模块 id 形如 pages/home/index.uvue?vue&type=script&setup=true——其中并不包含 .vue 子串(.uvue?vue 中间是 ?),因此识别失败:
defineUniPage(...)调用不会在构建时被移除,残留进产物 → 运行时ReferenceErrorisRouteConfigRequest仅依赖?vue与type=,对.uvue可正常命中,<route-config>拦截不受影响
2.2 修复方式
识别规则改为正则:
return /\.(vue|uvue|nvue)(\?|$)/i.test(id) && /[?&]type=script/.test(id)实测:.uvue?vue&type=script&setup=true ✅ 命中;.uvue?vue&type=route-config&index=0、type=template ✅ 不误命中;.vue / .nvue 行为不变。generatePages / generateUni 两处同步修正。
2.3 影响说明
该缺陷只影响 .uvue 页面使用 defineUniPage 宏的场景;仅用 <route-config> 自定义块的项目不受影响。
三、修复范围
项目 | 说明 |
|---|---|
主包 + 分包 | 扩展名按主包 / 分包各自扫描目录相对路径动态剥离 |
generatePages | 独立使用与 generateUni 阶段一共享 |
generateUni | 阶段一 pages.json、阶段二路由配置(内存直传)均基于正确路径,无需改动 |
js_sdk(uni_modules 内嵌) | 已同步重建,嵌入式 uni-app 插件包可直接使用 |
文档 |
|
四、升级步骤与注意事项
升级依赖:
devDependencies中@meng-xi/vite-plugin改为^1.4.1重新生成一次 pages.json:删除或保留均可,插件将基于正确逻辑重写
path.uvue页面沿用defineUniPage宏无需改动;若此前因该缺陷而改用<route-config>,可改回宏写法自定义扩展名(非
.vue/.nvue/.uvue)同样受支持,但<route-config>自定义块与defineUniPage宏仍要求页面为 Vue SFC 家族文件
本文基于 @meng-xi/vite-plugin@1.4.1 版本撰写。
