fix(nuxt): collect all identifiers before extracting page metadata (#30478)

This commit is contained in:
Matej Černý 2025-01-07 05:49:59 +01:00 committed by GitHub
parent 5ba98e8cdb
commit 65380c6bc9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 2 deletions

View File

@ -173,7 +173,9 @@ export const PageMetaPlugin = (options: PageMetaPluginOptions = {}) => createUnp
} }
} }
const scopeTracker = new ScopeTracker() const scopeTracker = new ScopeTracker({
keepExitedScopes: true,
})
function processDeclaration (scopeTrackerNode: ScopeTrackerNode | null) { function processDeclaration (scopeTrackerNode: ScopeTrackerNode | null) {
if (scopeTrackerNode?.type === 'Variable') { if (scopeTrackerNode?.type === 'Variable') {
@ -210,7 +212,13 @@ export const PageMetaPlugin = (options: PageMetaPluginOptions = {}) => createUnp
} }
} }
parseAndWalk(code, id, { const ast = parseAndWalk(code, id, {
scopeTracker,
})
scopeTracker.freeze()
walk(ast, {
scopeTracker, scopeTracker,
enter: (node) => { enter: (node) => {
if (node.type !== 'CallExpression' || node.callee.type !== 'Identifier') { return } if (node.type !== 'CallExpression' || node.callee.type !== 'Identifier') { return }
@ -221,6 +229,7 @@ export const PageMetaPlugin = (options: PageMetaPluginOptions = {}) => createUnp
if (!meta) { return } if (!meta) { return }
walk(meta, { walk(meta, {
scopeTracker,
enter (node, parent) { enter (node, parent) {
if ( if (
isNotReferencePosition(node, parent) isNotReferencePosition(node, parent)

View File

@ -497,6 +497,8 @@ function recursive () {
recursive() recursive()
} }
const route = useRoute()
definePageMeta({ definePageMeta({
middleware: [ middleware: [
() => { () => {
@ -513,9 +515,19 @@ definePageMeta({
prop = 'prop' prop = 'prop'
test () {} test () {}
} }
console.log(hoisted.value)
}, },
], ],
validate: (route) => {
return route.params.id === 'test'
}
}) })
// the order of a ref relative to the 'definePageMeta' call should be preserved (in contrast to a simple const)
// this tests whether the extraction handles all variables in the upper scope
const hoisted = ref('hoisted')
</script> </script>
` `
const res = compileScript(parse(sfc).descriptor, { id: 'component.vue' }) const res = compileScript(parse(sfc).descriptor, { id: 'component.vue' })
@ -534,6 +546,7 @@ definePageMeta({
function recursive () { function recursive () {
recursive() recursive()
} }
const hoisted = ref('hoisted')
const __nuxt_page_meta = { const __nuxt_page_meta = {
middleware: [ middleware: [
() => { () => {
@ -550,8 +563,13 @@ definePageMeta({
prop = 'prop' prop = 'prop'
test () {} test () {}
} }
console.log(hoisted.value)
}, },
], ],
validate: (route) => {
return route.params.id === 'test'
}
} }
export default __nuxt_page_meta" export default __nuxt_page_meta"
`) `)