diff --git a/.gitignore b/.gitignore index 615ec291f2..1024d99742 100644 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,5 @@ eslint-typegen.d.ts .eslintcache test-results/ playwright-report + +temp diff --git a/packages/nuxt/src/pages/utils.ts b/packages/nuxt/src/pages/utils.ts index d413c0aaa8..326d3deb17 100644 --- a/packages/nuxt/src/pages/utils.ts +++ b/packages/nuxt/src/pages/utils.ts @@ -137,7 +137,8 @@ export function generateRoutesFromFiles (files: ScannedFile[], options: Generate route.name += (route.name && '/') + segmentName // ex: parent.vue + parent/child.vue - const path = withLeadingSlash(joinURL(route.path, getRoutePath(tokens).replace(INDEX_PAGE_RE, '/'))) + const routePath = getRoutePath(tokens, segments[i + 1] !== undefined) + const path = withLeadingSlash(joinURL(route.path, routePath.replace(INDEX_PAGE_RE, '/'))) const child = parent.find(parentRoute => parentRoute.name === route.name && parentRoute.path === path) if (child && child.children) { @@ -146,7 +147,7 @@ export function generateRoutesFromFiles (files: ScannedFile[], options: Generate } else if (segmentName === 'index' && !route.path) { route.path += '/' } else if (segmentName !== 'index') { - route.path += getRoutePath(tokens) + route.path += routePath } } @@ -319,7 +320,7 @@ export function getRouteMeta (contents: string, absolutePath: string, extraExtra } const COLON_RE = /:/g -function getRoutePath (tokens: SegmentToken[]): string { +function getRoutePath (tokens: SegmentToken[], hasSucceedingSegment = false): string { return tokens.reduce((path, token) => { return ( path + @@ -328,7 +329,7 @@ function getRoutePath (tokens: SegmentToken[]): string { : token.type === SegmentTokenType.dynamic ? `:${token.value}()` : token.type === SegmentTokenType.catchall - ? `:${token.value}(.*)*` + ? hasSucceedingSegment ? `:${token.value}([^/]*)*` : `:${token.value}(.*)*` : token.type === SegmentTokenType.group ? '' : encodePath(token.value).replace(COLON_RE, '\\:')) diff --git a/packages/nuxt/test/__snapshots__/pages-override-meta-disabled.test.ts.snap b/packages/nuxt/test/__snapshots__/pages-override-meta-disabled.test.ts.snap index 9cf64b5264..9516301b35 100644 --- a/packages/nuxt/test/__snapshots__/pages-override-meta-disabled.test.ts.snap +++ b/packages/nuxt/test/__snapshots__/pages-override-meta-disabled.test.ts.snap @@ -560,4 +560,15 @@ "redirect": "mockMeta?.redirect", }, ], + "should use more performant regexp when catchall is used in middle of path": [ + { + "alias": "mockMeta?.alias || []", + "component": "() => import("pages/[...id]/suffix.vue")", + "meta": "mockMeta || {}", + "name": "mockMeta?.name ?? "id-suffix"", + "path": "mockMeta?.path ?? "/:id([^/]*)*/suffix"", + "props": "mockMeta?.props ?? false", + "redirect": "mockMeta?.redirect", + }, + ], } \ No newline at end of file diff --git a/packages/nuxt/test/__snapshots__/pages-override-meta-enabled.test.ts.snap b/packages/nuxt/test/__snapshots__/pages-override-meta-enabled.test.ts.snap index 2247a9e4c7..5815724617 100644 --- a/packages/nuxt/test/__snapshots__/pages-override-meta-enabled.test.ts.snap +++ b/packages/nuxt/test/__snapshots__/pages-override-meta-enabled.test.ts.snap @@ -351,4 +351,11 @@ "redirect": "mockMeta?.redirect", }, ], + "should use more performant regexp when catchall is used in middle of path": [ + { + "component": "() => import("pages/[...id]/suffix.vue")", + "name": ""id-suffix"", + "path": ""/:id([^/]*)*/suffix"", + }, + ], } \ No newline at end of file diff --git a/packages/nuxt/test/pages.test.ts b/packages/nuxt/test/pages.test.ts index e4e0551a39..5401282218 100644 --- a/packages/nuxt/test/pages.test.ts +++ b/packages/nuxt/test/pages.test.ts @@ -574,6 +574,23 @@ describe('pages:generateRoutesFromFiles', () => { }, ], }, + { + description: 'should use more performant regexp when catchall is used in middle of path', + files: [ + { + path: `${pagesDir}/[...id]/suffix.vue`, + }, + ], + output: [ + { + name: 'id-suffix', + meta: undefined, + path: '/:id([^/]*)*/suffix', + file: `${pagesDir}/[...id]/suffix.vue`, + children: [], + }, + ], + }, { description: 'should merge route.meta with meta from file', files: [