修复 .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.jsonpath 残留扩展名导致页面无法识别,.uvue 页面里的 defineUniPage 宏调用也无法在构建时被移除。本次修复这两处,无新功能、无 Breaking Change

本版重点

能力 一句话说明 你需要做什么
pages.json 路径残留扩展名 includeExtensions 动态剥离扩展名,.uvue 不再生成 pages/home/index.uvue 错误路径 升级后重新生成一次即可
.uvue 页面宏剥离 SFC script 识别兼容 .uvue / .nvuedefineUniPage 宏调用不再残留于构建产物 无需配置,自动生效
generatePages / generateUni 两插件共用 producePages 流水线,一处修复同时生效 无感知
文档同步 includeExtensions 说明补充「生成的 path 不含扩展名」 无需配置

升级方式 :修改 devDependencies 中版本号为 ^1.4.1无 Breaking Change,1.x 用户可平滑升级。


一、修复一:pages.json 路径残留扩展名

1.1 背景

uni-app x 项目使用 .uvue 文件编写页面。配置:

typescript 复制代码
generateUni({
	pages: {
		pagesDir: 'src/pages',
		includeExtensions: ['.uvue'] // 启用 .uvue 页面扫描
	}
})

v1.4.0 之前这行配置形同虚设------生成的 pages.json 里出现:

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):

typescript 复制代码
const pagePath = relativePath.replace(/\.(vue|nvue)$/i, '')

扫描层按 includeExtensions 过滤文件没有错(.uvue 能被扫到),但组装层只剥离 .vue / .nvue------正则要求末尾是 .vue / .nvue.uvue 无法匹配,扩展名便残留进 path

1.3 修复方式

改为按文件实际扩展名动态剥离

  • path.extname 取文件真实扩展名,命中 includeExtensions 列表(忽略大小写、容忍前导点)才剥离
  • 未配置 includeExtensions 时回退原 .vue / .nvue 行为,兼容既有项目
场景 此前 现在
includeExtensions: ['.uvue'] pages/home/index.uvue pages/home/index
未配置 includeExtensions(默认) pages/home/index pages/home/index(保持)

同一定理由此可正确处理任意自定义扩展名(.tsx / .mjs 等),不再局限于 .vue 家族。

1.4 验证

实测 6 组场景:.uvue 单配、默认 .vue、混合 ['.vue','.uvue']、自定义 .tsx 等,输出路径均正确;未配置时行为与旧版完全一致。


二、修复二:.uvue 页面 defineUniPage 宏未剥离

2.1 根因

generatePages / generateUni 的 transform 钩子负责两件事:拦截 <route-config> 虚拟模块、剥离 defineUniPage 宏调用。后者是否执行取决于对「Vue SFC script 模块」的识别:

typescript 复制代码
return id.includes('.vue') && /[?&]type=script/.test(id)

.uvue 页面的 script 虚拟模块 id 形如 pages/home/index.uvue?vue&type=script&setup=true------其中并不包含 .vue 子串(.uvue?vue 中间是 ?),因此识别失败:

  • defineUniPage(...) 调用不会在构建时被移除,残留进产物 → 运行时 ReferenceError
  • isRouteConfigRequest 仅依赖 ?vuetype=,对 .uvue 可正常命中,<route-config> 拦截不受影响

2.2 修复方式

识别规则改为正则:

typescript 复制代码
return /\.(vue|uvue|nvue)(\?|$)/i.test(id) && /[?&]type=script/.test(id)

实测:.uvue?vue&type=script&setup=true ✅ 命中;.uvue?vue&type=route-config&index=0type=template ✅ 不误命中;.vue / .nvue 行为不变。generatePages / generateUni 两处同步修正。

2.3 影响说明

该缺陷只影响 .uvue 页面使用 defineUniPage 宏的场景;仅用 <route-config> 自定义块的项目不受影响。


三、修复范围

项目 说明
主包 + 分包 扩展名按主包 / 分包各自扫描目录相对路径动态剥离
generatePages 独立使用与 generateUni 阶段一共享 producePages,同时生效
generateUni 阶段一 pages.json、阶段二路由配置(内存直传)均基于正确路径,无需改动
js_sdk(uni_modules 内嵌) 已同步重建,嵌入式 uni-app 插件包可直接使用
文档 generate-pages.md(zh/en)includeExtensions 说明补充「生成的 path 不含扩展名」

四、升级步骤与注意事项

  1. 升级依赖:devDependencies@meng-xi/vite-plugin 改为 ^1.4.1
  2. 重新生成一次 pages.json:删除或保留均可,插件将基于正确逻辑重写 path
  3. .uvue 页面沿用 defineUniPage 宏无需改动;若此前因该缺陷而改用 <route-config>,可改回宏写法
  4. 自定义扩展名(非 .vue / .nvue / .uvue)同样受支持,但 <route-config> 自定义块与 defineUniPage 宏仍要求页面为 Vue SFC 家族文件

本文基于 @meng-xi/vite-plugin@1.4.1 版本撰写。

相关推荐
颜进强1 小时前
从零搭一套 WorkBuddy Skill 骨架:调接口 → 生成 HTML 报告的分层设计与流转拆解
前端·后端·ai编程
YHL1 小时前
🔍 结构化输出:从 `JSON.parse` 到 `withStructuredOutput` 的三级火箭
前端·深度学习
YHL1 小时前
🚰流式输出:把 LLM 的每个字,像水一样送到浏览器
前端·javascript
秋天的一阵风1 小时前
⚡2026 年了,十万级表格还只会「虚拟滚动」?难怪你的页面照样卡顿
前端·javascript·面试
秋天的一阵风1 小时前
🤖 AI写代码越跑越快,项目组件却越来越乱?一套工程闭环根治重复造轮子 ⚡
前端·面试·ai编程
恋猫de小郭2 小时前
Flutter GSoC 2026 提案进度解读,补上 DevTools、FFI 和原生平台的关键缺口
android·前端·flutter
尘世中一位迷途小书童2 小时前
我为什么在 Windows 上做了一个翻译软件:SnapLingo
前端·人工智能·机器学习
志尊宝2 小时前
Vue3 零基础每日笔记(029):插槽 slot 三连——默认、具名、作用域一次讲透
前端·javascript·vue.js·vue·前端开发