v1.4.0:新增 defineUniPage 宏声明页面配置,架构全面重构

版本:1.4.0 | 协议:MIT | 依赖:Vite >=5.0.0 <9.0.0


写在前面

v1.4.0 的主题是:新增 defineUniPage 宏声明页面配置,并重构页面生成架构,统一监听与串行生成

v1.3.0 通过 generateUni 将「扫描页面 → pages.json → 路由配置」收敛为一条流水线,但页面配置仍依赖 <route-config> 自定义块。v1.4.0 新增 defineUniPage 宏------在 <script setup>(或 <script> 顶层)中直接调用声明页面配置,功能与 <route-config> 一致、写法更贴近 JS/TS,且优先级更高

同时,本版抽取公共 producePages() 流水线消除 generatePages / generateUni 的重复代码,新增 DirectoryWatcher / TaskQueue 公共模块统一三个生成插件的监听与串行生成,并增强 factory 的类型安全。

本版重点

能力 一句话说明 你需要做什么
新增 defineUniPage <script setup> 中调用宏声明页面配置,优先级高于 <route-config> 用宏替换 <route-config>(可选)
宏类型声明自动生成 自动生成全局 dts,IDE 开箱识别宏(dts 可自定义或关闭) 无需配置,自动生效
页面生成架构重构 抽取公共 producePages() 流水线,消除 generatePages / generateUni 重复代码 无感知,行为等价
公共模块新增 DirectoryWatcher(目录递归监听)/ TaskQueue(串行任务队列) 可直接按需导入使用
监听与串行化统一 generatePages / generateUni / generateRouter 三者统一串行队列 + 目录监听 无需配置,自动生效
factory 类型增强 新增 FunctionHookMap / getBaseDefaults(),钩子注册更类型安全 插件开发者无感,类型导出保持兼容

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


一、5 分钟快速上手

1.1 安装与升级

json 复制代码
{
	"devDependencies": {
		"@meng-xi/vite-plugin": "^1.4.0"
	}
}

1.2 用宏声明页面配置

vue 复制代码
<!-- src/pages/mine/mine.vue -->
<script setup lang="ts">
defineUniPage({
	title: '我的',
	name: 'MinePage',
	isTab: true,
	tab: { text: '我的', order: 2 }
})
</script>
  • 无需 import ,插件默认自动生成全局类型声明 src/define-uni-page.d.ts,IDE(Vue (Official) / Volar / tsc)直接识别,获得类型提示与编译期检查
  • 同一页面同时声明宏与 <route-config> 时,以宏为准(顶层字段按宏覆盖)
  • 宏在扫描时被消费,构建时自动移除调用,运行时不留痕

1.3 关闭或自定义宏类型声明

typescript 复制代码
generatePages({
	// 自定义输出路径
	dts: 'types/define-uni-page.d.ts'
})
// 或关闭自动生成
generatePages({ dts: false })

generateUni 通过 pages.dts 配置,用法一致。


二、defineUniPage 宏详解

2.1 能力总览

能力 说明
优先级 高于 <route-config>:同时声明时顶层同名字段以宏为准
参数 JS 对象字面量,支持注释、单引号、尾随逗号与嵌套对象(tab / style / meta
适用位置 <script setup><script> 顶层
运行时无痕 扫描时消费 + transform 自动移除调用,无需 import、不会 ReferenceError
IDE 识别 自动生成全局声明(默认 src/define-uni-page.d.ts),Vue (Official) / Volar / tsc 开箱识别

2.2 与 <route-config> 的优先级

同一页面同时声明宏与自定义块时,顶层字段以宏为准:

vue 复制代码
<script setup lang="ts">
defineUniPage({ title: '首页(宏优先)' })
</script>

<route-config lang="jsonc">
{
	"title": "首页",
	"isTab": true
}
</route-config>

最终 pages.json 中标题为宏的 '首页(宏优先)'

2.3 <route-config> 增强:JSONC

<route-config> 自定义块解析同步支持 JSONC (注释 + 尾随逗号),与 lang="jsonc" 的 IDE 高亮语义一致:

vue 复制代码
<route-config lang="jsonc">
{
	// 支持注释与尾随逗号
	"title": "首页",
	"isTab": true
}
</route-config>

三、页面生成架构重构

3.1 抽取公共 producePages 流水线

新增 generatePages/helpers/produce.ts 的公共 producePages() 函数,将「扫描页面 + <route-config> / defineUniPage → 组装 → 合并」抽取为内存流水线:

  • generatePages 直接写盘;generateUni 内存直传阶段二,消除「先写盘再读盘」的往返
  • 删除 generateUni 内部重复实现(约 76 行),统一复用 generatePages 公共逻辑

3.2 监听与串行化统一

  • generatePages / generateUni / generateRouter 三者统一使用 TaskQueue 串行生成,避免高频变更时并发读改写竞态
  • generatePages / generateUni 统一使用 DirectoryWatcher 管理页面目录监听(此前为各自私有的 fs.watch 循环)
  • generateRouter 监听 pages.json 变更时同样走串行队列(此前直接 await 重新生成)

四、公共模块(新增)

4.1 DirectoryWatcher(common/fs)

目录递归监听器,统一管理多目录监听:

typescript 复制代码
import { DirectoryWatcher } from '@meng-xi/vite-plugin/common/fs'

const watcher = new DirectoryWatcher({
	dirs: ['/abs/pages', '/abs/pages-sub'],
	onChange: () => regenerate(),
	logger: { info: console.log, warn: console.warn },
	label: '页面目录'
})
watcher.start() // 返回成功建立监听的目录数量
watcher.stop()
  • 提供 start() / stop() / size
  • 平台不支持 recursive 时自动降级跳过并告警,避免插件崩溃

4.2 TaskQueue(common/concurrency)

串行任务队列,将异步任务按提交顺序依次执行:

typescript 复制代码
import { TaskQueue } from '@meng-xi/vite-plugin/common/concurrency'

const queue = new TaskQueue()
queue.run(() => generate()) // 第二个任务等待第一个完成后执行
queue.run(() => generate())
  • 单个任务失败不阻塞后续任务
  • 适用于高频触发(如文件监听)时避免并发读改写竞态

五、factory 增强

5.1 FunctionHookMap

新增 FunctionHookMap 类型:registerHook / registerOrderedHook 的钩子名泛型约束从 keyof Plugin 收紧为仅限函数型钩子,排除 name / enforce / apply 等非函数属性,提升钩子注册的编译期类型安全。

5.2 getBaseDefaults

新增可重写的 getBaseDefaults() 方法,将基础默认配置(enabled / verbose / errorStrategy)提取为子类可覆盖的独立方法,便于自定义插件调整基础默认值。


六、细节修复

  • generatePages / generateUni 的 <route-config> 虚拟模块请求匹配由 id.includes('vue') 收紧为 id.includes('?vue'),避免误拦截
  • <route-config> 解析支持 JSONC 尾随逗号,与 lang="jsonc" 的 IDE 高亮语义一致

七、插件清单(不变)

插件总数维持 17 个、7 个分组,本版无新增 / 删除插件,重点是能力增强与内部重构。

分组 插件
generate autoImportgenerateUnigeneratePagesgenerateRoutergenerateVersion
analyze buildProgressbundleAnalyzer
compress compressAssetsimageOptimizer
copy assetManifestcopyFile
guard envGuard
inject faviconManagerhtmlInjectloadingManagerversionUpdateChecker
proxy proxyManager

八、实战场景

8.1 uni-app 项目:宏 + 流水线

typescript 复制代码
// vite.config.ts
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import { generateUni } from '@meng-xi/vite-plugin'

export default defineConfig({
	plugins: [
		uni(),
		generateUni({
			pagesJsonPath: 'src/pages.json',
			pages: {
				pagesDir: 'src/pages',
				subPackages: [{ root: 'pages-sub', dir: 'src/pages-sub' }],
				entryPage: 'pages/index/index',
				dts: 'src/define-uni-page.d.ts', // defineUniPage 宏的全局类型声明
				tabBar: { color: '#999999', selectedColor: '#42b883' }
			},
			router: {
				outputPath: 'src/router.config.ts',
				dts: 'src/router.d.ts'
			}
		})
	]
})

页面内就近声明(宏优先):

vue 复制代码
<!-- src/pages/index/index.vue -->
<script setup lang="ts">
defineUniPage({
	title: '首页',
	isTab: true,
	tab: { order: 0 }
})
</script>

8.2 独立使用公共模块

typescript 复制代码
// 串行化高频任务
import { TaskQueue } from '@meng-xi/vite-plugin/common/concurrency'

// 递归监听目录
import { DirectoryWatcher } from '@meng-xi/vite-plugin/common/fs'

九、注意事项

  • defineUniPage 宏参数需为纯对象字面量(不支持变量 / 表达式),否则静默忽略
  • 宏在构建时被自动移除,无需 import ,但需保证 IDE 识别(dts 默认生成,或项目 tsconfig include 已生成的声明文件)
  • 同时声明宏与 <route-config> 时以宏为准;若仅用 <route-config>,建议添加 lang="jsonc" 获得 IDE 高亮
  • 架构重构为内部实现,generatePages / generateUni / generateRouter 对外 API 与行为完全兼容
  • DirectoryWatcher / TaskQueue 为新增公共导出,子路径导入即可使用,不影响原有 API

写在最后

v1.4.0 让页面配置声明从「模板块」升级为「宏调用」:defineUniPage 一个函数、一处调用、类型安全,且优先级天然高于 <route-config>

  • 宏能力让页面配置更贴近 JS/TS 开发习惯,配合自动生成的全局声明,IDE 体验与 Vue 官方宏一致
  • 架构重构抽取公共流水线与公共模块,三个生成插件统一监听与串行生成,代码更精简、行为更一致
  • 零破坏性升级让 1.x 用户可平滑迁移

后续版本将聚焦于:宏的更多配置来源(如 manifest.json)、uni-app 条件编译深度集成。如果你有任何建议或问题,欢迎在 GitHub Issues 反馈。

相关推荐
泯泷8 小时前
那段文字是谁删的?Yjs 14 正式版之前,一套删除归属方案的实现与边界
前端·javascript·算法
野槐10 小时前
前端项目优化(有了我,会发生...)
前端
aa小小11 小时前
【无标题】
前端
计算机魔术师12 小时前
还在单线程跟 AI 聊天?Claude Code 并行多会话让你一个人干三个人的活
前端
志尊宝12 小时前
Vue3 零基础每日笔记(038):亲手封装 useDebounceFn 与 useThrottleFn——高频事件的流量阀
前端·javascript·vue·html·vue3
JavaGuide12 小时前
对标 MinIO!全新一代分布式文件系统正式发布
前端·后端
风骏时光牛马12 小时前
AI驱动自动化业务工作流搭建实践
前端
码云之上12 小时前
Skill 里的脚本终于能跑了,星悟接 CubeSandbox 的纪实
前端·人工智能·前端框架
IT_陈寒13 小时前
Vue computed属性这个坑,我居然踩了三次才爬出来
前端·人工智能·后端
烈风逍遥13 小时前
第三篇:组件化实践,SpTable 通用表格组件设计
前端·架构