@@ -18,7 +18,9 @@ import {
18
18
SequenceExpression ,
19
19
ConditionalExpression ,
20
20
CacheExpression ,
21
- locStub
21
+ locStub ,
22
+ SSRCodegenNode ,
23
+ TemplateLiteral
22
24
} from './ast'
23
25
import { SourceMapGenerator , RawSourceMap } from 'source-map'
24
26
import {
@@ -44,7 +46,7 @@ import {
44
46
} from './runtimeHelpers'
45
47
import { ImportItem } from './transform'
46
48
47
- type CodegenNode = TemplateChildNode | JSChildNode
49
+ type CodegenNode = TemplateChildNode | JSChildNode | SSRCodegenNode
48
50
49
51
export interface CodegenResult {
50
52
code : string
@@ -74,7 +76,8 @@ function createCodegenContext(
74
76
prefixIdentifiers = mode === 'module' || mode === 'cjs' ,
75
77
sourceMap = false ,
76
78
filename = `template.vue.html` ,
77
- scopeId = null
79
+ scopeId = null ,
80
+ ssr = false
78
81
} : CodegenOptions
79
82
) : CodegenContext {
80
83
const context : CodegenContext = {
@@ -83,6 +86,7 @@ function createCodegenContext(
83
86
sourceMap,
84
87
filename,
85
88
scopeId,
89
+ ssr,
86
90
source : ast . loc . source ,
87
91
code : `` ,
88
92
column : 1 ,
@@ -169,7 +173,8 @@ export function generate(
169
173
indent,
170
174
deindent,
171
175
newline,
172
- scopeId
176
+ scopeId,
177
+ ssr
173
178
} = context
174
179
const hasHelpers = ast . helpers . length > 0
175
180
const useWithBlock = ! prefixIdentifiers && mode !== 'module'
@@ -231,10 +236,14 @@ export function generate(
231
236
}
232
237
233
238
// enter render function
234
- if ( genScopeId ) {
239
+ if ( genScopeId && ! ssr ) {
235
240
push ( `const render = withId(` )
236
241
}
237
- push ( `function render() {` )
242
+ if ( ! ssr ) {
243
+ push ( `function render() {` )
244
+ } else {
245
+ push ( `function ssrRender(_ctx, _push, _parent) {` )
246
+ }
238
247
indent ( )
239
248
240
249
if ( useWithBlock ) {
@@ -255,7 +264,7 @@ export function generate(
255
264
}
256
265
newline ( )
257
266
}
258
- } else {
267
+ } else if ( ! ssr ) {
259
268
push ( `const _ctx = this` )
260
269
if ( ast . cached > 0 ) {
261
270
newline ( )
@@ -276,7 +285,9 @@ export function generate(
276
285
}
277
286
278
287
// generate the VNode tree expression
279
- push ( `return ` )
288
+ if ( ! ssr ) {
289
+ push ( `return ` )
290
+ }
280
291
if ( ast . codegenNode ) {
281
292
genNode ( ast . codegenNode , context )
282
293
} else {
@@ -291,7 +302,7 @@ export function generate(
291
302
deindent ( )
292
303
push ( `}` )
293
304
294
- if ( genScopeId ) {
305
+ if ( genScopeId && ! ssr ) {
295
306
push ( `)` )
296
307
}
297
308
@@ -325,7 +336,7 @@ function genHoists(hoists: JSChildNode[], context: CodegenContext) {
325
336
return
326
337
}
327
338
const { push, newline, helper, scopeId, mode } = context
328
- const genScopeId = ! __BROWSER__ && scopeId != null && mode === 'module '
339
+ const genScopeId = ! __BROWSER__ && scopeId != null && mode !== 'function '
329
340
newline ( )
330
341
331
342
// push scope Id before initilaizing hoisted vnodes so that these vnodes
@@ -469,6 +480,18 @@ function genNode(node: CodegenNode | symbol | string, context: CodegenContext) {
469
480
case NodeTypes . JS_CACHE_EXPRESSION :
470
481
genCacheExpression ( node , context )
471
482
break
483
+
484
+ // SSR only types
485
+ case NodeTypes . JS_BLOCK_STATEMENT :
486
+ ! __BROWSER__ && genNodeList ( node . body , context , true )
487
+ break
488
+ case NodeTypes . JS_TEMPLATE_LITERAL :
489
+ ! __BROWSER__ && genTemplateLiteral ( node , context )
490
+ break
491
+ case NodeTypes . JS_IF_STATEMENT :
492
+ // TODO
493
+ break
494
+
472
495
/* istanbul ignore next */
473
496
default :
474
497
if ( __DEV__ ) {
@@ -589,10 +612,10 @@ function genFunctionExpression(
589
612
context : CodegenContext
590
613
) {
591
614
const { push, indent, deindent, scopeId, mode } = context
592
- const { params, returns, newline, isSlot } = node
615
+ const { params, returns, body , newline, isSlot } = node
593
616
// slot functions also need to push scopeId before rendering its content
594
617
const genScopeId =
595
- ! __BROWSER__ && isSlot && scopeId != null && mode === 'module '
618
+ ! __BROWSER__ && isSlot && scopeId != null && mode !== 'function '
596
619
597
620
if ( genScopeId ) {
598
621
push ( `withId(` )
@@ -604,17 +627,23 @@ function genFunctionExpression(
604
627
genNode ( params , context )
605
628
}
606
629
push ( `) => ` )
607
- if ( newline ) {
630
+ if ( newline || body ) {
608
631
push ( `{` )
609
632
indent ( )
610
- push ( `return ` )
611
633
}
612
- if ( isArray ( returns ) ) {
613
- genNodeListAsArray ( returns , context )
614
- } else {
615
- genNode ( returns , context )
634
+ if ( returns ) {
635
+ if ( newline ) {
636
+ push ( `return ` )
637
+ }
638
+ if ( isArray ( returns ) ) {
639
+ genNodeListAsArray ( returns , context )
640
+ } else {
641
+ genNode ( returns , context )
642
+ }
643
+ } else if ( body ) {
644
+ genNode ( body , context )
616
645
}
617
- if ( newline ) {
646
+ if ( newline || body ) {
618
647
deindent ( )
619
648
push ( `}` )
620
649
}
@@ -686,3 +715,19 @@ function genCacheExpression(node: CacheExpression, context: CodegenContext) {
686
715
}
687
716
push ( `)` )
688
717
}
718
+
719
+ function genTemplateLiteral ( node : TemplateLiteral , context : CodegenContext ) {
720
+ const { push } = context
721
+ push ( '`' )
722
+ for ( let i = 0 ; i < node . elements . length ; i ++ ) {
723
+ const e = node . elements [ i ]
724
+ if ( isString ( e ) ) {
725
+ push ( e . replace ( / ` / g, '\\`' ) )
726
+ } else {
727
+ push ( '${' )
728
+ genNode ( e , context )
729
+ push ( '}' )
730
+ }
731
+ }
732
+ push ( '`' )
733
+ }
0 commit comments