Browse Source

annotate ssr code

dev
Evan You 9 years ago
parent
commit
6d712753d8
  1. 1
      .flowconfig
  2. 10
      flow/declarations.js
  3. 47
      src/server/create-renderer.js
  4. 21
      src/server/render-stream.js
  5. 27
      src/server/render.js

1
.flowconfig

@ -8,6 +8,7 @@
[include]
[libs]
flow
[options]
module.name_mapper='^compiler/\(.*\)$' -> '<PROJECT_ROOT>/src/compiler/\1'

10
flow/declarations.js

@ -0,0 +1,10 @@
declare class Vue {
_render: Function;
}
declare interface VNode {
tag: ?string;
text: ?string;
data: ?Object;
children: ?Array<VNode>;
}

47
src/server/create-renderer.js

@ -1,14 +1,23 @@
/* @flow */
import RenderStream from './render-stream'
import { createRenderFunction } from './render'
import { warn } from 'core/util/debug'
export const MAX_STACK_DEPTH = 1000
export const MAX_STACK_DEPTH = 10
export function createRenderer ({
modules = [],
directives = {},
isUnaryTag = (() => false)
} = {}) {
}: {
modules: Array<Function>,
directives: Object,
isUnaryTag: Function
} = {}): {
renderToString: Function,
renderToStream: Function
} {
if (process.env.VUE_ENV !== 'server') {
warn(
'You are using createRenderer without setting VUE_ENV enviroment variable to "server". ' +
@ -17,35 +26,35 @@ export function createRenderer ({
)
}
const render = createRenderFunction(modules, directives, isUnaryTag)
return {
renderToString (component, done) {
renderToString (component: Vue, done: Function): void {
let result = ''
let stackDepth = 0
const write = (str, next) => {
const write = (str: string, next: Function) => {
result += str
if (next) {
if (stackDepth >= MAX_STACK_DEPTH) {
process.nextTick(() => {
try { next() } catch (e) {
done(e)
}
})
} else {
stackDepth++
next()
stackDepth--
}
if (stackDepth >= MAX_STACK_DEPTH) {
process.nextTick(() => {
try { next() } catch (e) {
done(e)
}
})
} else {
done(null, result)
stackDepth++
next()
stackDepth--
}
}
try {
render(component, write)
render(component, write, () => {
done(null, result)
})
} catch (e) {
done(e)
}
},
renderToStream (component) {
renderToStream (component: Vue): RenderStream {
return new RenderStream((write, done) => {
render(component, write, done)
})

21
src/server/render-stream.js

@ -1,3 +1,5 @@
/* @flow */
import stream from 'stream'
import { MAX_STACK_DEPTH } from './create-renderer'
@ -7,13 +9,23 @@ import { MAX_STACK_DEPTH } from './create-renderer'
* Modified by Evan You (@yyx990803)
*/
export default class RenderStream extends stream.Readable {
constructor (render) {
buffer: string;
render: Function;
expectedSize: number;
stackDepth: number;
write: Function;
next: Function;
end: Function;
done: boolean;
constructor (render: Function) {
super()
this.buffer = ''
this.render = render
this.expectedSize = 0
this.stackDepth = 0
this.write = (text, next) => {
this.write = (text: string, next: Function) => {
const n = this.expectedSize
this.buffer += text
if (this.buffer.length >= n) {
@ -43,7 +55,7 @@ export default class RenderStream extends stream.Readable {
}
}
pushBySize (n) {
pushBySize (n: number) {
const bufferToPush = this.buffer.substring(0, n)
this.buffer = this.buffer.substring(n)
this.push(bufferToPush)
@ -65,7 +77,7 @@ export default class RenderStream extends stream.Readable {
}
}
_read (n) {
_read (n: number) {
this.expectedSize = n
// it's possible that the last chunk added bumped the buffer up to > 2 * n,
// which means we will need to go through multiple read calls to drain it
@ -79,7 +91,6 @@ export default class RenderStream extends stream.Readable {
return
}
if (!this.next) {
this.stackDepth = 0
// start the rendering chain.
this.tryRender()
} else {

27
src/server/render.js

@ -1,7 +1,13 @@
/* @flow */
import { createComponentInstanceForVnode } from 'core/vdom/create-component'
export function createRenderFunction (modules, directives, isUnaryTag) {
function renderNode (node, write, next, isRoot) {
export function createRenderFunction (
modules: Array<Function>,
directives: Object,
isUnaryTag: Function
) {
function renderNode (node: VNode, write: Function, next: Function, isRoot: boolean) {
if (node.componentOptions) {
const child = createComponentInstanceForVnode(node)
renderNode(child._render(), write, next, isRoot)
@ -14,7 +20,7 @@ export function createRenderFunction (modules, directives, isUnaryTag) {
}
}
function renderElement (el, write, next, isRoot) {
function renderElement (el: VNode, write: Function, next: Function, isRoot: boolean) {
if (isRoot) {
if (!el.data) el.data = {}
if (!el.data.attrs) el.data.attrs = {}
@ -27,27 +33,28 @@ export function createRenderFunction (modules, directives, isUnaryTag) {
} else if (!el.children || !el.children.length) {
write(startTag + endTag, next)
} else {
const children: Array<VNode> = el.children || []
write(startTag, () => {
const total = el.children.length
const total = children.length
let rendered = 0
function renderChild (child) {
function renderChild (child: VNode) {
renderNode(child, write, () => {
rendered++
if (rendered < total) {
renderChild(el.children[rendered])
renderChild(children[rendered])
} else {
write(endTag, next)
}
})
}, false)
}
renderChild(el.children[0])
renderChild(children[0])
})
}
}
function renderStartingTag (node) {
function renderStartingTag (node: VNode) {
let markup = `<${node.tag}`
if (node.data) {
// check directives
@ -73,7 +80,7 @@ export function createRenderFunction (modules, directives, isUnaryTag) {
return markup + '>'
}
return function render (component, write, done) {
return function render (component: Vue, write: Function, done: Function) {
renderNode(component._render(), write, done, true)
}
}

Loading…
Cancel
Save