Skip to content

Commit

Permalink
fix: parse non modules with definePage
Browse files Browse the repository at this point in the history
Fix #114
  • Loading branch information
posva committed Jan 8, 2023
1 parent 348e95c commit ce70048
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 35 deletions.
9 changes: 9 additions & 0 deletions playground/src/pages/custom-definePage.vue
@@ -0,0 +1,9 @@
<script lang="ts" setup>
definePage({
// name: hey
})
</script>

<template>
<main>content</main>
</template>
1 change: 1 addition & 0 deletions playground/typed-router.d.ts
Expand Up @@ -43,6 +43,7 @@ declare module 'vue-router/auto/routes' {
'/articles/': RouteRecordInfo<'/articles/', '/articles', Record<never, never>, Record<never, never>>,
'/articles/[id]': RouteRecordInfo<'/articles/[id]', '/articles/:id', { id: ParamValue<true> }, { id: ParamValue<false> }>,
'/articles/[id]+': RouteRecordInfo<'/articles/[id]+', '/articles/:id+', { id: ParamValueOneOrMore<true> }, { id: ParamValueOneOrMore<false> }>,
'/custom-definePage': RouteRecordInfo<'/custom-definePage', '/custom-definePage', Record<never, never>, Record<never, never>>,
'a rebel': RouteRecordInfo<'a rebel', '/custom-name', Record<never, never>, Record<never, never>>,
'/deep/nesting/works/[[files]]+': RouteRecordInfo<'/deep/nesting/works/[[files]]+', '/deep/nesting/works/:files*', { files?: ParamValueZeroOrMore<true> }, { files?: ParamValueZeroOrMore<false> }>,
'deep the most rebel': RouteRecordInfo<'deep the most rebel', '/deep-most-rebel', Record<never, never>, Record<never, never>>,
Expand Down
15 changes: 15 additions & 0 deletions src/core/__snapshots__/definePage.spec.ts.snap
@@ -0,0 +1,15 @@
// Vitest Snapshot v1

exports[`definePage > removes definePage 1`] = `
"
<script setup>
const a = 1
const b = 1
</script>
<template>
<div>hello</div>
</template>
"
`;
76 changes: 46 additions & 30 deletions src/core/definePage.spec.ts
@@ -1,10 +1,8 @@
import { TransformResult } from 'vite'
import { expect, describe, it } from 'vitest'
import { definePageTransform, extractDefinePageNameAndPath } from './definePage'

describe('definePage', () => {
it('removes definePage', async () => {
const result = await definePageTransform({
code: `
const sampleCode = `
<script setup>
const a = 1
definePage({
Expand All @@ -13,38 +11,26 @@ definePage({
})
const b = 1
</script>
`,
id: 'src/pages/basic.vue',
})
const code = typeof result === 'string' ? result : result?.code
<template>
<div>hello</div>
</template>
`

expect(code).toMatchInlineSnapshot(`
"
<script setup>
const a = 1
describe('definePage', () => {
it('removes definePage', async () => {
const result = (await definePageTransform({
code: sampleCode,
id: 'src/pages/basic.vue',
})) as Exclude<TransformResult, string>

const b = 1
</script>
"
`)
expect(result).toHaveProperty('code')
expect(result?.code).toMatchSnapshot()
})

it('extracts name and path', async () => {
expect(
await extractDefinePageNameAndPath(
`
<script setup>
const a = 1
definePage({
name: 'custom',
path: '/custom',
})
const b = 1
</script>
`,
'src/pages/basic.vue'
)
await extractDefinePageNameAndPath(sampleCode, 'src/pages/basic.vue')
).toEqual({
name: 'custom',
path: '/custom',
Expand All @@ -59,9 +45,39 @@ const b = 1
const a = 1
const b = 1
</script>
<template>
<div>hello</div>
</template>
`,
'src/pages/basic.vue'
)
).toEqual(undefined)
).toBeFalsy()
})

it('works with comments', async () => {
const code = `
<script setup>
// definePage
</script>
<template>
<div>hello</div>
</template>
`
// no need to transform
let result = (await definePageTransform({
code,
id: 'src/pages/basic.vue',
})) as Exclude<TransformResult, string>
expect(result).toBeFalsy()

// should give an empty object
result = (await definePageTransform({
code,
id: 'src/pages/basic.vue?definePage&vue',
})) as Exclude<TransformResult, string>

expect(result).toBe('export default {}')
})
})
16 changes: 11 additions & 5 deletions src/core/definePage.ts
Expand Up @@ -32,20 +32,26 @@ export function definePageTransform({
if (!code.includes(MACRO_DEFINE_PAGE)) return

const sfc = parseSFC(code, id)

if (!sfc.scriptSetup) return

// are we extracting only the definePage object
const isExtractingDefinePage = id.includes(MACRO_DEFINE_PAGE)

const { script, scriptSetup, scriptCompiled } = sfc

const definePageNodes = (scriptCompiled.scriptSetupAst as Node[])
const definePageNodes = (scriptCompiled?.scriptSetupAst || ([] as Node[]))
.map((node) => {
if (node.type === 'ExpressionStatement') node = node.expression
return isCallOf(node, MACRO_DEFINE_PAGE) ? node : null
})
.filter((node): node is CallExpression => !!node)

if (!definePageNodes.length) {
return
return isExtractingDefinePage
? // e.g. index.vue?definePage that contains a commented `definePage()
'export default {}'
: // e.g. index.vue that contains a commented `definePage()
null
} else if (definePageNodes.length > 1) {
throw new SyntaxError(`duplicate definePage() call`)
}
Expand All @@ -54,7 +60,7 @@ export function definePageTransform({
const setupOffset = scriptSetup.loc.start.offset

// we only want the page info
if (id.includes(MACRO_DEFINE_PAGE)) {
if (isExtractingDefinePage) {
const s = new MagicString(code)
// remove everything except the page info

Expand Down Expand Up @@ -107,7 +113,7 @@ export function extractDefinePageNameAndPath(

const { script, scriptSetup, scriptCompiled } = sfc

const definePageNodes = (scriptCompiled.scriptSetupAst as Node[])
const definePageNodes = (scriptCompiled?.scriptSetupAst ?? ([] as Node[]))
.map((node) => {
if (node.type === 'ExpressionStatement') node = node.expression
return isCallOf(node, MACRO_DEFINE_PAGE) ? node : null
Expand Down

0 comments on commit ce70048

Please sign in to comment.