feat(schema): allow adding page routes without a matching file (#19173)

This commit is contained in:
Ivan 2023-03-03 17:07:42 +03:00 committed by GitHub
parent 44068420da
commit 7131aef820
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 19 deletions

View File

@ -146,9 +146,11 @@ export default defineNuxtModule({
// Add router plugin
addPlugin(resolve(runtimeDir, 'plugins/router'))
const getSources = (pages: NuxtPage[]): string[] => pages.flatMap(p =>
[relative(nuxt.options.srcDir, p.file), ...getSources(p.children || [])]
)
const getSources = (pages: NuxtPage[]): string[] => pages
.filter(p => Boolean(p.file))
.flatMap(p =>
[relative(nuxt.options.srcDir, p.file as string), ...getSources(p.children || [])]
)
// Do not prefetch page chunks
nuxt.hook('build:manifest', async (manifest) => {

View File

@ -249,28 +249,40 @@ export function normalizeRoutes (routes: NuxtPage[], metaImports: Set<string> =
return {
imports: metaImports,
routes: genArrayFromRaw(routes.map((page) => {
const route = Object.fromEntries(
Object.entries(page)
.filter(([key, value]) => key !== 'file' && (Array.isArray(value) ? value.length : value))
.map(([key, value]) => [key, JSON.stringify(value)])
) as Record<Exclude<keyof NuxtPage, 'file'>, string> & { component?: string }
if (page.children?.length) {
route.children = normalizeRoutes(page.children, metaImports).routes
}
// Without a file, we can't use `definePageMeta` to extract route-level meta from the file
if (!page.file) {
for (const key of ['name', 'path', 'meta', 'alias', 'redirect'] as const) {
if (page[key]) { route[key] = JSON.stringify(page[key]) }
}
return route
}
const file = normalize(page.file)
const metaImportName = genSafeVariableName(filename(file) + hash(file)) + 'Meta'
metaImports.add(genImport(`${file}?macro=true`, [{ name: 'default', as: metaImportName }]))
let aliasCode = `${metaImportName}?.alias || []`
if (Array.isArray(page.alias) && page.alias.length) {
aliasCode = `${JSON.stringify(page.alias)}.concat(${aliasCode})`
const alias = Array.isArray(page.alias) ? page.alias : [page.alias].filter(Boolean)
if (alias.length) {
aliasCode = `${JSON.stringify(alias)}.concat(${aliasCode})`
}
const route = {
...Object.fromEntries(Object.entries(page).map(([key, value]) => [key, JSON.stringify(value)])),
file: undefined,
name: `${metaImportName}?.name ?? ${page.name ? JSON.stringify(page.name) : 'undefined'}`,
path: `${metaImportName}?.path ?? ${JSON.stringify(page.path)}`,
children: page.children ? normalizeRoutes(page.children, metaImports).routes : [],
meta: page.meta ? `{...(${metaImportName} || {}), ...${JSON.stringify(page.meta)}}` : `${metaImportName} || {}`,
alias: aliasCode,
redirect: page.redirect ? JSON.stringify(page.redirect) : `${metaImportName}?.redirect || undefined`,
component: genDynamicImport(file, { interopDefault: true })
}
delete route.file
route.name = `${metaImportName}?.name ?? ${page.name ? JSON.stringify(page.name) : 'undefined'}`
route.path = `${metaImportName}?.path ?? ${JSON.stringify(page.path)}`
route.meta = page.meta && Object.values(page.meta).filter(value => value !== undefined).length ? `{...(${metaImportName} || {}), ...${JSON.stringify(page.meta)}}` : `${metaImportName} || {}`
route.alias = aliasCode
route.redirect = page.redirect ? JSON.stringify(page.redirect) : `${metaImportName}?.redirect || undefined`
route.component = genDynamicImport(file, { interopDefault: true })
return route
}))

View File

@ -22,7 +22,7 @@ export type WatchEvent = 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir'
export type NuxtPage = {
name?: string
path: string
file: string
file?: string
meta?: Record<string, any>
alias?: string[] | string
redirect?: string