mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 15:15:19 +00:00
fix(nuxt): extract route rules/page meta in 2+ script blocks (#28625)
This commit is contained in:
parent
81774f3a5a
commit
eed8730688
@ -18,10 +18,12 @@ export async function extractRouteRules (code: string): Promise<NitroRouteConfig
|
||||
}
|
||||
if (!ROUTE_RULE_RE.test(code)) { return null }
|
||||
|
||||
const script = extractScriptContent(code)
|
||||
code = script?.code || code
|
||||
|
||||
let rule: NitroRouteConfig | null = null
|
||||
const contents = extractScriptContent(code)
|
||||
for (const script of contents) {
|
||||
if (rule) { break }
|
||||
|
||||
code = script?.code || code
|
||||
|
||||
const js = await transform(code, { loader: script?.loader || 'ts' })
|
||||
walk(parse(js.code, {
|
||||
@ -42,6 +44,7 @@ export async function extractRouteRules (code: string): Promise<NitroRouteConfig
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
ruleCache[code] = rule
|
||||
return rule
|
||||
|
@ -168,21 +168,23 @@ export async function augmentPages (routes: NuxtPage[], vfs: Record<string, stri
|
||||
return augmentedPages
|
||||
}
|
||||
|
||||
const SFC_SCRIPT_RE = /<script(?<attrs>[^>]*)>(?<content>[\s\S]*?)<\/script[^>]*>/i
|
||||
const SFC_SCRIPT_RE = /<script(?<attrs>[^>]*)>(?<content>[\s\S]*?)<\/script[^>]*>/gi
|
||||
export function extractScriptContent (html: string) {
|
||||
const groups = html.match(SFC_SCRIPT_RE)?.groups || {}
|
||||
|
||||
if (groups.content) {
|
||||
return {
|
||||
loader: groups.attrs.includes('tsx') ? 'tsx' : 'ts',
|
||||
code: groups.content.trim(),
|
||||
} as const
|
||||
const contents: Array<{ loader: 'tsx' | 'ts', code: string }> = []
|
||||
for (const match of html.matchAll(SFC_SCRIPT_RE)) {
|
||||
if (match?.groups?.content) {
|
||||
contents.push({
|
||||
loader: match.groups.attrs.includes('tsx') ? 'tsx' : 'ts',
|
||||
code: match.groups.content.trim(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
return contents
|
||||
}
|
||||
|
||||
const PAGE_META_RE = /definePageMeta\([\s\S]*?\)/
|
||||
const extractionKeys = ['name', 'path', 'alias', 'redirect'] as const
|
||||
const DYNAMIC_META_KEY = '__nuxt_dynamic_meta_key' as const
|
||||
|
||||
const pageContentsCache: Record<string, string> = {}
|
||||
@ -197,15 +199,17 @@ export async function getRouteMeta (contents: string, absolutePath: string): Pro
|
||||
if (absolutePath in metaCache) { return metaCache[absolutePath] }
|
||||
|
||||
const loader = getLoader(absolutePath)
|
||||
const script = !loader ? null : loader === 'vue' ? extractScriptContent(contents) : { code: contents, loader }
|
||||
if (!script) {
|
||||
const scriptBlocks = !loader ? null : loader === 'vue' ? extractScriptContent(contents) : [{ code: contents, loader }]
|
||||
if (!scriptBlocks) {
|
||||
metaCache[absolutePath] = {}
|
||||
return {}
|
||||
}
|
||||
|
||||
const extractedMeta = {} as Partial<Record<keyof NuxtPage, any>>
|
||||
|
||||
for (const script of scriptBlocks) {
|
||||
if (!PAGE_META_RE.test(script.code)) {
|
||||
metaCache[absolutePath] = {}
|
||||
return {}
|
||||
continue
|
||||
}
|
||||
|
||||
const js = await transform(script.code, { loader: script.loader })
|
||||
@ -215,8 +219,6 @@ export async function getRouteMeta (contents: string, absolutePath: string): Pro
|
||||
ranges: true,
|
||||
}) as unknown as Program
|
||||
|
||||
const extractedMeta = {} as Partial<Record<keyof NuxtPage, any>>
|
||||
const extractionKeys = ['name', 'path', 'alias', 'redirect'] as const
|
||||
const dynamicProperties = new Set<keyof NuxtPage>()
|
||||
|
||||
let foundMeta = false
|
||||
@ -291,6 +293,7 @@ export async function getRouteMeta (contents: string, absolutePath: string): Pro
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
metaCache[absolutePath] = extractedMeta
|
||||
return extractedMeta
|
||||
|
@ -61,6 +61,41 @@ describe('page metadata', () => {
|
||||
`)
|
||||
})
|
||||
|
||||
it('should extract serialisable metadata from files with multiple blocks', async () => {
|
||||
const meta = await getRouteMeta(`
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'thing'
|
||||
}
|
||||
</script>
|
||||
<script setup>
|
||||
definePageMeta({
|
||||
name: 'some-custom-name',
|
||||
path: '/some-custom-path',
|
||||
validate: () => true,
|
||||
middleware: [
|
||||
function () {},
|
||||
],
|
||||
otherValue: {
|
||||
foo: 'bar',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
`, filePath)
|
||||
|
||||
expect(meta).toMatchInlineSnapshot(`
|
||||
{
|
||||
"meta": {
|
||||
"__nuxt_dynamic_meta_key": Set {
|
||||
"meta",
|
||||
},
|
||||
},
|
||||
"name": "some-custom-name",
|
||||
"path": "/some-custom-path",
|
||||
}
|
||||
`)
|
||||
})
|
||||
|
||||
it('should extract serialisable metadata in options api', async () => {
|
||||
const meta = await getRouteMeta(`
|
||||
<script>
|
||||
|
Loading…
Reference in New Issue
Block a user