751b83d2e9d6039df1a06cd5d912aacd0eb0db4f47a6eef36f246fc2d8637d4da4c5711c1780cabaf810ddd5b482efea48070c65e7855f7474d77d7dcd9e68 1.9 KB

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