diff --git a/docs/reference/client-api.md b/docs/reference/client-api.md index 89ca1d6b4a..23c94eedd0 100644 --- a/docs/reference/client-api.md +++ b/docs/reference/client-api.md @@ -90,18 +90,24 @@ Client API is provided by [@vuepress/client](https://www.npmjs.com/package/@vuep - Also see: - [Guide > Assets > Base Helper](../guide/assets.md#base-helper) -## hasPage + +## getPagesPath - Details: + Returns all pages path, replacement of `router.getRoutes()`. + +## isPageExist + +- Details: Returns whether the corresponding path has a page. -## resolve +## resolvePage - Details: - Returns the route and related page metadata corresponding to the path, similar to `router.resolve()`. + Returns the route and related page metadata corresponding to the path, replacement of `router.resolve()`. ## Constants diff --git a/docs/zh/reference/client-api.md b/docs/zh/reference/client-api.md index 477eeb9431..6b3ce410f2 100644 --- a/docs/zh/reference/client-api.md +++ b/docs/zh/reference/client-api.md @@ -90,17 +90,23 @@ - 参考: - [指南 > 静态资源 > Base Helper](../guide/assets.md#base-helper) -## hasPage +## getPagesPath + +- 详情: + + 返回所有页面路径,替代 `router.getRoutes()`。 + +## isPageExist - 详情: 返回对应的路径是否存在相应页面。 -## resolve +## resolvePage - 详情: - 返回路径对应的路由和相关页面的元数据,类似 `router.resolve()`。 + 返回路径对应的最终路径和相关页面的元数据,替代 `router.resolve()`。 ## 常量 diff --git a/packages/client/src/components/Content.ts b/packages/client/src/components/Content.ts index ccee055fff..ca3449a848 100644 --- a/packages/client/src/components/Content.ts +++ b/packages/client/src/components/Content.ts @@ -1,6 +1,5 @@ -import { pagesMap } from '@internal/pagesMap' import { computed, defineComponent, h } from 'vue' -import { usePageData } from '../composables/index.js' +import { pagesMap, usePageData } from '../composables/index.js' /** * Markdown rendered content @@ -20,7 +19,7 @@ export const Content = defineComponent({ setup(props) { const page = usePageData() const pageComponent = computed( - () => pagesMap.get(props.url || page.value.path)?.comp, + () => pagesMap.value.get(props.url || page.value.path)?.comp, ) return () => pageComponent.value diff --git a/packages/client/src/composables/pagesMap.ts b/packages/client/src/composables/pagesMap.ts index b288009223..7213ba3a0e 100644 --- a/packages/client/src/composables/pagesMap.ts +++ b/packages/client/src/composables/pagesMap.ts @@ -17,3 +17,10 @@ export const pagesMap: PagesMapRef = ref(pagesMapRaw) * Returns the ref of pages map */ export const usePagesMap = (): PagesMapRef => pagesMap + +if (__VUEPRESS_DEV__ && (import.meta.webpackHot || import.meta.hot)) { + // reuse vue HMR runtime + __VUE_HMR_RUNTIME__.updatePagesMap = (data: PagesMap) => { + pagesMap.value = data + } +} diff --git a/packages/client/src/helpers/router.ts b/packages/client/src/helpers/router.ts index f08854b3bc..28971e215c 100644 --- a/packages/client/src/helpers/router.ts +++ b/packages/client/src/helpers/router.ts @@ -1,22 +1,36 @@ -import { pagesMap } from '@internal/pagesMap' import type { PagesMap } from '@internal/pagesMap' +import { pagesMap } from '../composables/index.js' import { resolvers } from '../resolvers.js' +/** + * Get all paths of pages + * + * @returns all paths of pages + */ +export const getPagesPath = (): string[] => Object.keys(pagesMap.value) + /** * Check whether the page exists * * @param path path of the page + * @returns whether the page exists */ -export const hasPage = (path: string): boolean => - pagesMap.has(resolvers.resolvePagePath(pagesMap, path)) +export const isPageExist = (path: string): boolean => + pagesMap.value.has(resolvers.resolvePagePath(pagesMap.value, path)) +/** + * Resolve final path and meta with given path + * + * @param path path of the page + * @returns resolved path and meta + */ export const resolve = ( path: string, ): { path: string; meta: PageMeta | null } => { - path = resolvers.resolvePagePath(pagesMap, path) + path = resolvers.resolvePagePath(pagesMap.value, path) return { path, - meta: (pagesMap as PagesMap).get(path)?.meta ?? null, + meta: (pagesMap.value as PagesMap).get(path)?.meta ?? null, } } diff --git a/packages/client/src/router.ts b/packages/client/src/router.ts index 8096ffd8df..ab39f927af 100644 --- a/packages/client/src/router.ts +++ b/packages/client/src/router.ts @@ -1,4 +1,3 @@ -import { pagesMap } from '@internal/pagesMap' import { removeEndingSlash } from '@vuepress/shared' import type { Router } from 'vue-router' import { @@ -8,6 +7,7 @@ import { START_LOCATION, } from 'vue-router' import { Vuepress } from './components/Vuepress.js' +import { pagesMap } from './composables/index.js' import type { PageData } from './composables/index.js' import { resolvers } from './resolvers.js' @@ -42,14 +42,15 @@ export const createVueRouter = (): Router => { // and save page data to route meta router.beforeResolve(async (to, from): Promise => { if (to.path !== from.path || from === START_LOCATION) { - const pagePath = resolvers.resolvePagePath(pagesMap, to.path) + const pagePath = resolvers.resolvePagePath(pagesMap.value, to.path) if (pagePath !== to.path) { return pagePath } // if no match at this point, then we should provide 404 page - const pageInfo = pagesMap.get(pagePath) || pagesMap.get('/404.html')! + const pageInfo = + pagesMap.value.get(pagePath) || pagesMap.value.get('/404.html')! // TODO: Added for backwards compatibility, remove in stable version to.meta = pageInfo.meta diff --git a/packages/core/src/app/prepare/preparePageMap.ts b/packages/core/src/app/prepare/preparePageMap.ts index ee465b43cf..d12798328d 100644 --- a/packages/core/src/app/prepare/preparePageMap.ts +++ b/packages/core/src/app/prepare/preparePageMap.ts @@ -1,11 +1,26 @@ import type { App } from '../../types/index.js' +const HMR_CODE = ` +if (import.meta.webpackHot) { + import.meta.webpackHot.accept() + if (__VUE_HMR_RUNTIME__.updatePagesMap) { + __VUE_HMR_RUNTIME__.updatePagesMap(pagesMap) + } +} + +if (import.meta.hot) { + import.meta.hot.accept(({ pagesMap }) => { + __VUE_HMR_RUNTIME__.updatePagesMap(pagesMap) + }) +} +` + /** * Generate page map temp file */ export const preparePagesMap = async (app: App): Promise => { // generate page component map file - const content = `\ + let content = `\ import { defineAsyncComponent } from 'vue' export const pagesMap = new Map([ @@ -35,5 +50,10 @@ export const pagesMap = new Map([ ]) ` + // inject HMR code + if (app.env.isDev) { + content += HMR_CODE + } + await app.writeTemp('internal/pagesMap.js', content) }