create-renderer.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /* @flow */
  2. import RenderStream from './render-stream'
  3. import TemplateRenderer from './template-renderer/index'
  4. import { createWriteFunction } from './write'
  5. import { createRenderFunction } from './render'
  6. import type { ClientManifest } from './template-renderer/index'
  7. export type Renderer = {
  8. renderToString: (component: Component, context: any, cb: any) => void;
  9. renderToStream: (component: Component, context?: Object) => stream$Readable;
  10. };
  11. type RenderCache = {
  12. get: (key: string, cb?: Function) => string | void;
  13. set: (key: string, val: string) => void;
  14. has?: (key: string, cb?: Function) => boolean | void;
  15. };
  16. export type RenderOptions = {
  17. modules?: Array<(vnode: VNode) => string>;
  18. directives?: Object;
  19. isUnaryTag?: Function;
  20. cache?: RenderCache;
  21. template?: string;
  22. inject?: boolean;
  23. basedir?: string;
  24. shouldPreload?: Function;
  25. clientManifest?: ClientManifest;
  26. runInNewContext?: boolean;
  27. };
  28. export function createRenderer ({
  29. modules = [],
  30. directives = {},
  31. isUnaryTag = (() => false),
  32. template,
  33. inject,
  34. cache,
  35. shouldPreload,
  36. clientManifest
  37. }: RenderOptions = {}): Renderer {
  38. const render = createRenderFunction(modules, directives, isUnaryTag, cache)
  39. const templateRenderer = new TemplateRenderer({
  40. template,
  41. inject,
  42. shouldPreload,
  43. clientManifest
  44. })
  45. return {
  46. renderToString (
  47. component: Component,
  48. context: any,
  49. done: any
  50. ): void {
  51. if (typeof context === 'function') {
  52. done = context
  53. context = {}
  54. }
  55. if (context) {
  56. templateRenderer.bindRenderFns(context)
  57. }
  58. let result = ''
  59. const write = createWriteFunction(text => {
  60. result += text
  61. return false
  62. }, done)
  63. try {
  64. render(component, write, context, () => {
  65. if (template) {
  66. result = templateRenderer.renderSync(result, context)
  67. }
  68. done(null, result)
  69. })
  70. } catch (e) {
  71. done(e)
  72. }
  73. },
  74. renderToStream (
  75. component: Component,
  76. context?: Object
  77. ): stream$Readable {
  78. if (context) {
  79. templateRenderer.bindRenderFns(context)
  80. }
  81. const renderStream = new RenderStream((write, done) => {
  82. render(component, write, context, done)
  83. })
  84. if (!template) {
  85. return renderStream
  86. } else {
  87. const templateStream = templateRenderer.createStream(context)
  88. renderStream.on('error', err => {
  89. templateStream.emit('error', err)
  90. })
  91. renderStream.pipe(templateStream)
  92. return templateStream
  93. }
  94. }
  95. }
  96. }