fix(nuxt): also augment page metadata after pages:extend hook (#27134)

This commit is contained in:
Daniel Roe 2024-06-10 17:24:43 +01:00 committed by GitHub
parent da28077be3
commit 0536dbeed9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 45 additions and 24 deletions

View File

@ -386,7 +386,7 @@ This option allows exposing some route metadata defined in `definePageMeta` at b
This only works with static or strings/arrays rather than variables or conditional assignment. See [original issue](https://github.com/nuxt/nuxt/issues/24770) for more information and context.
<!-- You can disable this feature if it causes issues in your project.
You can disable this feature if it causes issues in your project.
```ts twoslash [nuxt.config.ts]
export default defineNuxtConfig({
@ -394,7 +394,7 @@ export default defineNuxtConfig({
scanPageMeta: false
}
})
``` -->
```
## cookieStore

View File

@ -61,8 +61,12 @@ export default defineNuxtModule({
}
const pages = await resolvePagesRoutes()
await nuxt.callHook('pages:extend', pages)
if (pages.length) { return true }
if (pages.length) {
if (nuxt.apps.default) {
nuxt.apps.default.pages = pages
}
return true
}
return false
}
@ -75,7 +79,6 @@ export default defineNuxtModule({
nuxt.hook('app:templates', async (app) => {
app.pages = await resolvePagesRoutes()
await nuxt.callHook('pages:extend', app.pages)
if (!nuxt.options.ssr && app.pages.some(p => p.mode === 'server')) {
logger.warn('Using server pages with `ssr: false` is not supported with auto-detected component islands. Set `experimental.componentIslands` to `true`.')
@ -153,10 +156,9 @@ export default defineNuxtModule({
logs: nuxt.options.debug,
async beforeWriteFiles (rootPage) {
rootPage.children.forEach(child => child.delete())
let pages = nuxt.apps.default?.pages
if (!pages) {
pages = await resolvePagesRoutes()
await nuxt.callHook('pages:extend', pages)
const pages = nuxt.apps.default?.pages || await resolvePagesRoutes()
if (nuxt.apps.default) {
nuxt.apps.default.pages = pages
}
function addPage (parent: EditableTreeNode, page: NuxtPage) {
// @ts-expect-error TODO: either fix types upstream or figure out another

View File

@ -58,21 +58,30 @@ export async function resolvePagesRoutes (): Promise<NuxtPage[]> {
scannedFiles.sort((a, b) => a.relativePath.localeCompare(b.relativePath, 'en-US'))
const allRoutes = await generateRoutesFromFiles(uniqueBy(scannedFiles, 'relativePath'), {
shouldExtractBuildMeta: nuxt.options.experimental.scanPageMeta || nuxt.options.experimental.typedPages,
shouldUseServerComponents: !!nuxt.options.experimental.componentIslands,
vfs: nuxt.vfs,
})
return uniqueBy(allRoutes, 'path')
const pages = uniqueBy(allRoutes, 'path')
const shouldAugment = nuxt.options.experimental.scanPageMeta || nuxt.options.experimental.typedPages
if (shouldAugment) {
const augmentedPages = await augmentPages(pages, nuxt.vfs)
await nuxt.callHook('pages:extend', pages)
await augmentPages(pages, nuxt.vfs, augmentedPages)
augmentedPages.clear()
} else {
await nuxt.callHook('pages:extend', pages)
}
return pages
}
type GenerateRoutesFromFilesOptions = {
shouldExtractBuildMeta?: boolean
shouldUseServerComponents?: boolean
vfs?: Record<string, string>
}
export async function generateRoutesFromFiles (files: ScannedFile[], options: GenerateRoutesFromFilesOptions = {}): Promise<NuxtPage[]> {
export function generateRoutesFromFiles (files: ScannedFile[], options: GenerateRoutesFromFilesOptions = {}): NuxtPage[] {
const routes: NuxtPage[] = []
for (const file of files) {
@ -124,17 +133,26 @@ export async function generateRoutesFromFiles (files: ScannedFile[], options: Ge
}
}
if (options.shouldExtractBuildMeta && options.vfs) {
const fileContent = file.absolutePath in options.vfs ? options.vfs[file.absolutePath] : fs.readFileSync(file.absolutePath, 'utf-8')
Object.assign(route, await getRouteMeta(fileContent, file.absolutePath))
}
parent.push(route)
}
return prepareRoutes(routes)
}
export async function augmentPages (routes: NuxtPage[], vfs: Record<string, string>, augmentedPages = new Set<NuxtPage>()) {
for (const route of routes) {
if (!augmentedPages.has(route) && route.file) {
const fileContent = route.file in vfs ? vfs[route.file] : fs.readFileSync(route.file, 'utf-8')
Object.assign(route, await getRouteMeta(fileContent, route.file))
}
if (route.children && route.children.length > 0) {
await augmentPages(route.children, vfs)
}
}
return augmentedPages
}
const SFC_SCRIPT_RE = /<script[^>]*>([\s\S]*?)<\/script[^>]*>/i
export function extractScriptContent (html: string) {
const match = html.match(SFC_SCRIPT_RE)

View File

@ -1,6 +1,6 @@
import { describe, expect, it, vi } from 'vitest'
import type { NuxtPage } from 'nuxt/schema'
import { generateRoutesFromFiles, normalizeRoutes, pathToNitroGlob } from '../src/pages/utils'
import { augmentPages, generateRoutesFromFiles, normalizeRoutes, pathToNitroGlob } from '../src/pages/utils'
import { generateRouteKey } from '../src/pages/runtime/utils'
describe('pages:generateRoutesFromFiles', () => {
@ -568,11 +568,12 @@ describe('pages:generateRoutesFromFiles', () => {
) as Record<string, string>
try {
result = await generateRoutesFromFiles(test.files.map(file => ({
result = generateRoutesFromFiles(test.files.map(file => ({
shouldUseServerComponents: true,
absolutePath: file.path,
relativePath: file.path.replace(/^(pages|layer\/pages)\//, ''),
})), { shouldExtractBuildMeta: true, vfs })
})))
await augmentPages(result, vfs)
} catch (error: any) {
expect(error.message).toEqual(test.error)
}

View File

@ -378,7 +378,7 @@ export default defineUntypedSchema({
*
* https://github.com/nuxt/nuxt/issues/24770
*/
scanPageMeta: false,
scanPageMeta: true,
/**
* Automatically share payload _data_ between pages that are prerendered. This can result in a significant