UNPKG

1.93 kBJavaScriptView Raw
1/* @flow */
2
3const Transform = require('stream').Transform
4import type TemplateRenderer from './index'
5import type { ParsedTemplate } from './parse-template'
6
7export default class TemplateStream extends Transform {
8 started: boolean;
9 renderer: TemplateRenderer;
10 template: ParsedTemplate;
11 context: Object;
12 inject: boolean;
13
14 constructor (
15 renderer: TemplateRenderer,
16 template: ParsedTemplate,
17 context: Object
18 ) {
19 super()
20 this.started = false
21 this.renderer = renderer
22 this.template = template
23 this.context = context || {}
24 this.inject = renderer.inject
25 }
26
27 _transform (data: Buffer | string, encoding: string, done: Function) {
28 if (!this.started) {
29 this.emit('beforeStart')
30 this.start()
31 }
32 this.push(data)
33 done()
34 }
35
36 start () {
37 this.started = true
38 this.push(this.template.head(this.context))
39
40 if (this.inject) {
41 // inline server-rendered head meta information
42 if (this.context.head) {
43 this.push(this.context.head)
44 }
45
46 // inline preload/prefetch directives for initial/async chunks
47 const links = this.renderer.renderResourceHints(this.context)
48 if (links) {
49 this.push(links)
50 }
51
52 // CSS files and inline server-rendered CSS collected by vue-style-loader
53 const styles = this.renderer.renderStyles(this.context)
54 if (styles) {
55 this.push(styles)
56 }
57 }
58
59 this.push(this.template.neck(this.context))
60 }
61
62 _flush (done: Function) {
63 this.emit('beforeEnd')
64
65 if (this.inject) {
66 // inline initial store state
67 const state = this.renderer.renderState(this.context)
68 if (state) {
69 this.push(state)
70 }
71
72 // embed scripts needed
73 const scripts = this.renderer.renderScripts(this.context)
74 if (scripts) {
75 this.push(scripts)
76 }
77 }
78
79 this.push(this.template.tail(this.context))
80 done()
81 }
82}