From 50ad81103d6c0573221015b4b333a536ac77c258 Mon Sep 17 00:00:00 2001 From: libondev Date: Fri, 28 Mar 2025 16:58:09 +0800 Subject: [PATCH 1/4] refactor!: remove the `handleHotUpdate` method, which is supported by `createRouter` NOTE: `handleHotUpdate` parameter is valid only when createRouter exported in `vue-router/auto-routes` is used. --- client.d.ts | 42 +++++++++++++++++++++++++++++------------- src/core/context.ts | 8 +++++++- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/client.d.ts b/client.d.ts index e6afb9f3b..aa0228f57 100644 --- a/client.d.ts +++ b/client.d.ts @@ -1,32 +1,48 @@ declare module 'vue-router/auto-routes' { - import type { RouteRecordRaw, Router } from 'vue-router' + import type { RouteRecordRaw, Router, RouterOptions } from 'vue-router' /** * Array of routes generated by unplugin-vue-router */ export const routes: RouteRecordRaw[] + type HandleHotUpdateCallback = (newRoutes: RouteRecordRaw[]) => void + /** - * Setups hot module replacement for routes. - * @param router - The router instance - * @param hotUpdateCallback - Callback to be called after replacing the routes and before the navigation - * @example + * Creates a router instance. + * @param options - The router options + * @param hotUpdateCallback - Callback to be called after replacing the routes and before the navigation (Invalid setting when import.meta.hot is not supported). + * @example Common usage * ```ts * import { createRouter, createWebHistory } from 'vue-router' - * import { routes, handleHotUpdate } from 'vue-router/auto-routes' + * import { routes, createRouter } from 'vue-router/auto-routes' + * * const router = createRouter({ * history: createWebHistory(), * routes, * }) - * if (import.meta.hot) { - * handleHotUpdate(router) - * } + * ``` + * + * @example Hot module replacement + * ```ts + * import { createRouter, createWebHistory } from 'vue-router' + * import { routes, createRouter } from 'vue-router/auto-routes' + * + * const router = createRouter( + * { + * history: createWebHistory(), + * routes, + * }, + * (newRoutes) => { + * console.log('🔥 HMR with', newRoutes) + * } + * ) * ``` */ - export function handleHotUpdate( - router: Router, - hotUpdateCallback?: (newRoutes: RouteRecordRaw[]) => void - ): void + export function createRouter( + options: RouterOptions, + hotUpdateCallback?: HandleHotUpdateCallback + ): Router } declare module 'vue-router' { diff --git a/src/core/context.ts b/src/core/context.ts index 5d9de314e..26dafe2be 100644 --- a/src/core/context.ts +++ b/src/core/context.ts @@ -188,11 +188,17 @@ export function createRoutesContext(options: ResolvedOptions) { )}\n` let hmr = ts` -export function handleHotUpdate(_router, _hotUpdateCallback) { +import { createRouter as createVueRouter } from 'vue-router' + +export function createRouter(options, _hotUpdateCallback) { + const _router = createVueRouter(options || {}) + if (import.meta.hot) { import.meta.hot.data.router = _router import.meta.hot.data.router_hotUpdateCallback = _hotUpdateCallback } + + return _router } if (import.meta.hot) { From b9c707621006e95069921ada6c005ab01c31f5bb Mon Sep 17 00:00:00 2001 From: libondev Date: Fri, 28 Mar 2025 16:59:21 +0800 Subject: [PATCH 2/4] chore(playground): update playground code --- playground/src/router.ts | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/playground/src/router.ts b/playground/src/router.ts index 69e44b1c9..889adf5b7 100644 --- a/playground/src/router.ts +++ b/playground/src/router.ts @@ -1,11 +1,16 @@ -import { createRouter, createWebHistory } from 'vue-router' -import { routes, handleHotUpdate } from 'vue-router/auto-routes' +import { createWebHistory } from 'vue-router' +import { routes, createRouter } from 'vue-router/auto-routes' import type { RouteRecordInfo, ParamValue } from 'vue-router' -export const router = createRouter({ - history: createWebHistory(), - routes, -}) +export const router = createRouter( + { + history: createWebHistory(), + routes, + }, + (routes) => { + console.log('🔥 HMR', routes) + } +) function addRedirects() { router.addRoute({ @@ -14,15 +19,7 @@ function addRedirects() { }) } -if (import.meta.hot) { - handleHotUpdate(router, (routes) => { - console.log('🔥 HMR with', routes) - addRedirects() - }) -} else { - // production - addRedirects() -} +addRedirects() // manual extension of route types declare module 'vue-router/auto-routes' { From 486062af3eff819922ebd58f8074eb472cc70fd5 Mon Sep 17 00:00:00 2001 From: libondev Date: Fri, 28 Mar 2025 17:43:35 +0800 Subject: [PATCH 3/4] chore: update docs --- docs/guide/hmr.md | 48 ++++++++++++-------------------------------- docs/introduction.md | 10 +++------ 2 files changed, 16 insertions(+), 42 deletions(-) diff --git a/docs/guide/hmr.md b/docs/guide/hmr.md index c85a60608..fbd729174 100644 --- a/docs/guide/hmr.md +++ b/docs/guide/hmr.md @@ -2,38 +2,25 @@ When using `definePage()` and `` blocks, it's possible to enable Hot Module Replacement (HMR) for your routes **and avoid the need of reloading the page or the server** when you make changes to your routes. -Enabling HMR is **strongly recommended** and currently **only works with Vite**. - -```ts [src/router.ts] -import { createRouter, createWebHistory } from 'vue-router' -import { - routes, - handleHotUpdate, // [!code ++] -} from 'vue-router/auto-routes' - -export const router = createRouter({ - history: createWebHistory(), - routes, -}) - -// This will update routes at runtime without reloading the page -if (import.meta.hot) { // [!code ++] - handleHotUpdate(router) // [!code ++] -} // [!code ++] -``` +Enabling HMR is **strongly recommended** and currently **only works with Vite**. But you don't need to do anything, because this step has been done for you internally. ## Runtime routes If you add routes at runtime, you will have to add them within a callback to ensure they are added during development. ```ts{16-23} [src/router.ts] -import { createRouter, createWebHistory } from 'vue-router' -import { routes, handleHotUpdate } from 'vue-router/auto-routes' - -export const router = createRouter({ - history: createWebHistory(), - routes, -}) +import { createWebHistory } from 'vue-router' +import { routes, createRouter } from 'vue-router/auto-routes' + +export const router = createRouter( + { + history: createWebHistory(), + routes, + }, + () => { + addRedirects() + } +) function addRedirects() { router.addRoute({ @@ -41,15 +28,6 @@ function addRedirects() { redirect: '/about?from=/new-about', }) } - -if (import.meta.hot) { - handleHotUpdate(router, (newRoutes) => { - addRedirects() - }) -} else { - // production - addRedirects() -} ``` diff --git a/docs/introduction.md b/docs/introduction.md index 71e4147e2..c37d1d34d 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -188,8 +188,9 @@ Given the following route configuration: ::: code-group ```ts [src/router.ts] -import { createRouter, createWebHistory } from 'vue-router' -import { routes, handleHotUpdate } from 'vue-router/auto-routes' // [!code ++] +import { createRouter, createWebHistory } from 'vue-router' // [!code --] +import { createWebHistory } from 'vue-router/auto-routes' // [!code ++] +import { routes, createRouter } from 'vue-router/auto-routes' // [!code ++] export const router = createRouter({ history: createWebHistory(), @@ -209,11 +210,6 @@ export const router = createRouter({ ] // [!code --] routes, // [!code ++] }) - -// This will update routes at runtime without reloading the page -if (import.meta.hot) { // [!code ++] - handleHotUpdate(router) // [!code ++] -} // [!code ++] ``` ```ts{2,5} [main.ts] From 3529121c58445d56bda5305a67fec66822e0e045 Mon Sep 17 00:00:00 2001 From: libondev Date: Fri, 28 Mar 2025 17:48:15 +0800 Subject: [PATCH 4/4] chore: ensure that you can perform at least one callback when hmr is not supported --- client.d.ts | 3 ++- src/core/context.ts | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/client.d.ts b/client.d.ts index aa0228f57..719410e64 100644 --- a/client.d.ts +++ b/client.d.ts @@ -11,7 +11,8 @@ declare module 'vue-router/auto-routes' { /** * Creates a router instance. * @param options - The router options - * @param hotUpdateCallback - Callback to be called after replacing the routes and before the navigation (Invalid setting when import.meta.hot is not supported). + * @param hotUpdateCallback - Callback to be called after replacing the routes and before the navigation. + * (If `import.meta.hot` is not supported, it will only be executed once during initialization.) * @example Common usage * ```ts * import { createRouter, createWebHistory } from 'vue-router' diff --git a/src/core/context.ts b/src/core/context.ts index 26dafe2be..523ac69c4 100644 --- a/src/core/context.ts +++ b/src/core/context.ts @@ -196,6 +196,8 @@ export function createRouter(options, _hotUpdateCallback) { if (import.meta.hot) { import.meta.hot.data.router = _router import.meta.hot.data.router_hotUpdateCallback = _hotUpdateCallback + } else if (typeof _hotUpdateCallback === 'function') { + _hotUpdateCallback(_router.getRoutes()) } return _router