# hrouter **Repository Path**: Duke_Bit/hrouter ## Basic Information - **Project Name**: hrouter - **Description**: HarmonyOS 路由解决方案 解决HSP路由跳转负责的问题 - **Primary Language**: TypeScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 6 - **Forks**: 1 - **Created**: 2024-05-07 - **Last Updated**: 2026-07-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: HarmonyOS组件, Router, OpenHarmony组件 ## README # HRouter HarmonyOS 路由框架。编译期 hvigor 插件扫描装饰器生成路由表,运行时 `HRouter` + `RouteBuilder` 完成页面跳转、服务发现、拦截器、生命周期。 ## 安装 `hrouter` 是运行时 HAR 包,`hrouter-compiler` 是编译期 hvigor 插件。两者必须同时安装。 ```json5 // oh-package.json5 { "dependencies": { "hrouter": "^2.0.0", } } ``` ```json5 // hvigor/hvigor-config.json5(项目根 hvigor 目录) { "dependencies": { "hrouter-compiler": "^2.0.0" // 这一行告诉 hvigor 把 hrouter-compiler 当 plugin 加载 } } ``` ```typescript // hvigorfile.ts (项目根) import { appTasks } from '@ohos/hvigor-ohos-plugin'; import { hrouterPlugin } from 'hrouter-compiler'; export default { system: appTasks, plugins: [hrouterPlugin({ exclude: ['library'], scanPaths: ['src/main/ets/pages', 'src/main/ets/services', 'src/main/ets/interceptors'], root: 'entry' })] } ``` > hvigor 加载 plugin 的链路:`hvigor-config.json5` 声明要加载哪些 npm 包作为 hvigor 插件;`hvigorfile.ts` `import` 这些包并实例化它们。所以两步都缺一不可。 发布到 OHPM 后使用上述版本号;本仓库内开发时 `ohpm` 安装使用 `file:../library` + `file:../hrouter-compiler`。 ## 三步接入 ### 1. 启动时初始化 ```typescript // EntryAbility.onWindowStageCreate HRouter.init(this.context, { enableLog: true }); ``` 就这一行。本模块装饰器的加载由插件自动织入完成:编译期插件会在 EntryAbility 最后一个 import 后写入一行 `import '../_generated/hrouter/EntryRegistry';`(带 AUTO-GENERATED 标记,幂等,被删后下次构建自动恢复)。sibling(HAR/HSP)模块无需任何手工 import,由框架按需自动挂载(见 `library/README.md` 的「按需加载机制」)。 ### 2. 标记页面 ```typescript @Route({ name: 'user_detail', title: '用户详情' }) @ComponentV2 export struct UserDetail { /* ... */ } ``` ### 3. 注册栈 + 跳转 ```typescript // 单 Navigation aboutToAppear() { HRouter.registerNavPathStack(HR_DEFAULT_STACK_NAME, this.pageStack); } // 多 Navigation / 多 Tab HRouter.registerNavPathStack('tab_a', this.stackA); HRouter.registerNavPathStack('tab_b', this.stackB); // 跳转 HRouter.build('tab_a').withParam({ id: 1 }).push('user_detail'); ``` ## 关键示例 ### 链式跳转 + onPop 回调(NavPathStack 11+ 原生机制) ```typescript // 发起 push 的页面 HRouter.build('home') .withParam({ userId: 1 }) .withOnPop((info: PopInfo) => console.info('result:', info.result)) .push('page_b'); // 被 push 的页面回传 HRouter.build().pop({ success: true }); ``` ### 拦截器链 ```typescript // 全局拦截器:对所有路由生效。注意:不得再被 @Route(interceptors) 显式引用(编译期硬校验) @Interceptor({ priority: 10 }) export class AuthCheck implements RouteInterceptor { onIntercept(ctx: RouteContext): boolean { return isLoggedIn(); } } // 路由级拦截器:仅 @Route(interceptors) 显式绑定的路由触发 @Interceptor({ priority: 5, global: false }) export class RegionCheck implements RouteInterceptor { /* ... */ } HRouter.build().pushDestination('home') .catch((err: Error) => { if (err instanceof RouteInterceptError) { // err.interceptedResult: { reason, interceptor, message } } }); ``` ### 服务发现 ```typescript @Service('ILogger') @ComponentV2 export class ConsoleLogger implements ILogger { /* ... */ } const logger = await HRouter.getService('ILogger'); const allLoggers = await HRouter.getAllServices(ILogger); ``` ### 目标页面取参数 ```typescript aboutToAppear() { const params = HRouter.getParams>(this); // this 直传 } ``` ## 模块组成 | 模块 | 类型 | 角色 | |------------------|-----|-----------------------------------------| | `library` | HAR | 运行时 API + 装饰器。排除扫描。 | | `shared` | HAR | 共享服务/拦截器。 | | `feature` | HSP | 功能模块。 | | `entry` | HAP | 应用入口,唯一生成 `service_map.json`。 | | `hrouter-compiler` | npm | hvigor 编译期插件(npm 名 `hrouter-compiler`)。 | ## 按需加载机制(HAR/HSP) 用到的模块才被加载,无需在 EntryAbility 静态 import 任何业务模块: - **本模块服务/拦截器**:启动时经插件织入 EntryAbility 的一行 `import '../_generated/hrouter/EntryRegistry'` 触发装饰器自注册; - **sibling 全局拦截器**:`HRouter.init` 时按模块名 `import('')` 立即挂载(首次导航前必须就绪); - **sibling 服务 / 路由级拦截器**:首次 `getService` / 首次导航到绑定路由时惰性挂载(HSP 此刻才被系统加载)。 支撑机制由 `hrouter-compiler` 编译期自动完成(零手工配置):织入 EntryAbility 的 registry import(可用 `injectEntryRegistry:false` 关闭)、注入 `build-profile.json5` 的 `arkOptions.runtimeOnly.packages`、维护 sibling `Index.ets` 的装饰器 re-export、生成 `EntryRegistry.ets`。详见 [`library/README.md`](./library/README.md)「按需加载机制」一节。 ## 编译期校验 `global: true`(含默认)的 `@Interceptor` **禁止**出现在任何 `@Route(interceptors)` 数组中 —— 全局拦截器对所有路由生效,再显式绑定会导致同一拦截器被执行两遍。违反时插件直接报错(含修复建议)并使构建失败。路由级拦截器请用 `@Interceptor({ priority: N, global: false })`。 ## 运行时调试 ```bash hilog -d 0xA001 # 按 domain 过滤 hrouter 全部日志 hilog -t hrouter # 按 tag ``` - `HRouter.init({ enableLog: false })` 可关闭 INFO/WARN/ERROR 输出(DEBUG 由 hilog 控制) - 内部日志走 `library/src/main/ets/logger/HRLog.ts` ## 环境要求 - DevEco Studio 5.0+ - Stage Model / API 12+ - `build-profile.json5` 开启 `useNormalizedOHMUrl: true` - ArkTS 1.2 严格类型(装饰器写在 `.ts`,绕开 ArkTS 类型签名限制) - `arkOptions.runtimeOnly.packages` 由插件自动注入(无需手工配置;手工已配置的项会幂等合并) ## 其他库 - [eventpost](https://ohpm.openharmony.cn/#/cn/detail/eventpost) 事件分发,支持组件中的lifecycle,在组件中使用自动取消订阅: [https://gitee.com/Duke_Bit/eventpost](https://gitee.com/Duke_Bit/eventpost) - [@duke/view-model](https://ohpm.openharmony.cn/#/cn/detail/@duke%2Fview-model) 鸿蒙版本的Lifecycle库,支持组件、Router和Navigation: [https://gitee.com/Duke_Bit/view-model](https://gitee.com/Duke_Bit/view-model) - [@duke/logan-ext](https://ohpm.openharmony.cn/#/cn/detail/@duke%2Flogan-ext) Logan扩展库,方便开箱即用: [https://gitee.com/Duke_Bit/logan](https://gitee.com/Duke_Bit/logan) - [@duke/logan](https://ohpm.openharmony.cn/#/cn/detail/@duke%2Flogan) Logan是一个为OpenHarmony开发的日志库,对美团技术团队的Logan的鸿蒙化移植版本: [https://gitee.com/Duke_Bit/logan](https://gitee.com/Duke_Bit/logan) - [@duke/websocket-client](https://ohpm.openharmony.cn/#/cn/detail/@duke%2Fwebsocket-client) WebSocket库解决官方API的一些bug问题: [https://gitee.com/Duke_Bit/websocket](https://gitee.com/Duke_Bit/websocket) - [@duke/component-lifecycle](https://ohpm.openharmony.cn/#/cn/detail/@duke%2Fcomponent-lifecycle) 鸿蒙版本的Lifecycle库,支持组件、Router和Navigation: [https://gitee.com/Duke_Bit/component-lifecycle](https://gitee.com/Duke_Bit/component-lifecycle) - [@duke/elf-dialog](https://ohpm.openharmony.cn/#/cn/detail/@duke%2Felf-dialog) CustomDialog黑魔法 不依赖promptAction 实现的函数级弹窗,省去复杂的模版代码,让你专注于你的业务,一行代码搞定弹窗: [https://gitee.com/Duke_Bit/elf-dialog](https://gitee.com/Duke_Bit/elf-dialog) - [@duke/elf-refresh](https://ohpm.openharmony.cn/#/cn/detail/@duke%2Felf-refresh) OpenHarmony 刷新组件,支持下拉刷新和上拉加载更多,支持各种组件,List、Grid,支持header,footer,目标打造HarmonyOS的SmartRefreshLayout: [https://gitee.com/Duke_Bit/ElfRefresh](https://gitee.com/Duke_Bit/ElfRefresh) - [@duke/leak-guard](https://ohpm.openharmony.cn/#/cn/detail/@duke%2Fleak-guard) 内存泄漏检测库,实时检测 ArkTS 对象的内存泄漏: [https://gitee.com/Duke_Bit/leak-canary](https://gitee.com/Duke_Bit/leak-canary) 完整更新日志见 [CHANGELOG.md](./CHANGELOG.md)。