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