Skip to content

Commit 8ce1d27

Browse files
committed
feat: support clean url and improve route resolve
1 parent 46bd7ba commit 8ce1d27

File tree

25 files changed

+335
-247
lines changed

25 files changed

+335
-247
lines changed

.eslintrc.cjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
module.exports = {
22
root: true,
33
extends: 'vuepress',
4+
5+
// FIXME: This should be added to `eslint-config-vuepress`
6+
globals: {
7+
__VUEPRESS_CLEAN_URL__: 'readonly',
8+
},
9+
410
overrides: [
511
{
612
files: ['*.ts', '*.vue', '*.cts'],

packages/bundler-vite/src/plugins/vuepressMainPlugin.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ const resolveDefine = async ({
205205
const define: UserConfig['define'] = {
206206
__VUEPRESS_VERSION__: JSON.stringify(app.version),
207207
__VUEPRESS_BASE__: JSON.stringify(app.options.base),
208+
__VUEPRESS_CLEAN_URL__: JSON.stringify(app.options.route.cleanUrl),
208209
__VUEPRESS_DEV__: JSON.stringify(!isBuild),
209210
__VUEPRESS_SSR__: JSON.stringify(isServer),
210211
// @see http://link.vuejs.org/feature-flags

packages/bundler-webpack/src/config/handlePluginDefine.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const handlePluginDefine = async ({
2121
{
2222
__VUEPRESS_VERSION__: JSON.stringify(app.version),
2323
__VUEPRESS_BASE__: JSON.stringify(app.options.base),
24+
__VUEPRESS_CLEAN_URL__: JSON.stringify(app.options.route.cleanUrl),
2425
__VUEPRESS_DEV__: JSON.stringify(!isBuild),
2526
__VUEPRESS_SSR__: JSON.stringify(isServer),
2627
// @see http://link.vuejs.org/feature-flags

packages/cli/src/commands/dev/watchPageFiles.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const watchPageFiles = (app: App): FSWatcher[] => {
4141
app.pages.forEach((page) => addDeps(page))
4242

4343
// watch page files
44-
const pagesWatcher = chokidar.watch(app.options.pagePatterns, {
44+
const pagesWatcher = chokidar.watch(app.options.route.pagePatterns, {
4545
cwd: app.dir.source(),
4646
ignoreInitial: true,
4747
})

packages/client/src/router/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ export { useRoute, useRouter } from 'vue-router'
33

44
export * from './resolveRoute.js'
55
export * from './resolveRouteFullPath.js'
6+
export * from './resolveRouteKey.js'
67
export * from './resolveRoutePath.js'

packages/client/src/router/resolveRoute.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { resolvePathInfo } from '@vuepress/shared'
1+
import { resolvePathInfo, resolveRoutePathWithExt } from '@vuepress/shared'
22
import { routes } from '../internal/routes.js'
33
import type { Route, RouteMeta } from '../types/index.js'
4-
import { resolveRoutePath } from './resolveRoutePath.js'
4+
import { resolveRouteKey } from './resolveRouteKey.js'
55

66
export interface ResolvedRoute<T extends RouteMeta = RouteMeta>
77
extends Route<T> {
@@ -20,20 +20,22 @@ export const resolveRoute = <T extends RouteMeta = RouteMeta>(
2020
const [pathname, hashAndQueries] = resolvePathInfo(path)
2121

2222
// resolve the route path
23-
const routePath = resolveRoutePath(pathname, currentPath)
24-
const routeFullPath = routePath + hashAndQueries
23+
const routeKey = resolveRouteKey(pathname, currentPath)
24+
const routeFullPath = __VUEPRESS_CLEAN_URL__
25+
? routeKey
26+
: resolveRoutePathWithExt(routeKey) + hashAndQueries
2527

2628
// the route not found
27-
if (!routes.value[routePath]) {
29+
if (!routes.value[routeKey]) {
2830
return {
29-
...routes.value['/404.html'],
31+
...routes.value['/404'],
3032
path: routeFullPath,
3133
notFound: true,
3234
} as ResolvedRoute<T>
3335
}
3436

3537
return {
36-
...routes.value[routePath],
38+
...routes.value[routeKey],
3739
path: routeFullPath,
3840
notFound: false,
3941
} as ResolvedRoute<T>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { normalizeRoutePath } from '@vuepress/shared'
2+
import { redirects, routes } from '../internal/routes.js'
3+
4+
/**
5+
* Resolve route path with given raw path
6+
*/
7+
export const resolveRouteKey = (
8+
pathname: string,
9+
currentPath?: string,
10+
): string => {
11+
// normalized path
12+
const routePath = normalizeRoutePath(pathname, currentPath)
13+
14+
// check if the normalized path is in routes
15+
if (routes.value[routePath]) return routePath
16+
17+
// check encoded path
18+
const encodedRoutePath = encodeURI(routePath)
19+
20+
if (routes.value[encodedRoutePath]) {
21+
return encodedRoutePath
22+
}
23+
24+
// check redirected path with normalized path and encoded path
25+
const redirectedRoutePath =
26+
redirects.value[routePath] || redirects.value[encodedRoutePath]
27+
28+
if (redirectedRoutePath) {
29+
return redirectedRoutePath
30+
}
31+
32+
// default to normalized route path
33+
return routePath
34+
}
Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { normalizeRoutePath } from '@vuepress/shared'
2-
import { redirects, routes } from '../internal/routes.js'
1+
import { resolveRoutePathWithExt } from '@vuepress/shared'
2+
import { resolveRouteKey } from './resolveRouteKey.js'
33

44
/**
55
* Resolve route path with given raw path
@@ -8,27 +8,8 @@ export const resolveRoutePath = (
88
pathname: string,
99
currentPath?: string,
1010
): string => {
11-
// normalized path
12-
const normalizedRoutePath = normalizeRoutePath(pathname, currentPath)
11+
// clean route path format used as key in routes
12+
const routeKey = resolveRouteKey(pathname, currentPath)
1313

14-
// check if the normalized path is in routes
15-
if (routes.value[normalizedRoutePath]) return normalizedRoutePath
16-
17-
// check encoded path
18-
const encodedRoutePath = encodeURI(normalizedRoutePath)
19-
20-
if (routes.value[encodedRoutePath]) {
21-
return encodedRoutePath
22-
}
23-
24-
// check redirected path with normalized path and encoded path
25-
const redirectedRoutePath =
26-
redirects.value[normalizedRoutePath] || redirects.value[encodedRoutePath]
27-
28-
if (redirectedRoutePath) {
29-
return redirectedRoutePath
30-
}
31-
32-
// default to normalized route path
33-
return normalizedRoutePath
14+
return __VUEPRESS_CLEAN_URL__ ? routeKey : resolveRoutePathWithExt(routeKey)
3415
}

packages/client/src/setupGlobalComputed.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { clientDataSymbol } from './composables/index.js'
55
import { redirects, routes } from './internal/routes.js'
66
import { siteData } from './internal/siteData.js'
77
import { resolvers } from './resolvers.js'
8+
import { resolveRouteKey } from './router/resolveRouteKey.js'
89
import type {
910
ClientConfig,
1011
ClientData,
@@ -46,10 +47,10 @@ export const setupGlobalComputed = (
4647
// handle page data HMR
4748
if (__VUEPRESS_DEV__ && (import.meta.webpackHot || import.meta.hot)) {
4849
__VUE_HMR_RUNTIME__.updatePageData = async (newPageData: PageData) => {
49-
const oldPageChunk = await routes.value[newPageData.path].loader()
50+
const routeKey = resolveRouteKey(newPageData.path)
51+
const oldPageChunk = await routes.value[routeKey].loader()
5052
const newPageChunk = { comp: oldPageChunk.comp, data: newPageData }
51-
routes.value[newPageData.path].loader = () =>
52-
Promise.resolve(newPageChunk)
53+
routes.value[routeKey].loader = () => Promise.resolve(newPageChunk)
5354
if (
5455
newPageData.path ===
5556
router.currentRoute.value.meta._pageChunk?.data.path

packages/client/types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
declare const __VUEPRESS_VERSION__: string
22
declare const __VUEPRESS_BASE__: string
33
declare const __VUEPRESS_DEV__: boolean
4+
declare const __VUEPRESS_CLEAN_URL__: boolean
45
declare const __VUEPRESS_SSR__: boolean
56
declare const __VUE_HMR_RUNTIME__: Record<string, any>
67
declare const __VUE_OPTIONS_API__: boolean

0 commit comments

Comments
 (0)