fix(nuxt): scan jsx pages for page metadata (#28479)

This commit is contained in:
Daniel Roe 2024-08-09 12:11:38 +01:00 committed by GitHub
parent 84cd13ec46
commit 487170c867
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 27 additions and 3 deletions

View File

@ -1,5 +1,5 @@
export { getNameFromPath, hasSuffix, resolveComponentNameSegments } from './names' export { getNameFromPath, hasSuffix, resolveComponentNameSegments } from './names'
export { isJS, isVue } from './plugins' export { getLoader, isJS, isVue } from './plugins'
export function uniqueBy<T, K extends keyof T> (arr: T[], key: K) { export function uniqueBy<T, K extends keyof T> (arr: T[], key: K) {
if (arr.length < 2) { if (arr.length < 2) {

View File

@ -1,4 +1,5 @@
import { pathToFileURL } from 'node:url' import { pathToFileURL } from 'node:url'
import { extname } from 'pathe'
import { parseQuery, parseURL } from 'ufo' import { parseQuery, parseURL } from 'ufo'
export function isVue (id: string, opts: { type?: Array<'template' | 'script' | 'style'> } = {}) { export function isVue (id: string, opts: { type?: Array<'template' | 'script' | 'style'> } = {}) {
@ -41,3 +42,15 @@ export function isJS (id: string) {
const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href)) const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href))
return JS_RE.test(pathname) return JS_RE.test(pathname)
} }
export function getLoader (id: string): 'vue' | 'ts' | 'tsx' | null {
const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href))
const ext = extname(pathname)
if (ext === '.vue') {
return 'vue'
}
if (!JS_RE.test(ext)) {
return null
}
return ext.endsWith('x') ? 'tsx' : 'ts'
}

View File

@ -13,7 +13,7 @@ import { walk } from 'estree-walker'
import type { CallExpression, ExpressionStatement, ObjectExpression, Program, Property } from 'estree' import type { CallExpression, ExpressionStatement, ObjectExpression, Program, Property } from 'estree'
import type { NuxtPage } from 'nuxt/schema' import type { NuxtPage } from 'nuxt/schema'
import { uniqueBy } from '../core/utils' import { getLoader, uniqueBy } from '../core/utils'
import { toArray } from '../utils' import { toArray } from '../utils'
import { distDir } from '../dirs' import { distDir } from '../dirs'
@ -188,7 +188,8 @@ export async function getRouteMeta (contents: string, absolutePath: string): Pro
if (absolutePath in metaCache) { return metaCache[absolutePath] } if (absolutePath in metaCache) { return metaCache[absolutePath] }
const script = extractScriptContent(contents) const loader = getLoader(absolutePath)
const script = !loader ? null : loader === 'vue' ? extractScriptContent(contents) : { code: contents, loader }
if (!script) { if (!script) {
metaCache[absolutePath] = {} metaCache[absolutePath] = {}
return {} return {}

View File

@ -10,6 +10,16 @@ describe('page metadata', () => {
expect(await getRouteMeta('<template><div>Hi</div></template>', filePath)).toEqual({}) expect(await getRouteMeta('<template><div>Hi</div></template>', filePath)).toEqual({})
}) })
it('should extract metadata from JS/JSX files', async () => {
const fileContents = `definePageMeta({ name: 'bar' })`
for (const ext of ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs']) {
const meta = await getRouteMeta(fileContents, `/app/pages/index.${ext}`)
expect(meta).toStrictEqual({
name: 'bar',
})
}
})
it('should use and invalidate cache', async () => { it('should use and invalidate cache', async () => {
const fileContents = `<script setup>definePageMeta({ foo: 'bar' })</script>` const fileContents = `<script setup>definePageMeta({ foo: 'bar' })</script>`
const meta = await getRouteMeta(fileContents, filePath) const meta = await getRouteMeta(fileContents, filePath)