@@ -30,17 +30,20 @@ import {
3030 traverseNode ,
3131 ExpressionNode ,
3232 TemplateNode ,
33- findProp ,
34- JSChildNode
33+ SUSPENSE
3534} from '@vue/compiler-dom'
36- import { SSR_RENDER_COMPONENT , SSR_RENDER_PORTAL } from '../runtimeHelpers'
35+ import { SSR_RENDER_COMPONENT } from '../runtimeHelpers'
3736import {
3837 SSRTransformContext ,
3938 processChildren ,
4039 processChildrenAsStatement
4140} from '../ssrCodegenTransform'
41+ import { ssrProcessPortal } from './ssrTransformPortal'
42+ import {
43+ ssrProcessSuspense ,
44+ ssrTransformSuspense
45+ } from './ssrTransformSuspense'
4246import { isSymbol , isObject , isArray } from '@vue/shared'
43- import { createSSRCompilerError , SSRErrorCodes } from '../errors'
4447
4548// We need to construct the slot functions in the 1st pass to ensure proper
4649// scope tracking, but the children of each slot cannot be processed until
@@ -56,6 +59,12 @@ interface WIPSlotEntry {
5659
5760const componentTypeMap = new WeakMap < ComponentNode , symbol > ( )
5861
62+ // ssr component transform is done in two phases:
63+ // In phase 1. we use `buildSlot` to analyze the children of the component into
64+ // WIP slot functions (it must be done in phase 1 because `buildSlot` relies on
65+ // the core transform context).
66+ // In phase 2. we convert the WIP slots from phase 1 into ssr-specific codegen
67+ // nodes.
5968export const ssrTransformComponent : NodeTransform = ( node , context ) => {
6069 if (
6170 node . type !== NodeTypes . ELEMENT ||
@@ -67,6 +76,9 @@ export const ssrTransformComponent: NodeTransform = (node, context) => {
6776 const component = resolveComponentType ( node , context , true /* ssr */ )
6877 if ( isSymbol ( component ) ) {
6978 componentTypeMap . set ( node , component )
79+ if ( component === SUSPENSE ) {
80+ return ssrTransformSuspense ( node , context )
81+ }
7082 return // built-in component: fallthrough
7183 }
7284
@@ -132,12 +144,15 @@ export function ssrProcessComponent(
132144) {
133145 if ( ! node . ssrCodegenNode ) {
134146 // this is a built-in component that fell-through.
135- // just render its children.
136147 const component = componentTypeMap . get ( node ) !
137148 if ( component === PORTAL ) {
138149 return ssrProcessPortal ( node , context )
150+ } else if ( component === SUSPENSE ) {
151+ return ssrProcessSuspense ( node , context )
152+ } else {
153+ // real fall-through (e.g. KeepAlive): just render its children.
154+ processChildren ( node . children , context )
139155 }
140- processChildren ( node . children , context )
141156 } else {
142157 // finish up slot function expressions from the 1st pass.
143158 const wipEntries = wipMap . get ( node ) || [ ]
@@ -161,47 +176,6 @@ export function ssrProcessComponent(
161176 }
162177}
163178
164- function ssrProcessPortal ( node : ComponentNode , context : SSRTransformContext ) {
165- const targetProp = findProp ( node , 'target' )
166- if ( ! targetProp ) {
167- context . onError (
168- createSSRCompilerError ( SSRErrorCodes . X_SSR_NO_PORTAL_TARGET , node . loc )
169- )
170- return
171- }
172-
173- let target : JSChildNode
174- if ( targetProp . type === NodeTypes . ATTRIBUTE && targetProp . value ) {
175- target = createSimpleExpression ( targetProp . value . content , true )
176- } else if ( targetProp . type === NodeTypes . DIRECTIVE && targetProp . exp ) {
177- target = targetProp . exp
178- } else {
179- context . onError (
180- createSSRCompilerError (
181- SSRErrorCodes . X_SSR_NO_PORTAL_TARGET ,
182- targetProp . loc
183- )
184- )
185- return
186- }
187-
188- const contentRenderFn = createFunctionExpression (
189- [ `_push` ] ,
190- undefined , // Body is added later
191- true , // newline
192- false , // isSlot
193- node . loc
194- )
195- contentRenderFn . body = processChildrenAsStatement ( node . children , context )
196- context . pushStatement (
197- createCallExpression ( context . helper ( SSR_RENDER_PORTAL ) , [
198- contentRenderFn ,
199- target ,
200- `_parent`
201- ] )
202- )
203- }
204-
205179export const rawOptionsMap = new WeakMap < RootNode , CompilerOptions > ( )
206180
207181const [ baseNodeTransforms , baseDirectiveTransforms ] = getBaseTransformPreset (
0 commit comments