Skip to content

Commit c0b310f

Browse files
committed
feat(macros/defineComponent): support auto return functional component for SSR
1 parent 8d47c72 commit c0b310f

File tree

7 files changed

+103
-3
lines changed

7 files changed

+103
-3
lines changed

packages/macros/src/core/define-component/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import { walkIdentifiers } from '@vue/compiler-sfc'
33
import { restructure } from '../restructure'
44
import type { FunctionalNode, RootMapValue } from '..'
55
import { transformAwait } from './await'
6+
import { transformReturn } from './return'
67
import type { ObjectExpression } from '@babel/types'
78

89
export function transformDefineComponent(
910
root: FunctionalNode,
1011
propsName: string,
1112
map: RootMapValue,
1213
s: MagicStringAST,
14+
autoReturnFunction = false,
1315
): void {
1416
if (!map.defineComponent) return
1517

@@ -94,6 +96,9 @@ export function transformDefineComponent(
9496
}
9597

9698
transformAwait(root, s)
99+
if (autoReturnFunction) {
100+
transformReturn(root, s)
101+
}
97102
}
98103

99104
function prependObjectExpression(
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { isFunctionalNode, type FunctionalNode } from '..'
2+
import type { MagicStringAST } from '@vue-macros/common'
3+
4+
export function transformReturn(root: FunctionalNode, s: MagicStringAST): void {
5+
const node =
6+
root.body.type === 'BlockStatement'
7+
? root.body.body.find((node) => node.type === 'ReturnStatement')?.argument
8+
: root.body
9+
if (!node || isFunctionalNode(node)) return
10+
11+
s.appendRight(
12+
node.extra?.parenthesized ? (node.extra.parenStart as number) : node.start!,
13+
'() => ',
14+
)
15+
}

packages/macros/src/core/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,13 @@ export function transformJsxMacros(
9595
}
9696

9797
if (map.defineComponent) {
98-
transformDefineComponent(root, propsName, map, s)
98+
transformDefineComponent(
99+
root,
100+
propsName,
101+
map,
102+
s,
103+
options.defineComponent?.autoReturnFunction,
104+
)
99105
}
100106
if (map.defineModel?.length) {
101107
map.defineModel.forEach(({ expression }) => {

packages/macros/src/options.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
} from '@vue-macros/common'
99

1010
export type Options = BaseOptions & {
11-
defineComponent?: { alias: string[] }
11+
defineComponent?: { alias: string[]; autoReturnFunction?: boolean }
1212
defineModel?: { alias: string[] }
1313
defineExpose?: { alias: string[] }
1414
defineSlots?: { alias: string[] }

packages/macros/src/raw.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ const plugin = (userOptions: Options = {}): UnpluginOptions => {
3939
if (importMap.get(id)) return true
4040
return filter(id)
4141
},
42-
transform(code, id) {
42+
transform(code, id, opt?: { ssr?: boolean }) {
43+
if (opt?.ssr) {
44+
options.defineComponent.autoReturnFunction = true
45+
}
4346
if (importMap.get(id)) return transformStyle(code, id, options)
4447
return transformJsxMacros(code, id, importMap, options)
4548
},

packages/macros/tests/__snapshots__/fixtures.spec.ts.snap

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,57 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3+
exports[`defineComponent autoReturnFunction fixtures > ./fixtures/define-component.tsx 1`] = `
4+
"
5+
import { createPropsDefaultProxy as __MACROS_createPropsDefaultProxy } from "vue-jsx-vapor/macros/with-defaults";
6+
import { useAttrs as __MACROS_useAttrs } from "vue";
7+
import { useModel as __MACROS_useModel } from "vue-jsx-vapor/macros/use-model";
8+
import { withAsyncContext as __MACROS_withAsyncContext } from "vue";import { defineComponent, nextTick } from 'vue'
9+
10+
const Comp = defineComponent(
11+
(__MACROS_props) => {
12+
const __MACROS_default_props = __MACROS_createPropsDefaultProxy(__MACROS_props, {'.bar': 'bar'!});const attrs = __MACROS_useAttrs();
13+
__MACROS_useModel(__MACROS_props, 'modelValue',)
14+
const foo = $(
15+
__MACROS_useModel(__MACROS_props, 'foo', {
16+
validator: (value) => {
17+
return value === 'foo'
18+
},
19+
type: String,
20+
})!,
21+
)
22+
return () => <div>{[foo, __MACROS_default_props.bar, attrs.baz]}</div>
23+
},
24+
{props: { 'bar': { required: true }, 'modelValue': null, 'onUpdate:modelValue': null, 'modelModifiers': null, 'foo': { required: true, validator: (value) => {
25+
return value === 'foo'
26+
}, type: String }, 'onUpdate:foo': null, 'fooModifiers': null },inheritAttrs: false, name: 'Comp' },
27+
)
28+
29+
const Comp1 = defineComponent((props: { bar: 'bar'; 'onUpdate:bar': any }) => {
30+
const foo = __MACROS_useModel(props, 'foo')
31+
return () => <div>{[foo.value, props['bar'], props['onUpdate:bar']]}</div>
32+
}, { props: { 'bar': null, 'onUpdate:bar': null, 'foo': null, 'onUpdate:foo': null, 'fooModifiers': null } })
33+
34+
const Comp2 = defineComponent(async (__MACROS_props) => {
35+
let __temp, __restore
36+
37+
;(
38+
([__temp,__restore] = __MACROS_withAsyncContext(() => nextTick())),
39+
await __temp,
40+
__restore()
41+
)
42+
let foo = (
43+
([__temp,__restore] = __MACROS_withAsyncContext(() => new Promise((resolve) => {
44+
setTimeout(() => resolve('foo'), 1000)
45+
}))),
46+
__temp = await __temp,
47+
__restore(),
48+
__temp
49+
)
50+
return () => <div>{foo}</div>
51+
})
52+
"
53+
`;
54+
355
exports[`fixtures > ./fixtures/define-component.tsx 1`] = `
456
"
557
import { createPropsDefaultProxy as __MACROS_createPropsDefaultProxy } from "vue-jsx-vapor/macros/with-defaults";

packages/macros/tests/fixtures.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,22 @@ describe('fixtures', async () => {
3737
})?.code,
3838
)
3939
})
40+
41+
describe('defineComponent autoReturnFunction fixtures', async () => {
42+
await testFixtures(
43+
import.meta.glob('./fixtures/**/define-component.tsx', {
44+
eager: true,
45+
as: 'raw',
46+
}),
47+
(args, id, code) =>
48+
transformJsxMacros(code, id, new Map(), {
49+
include: ['*.tsx'],
50+
version: 3.6,
51+
...options,
52+
defineComponent: {
53+
alias: ['defineComponent', 'defineVaporComponent'],
54+
autoReturnFunction: true,
55+
},
56+
})?.code,
57+
)
58+
})

0 commit comments

Comments
 (0)