@@ -11,7 +11,6 @@ import {
11
11
buildSlots ,
12
12
FunctionExpression ,
13
13
TemplateChildNode ,
14
- TELEPORT ,
15
14
createIfStatement ,
16
15
createSimpleExpression ,
17
16
getBaseTransformPreset ,
@@ -31,9 +30,12 @@ import {
31
30
ExpressionNode ,
32
31
TemplateNode ,
33
32
SUSPENSE ,
34
- TRANSITION_GROUP
33
+ TELEPORT ,
34
+ TRANSITION_GROUP ,
35
+ CREATE_VNODE ,
36
+ CallExpression
35
37
} from '@vue/compiler-dom'
36
- import { SSR_RENDER_COMPONENT } from '../runtimeHelpers'
38
+ import { SSR_RENDER_COMPONENT , SSR_RENDER_VNODE } from '../runtimeHelpers'
37
39
import {
38
40
SSRTransformContext ,
39
41
processChildren ,
@@ -58,7 +60,10 @@ interface WIPSlotEntry {
58
60
vnodeBranch : ReturnStatement
59
61
}
60
62
61
- const componentTypeMap = new WeakMap < ComponentNode , symbol > ( )
63
+ const componentTypeMap = new WeakMap <
64
+ ComponentNode ,
65
+ string | symbol | CallExpression
66
+ > ( )
62
67
63
68
// ssr component transform is done in two phases:
64
69
// In phase 1. we use `buildSlot` to analyze the children of the component into
@@ -75,8 +80,9 @@ export const ssrTransformComponent: NodeTransform = (node, context) => {
75
80
}
76
81
77
82
const component = resolveComponentType ( node , context , true /* ssr */ )
83
+ componentTypeMap . set ( node , component )
84
+
78
85
if ( isSymbol ( component ) ) {
79
- componentTypeMap . set ( node , component )
80
86
if ( component === SUSPENSE ) {
81
87
return ssrTransformSuspense ( node , context )
82
88
}
@@ -134,20 +140,38 @@ export const ssrTransformComponent: NodeTransform = (node, context) => {
134
140
? buildSlots ( node , context , buildSSRSlotFn ) . slots
135
141
: `null`
136
142
137
- node . ssrCodegenNode = createCallExpression (
138
- context . helper ( SSR_RENDER_COMPONENT ) ,
139
- [ component , props , slots , `_parent` ]
140
- )
143
+ if ( typeof component !== 'string' ) {
144
+ // dynamic component that resolved to a `resolveDynamicComponent` call
145
+ // expression - since the reoslved result may be a plain element (string)
146
+ // or a VNode, handle it with `renderVNode`.
147
+ node . ssrCodegenNode = createCallExpression (
148
+ context . helper ( SSR_RENDER_VNODE ) ,
149
+ [
150
+ `_push` ,
151
+ createCallExpression ( context . helper ( CREATE_VNODE ) , [
152
+ component ,
153
+ props ,
154
+ slots
155
+ ] ) ,
156
+ `_parent`
157
+ ]
158
+ )
159
+ } else {
160
+ node . ssrCodegenNode = createCallExpression (
161
+ context . helper ( SSR_RENDER_COMPONENT ) ,
162
+ [ component , props , slots , `_parent` ]
163
+ )
164
+ }
141
165
}
142
166
}
143
167
144
168
export function ssrProcessComponent (
145
169
node : ComponentNode ,
146
170
context : SSRTransformContext
147
171
) {
172
+ const component = componentTypeMap . get ( node ) !
148
173
if ( ! node . ssrCodegenNode ) {
149
174
// this is a built-in component that fell-through.
150
- const component = componentTypeMap . get ( node ) !
151
175
if ( component === TELEPORT ) {
152
176
return ssrProcessTeleport ( node , context )
153
177
} else if ( component === SUSPENSE ) {
@@ -176,7 +200,16 @@ export function ssrProcessComponent(
176
200
vnodeBranch
177
201
)
178
202
}
179
- context . pushStatement ( createCallExpression ( `_push` , [ node . ssrCodegenNode ] ) )
203
+ if ( typeof component === 'string' ) {
204
+ // static component
205
+ context . pushStatement (
206
+ createCallExpression ( `_push` , [ node . ssrCodegenNode ] )
207
+ )
208
+ } else {
209
+ // dynamic component (`resolveDynamicComponent` call)
210
+ // the codegen node is a `renderVNode` call
211
+ context . pushStatement ( node . ssrCodegenNode )
212
+ }
180
213
}
181
214
}
182
215
0 commit comments