diff --git a/flow/component.js b/flow/component.js index 04418ded..da6f9ca6 100644 --- a/flow/component.js +++ b/flow/component.js @@ -1,6 +1,7 @@ import type { Config } from '../src/core/config' import type VNode from '../src/core/vdom/vnode' import type Watcher from '../src/core/observer/watcher' +import type StringNode from '../src/server/optimizing-compiler/runtime-helpers' declare interface Component { // constructor information @@ -108,6 +109,11 @@ declare interface Component { // resolve scoped slots _u: (scopedSlots: ScopedSlotsData, res?: Object) => { [key: string]: Function }; + // SSR specific + _ssrNode: (open: string, close?: string, ) => StringNode; + _ssrList: (val: any, render: () => string) => string; + _ssrEscape: (v: string) => string; + // allow dynamic method registration [key: string]: any }; diff --git a/src/compiler/codegen/index.js b/src/compiler/codegen/index.js index c082d9dd..1ea6450c 100644 --- a/src/compiler/codegen/index.js +++ b/src/compiler/codegen/index.js @@ -32,7 +32,7 @@ export class CodegenState { } } -type CodegenResult = { +export type CodegenResult = { render: string, staticRenderFns: Array }; diff --git a/src/compiler/to-function.js b/src/compiler/to-function.js index cf13e581..6137422c 100644 --- a/src/compiler/to-function.js +++ b/src/compiler/to-function.js @@ -6,7 +6,6 @@ import { warn, tip } from 'core/util/debug' type CompiledFunctionResult = { render: Function; staticRenderFns: Array; - stringRenderFns?: Array; }; function createFunction (code, errors) { @@ -80,12 +79,6 @@ export function createCompileToFunctionFn (compile: Function): Function { res.staticRenderFns = compiled.staticRenderFns.map(code => { return createFunction(code, fnGenErrors) }) - // ssr-specific - if (res.stringRenderFns) { - res.stringRenderFns = compiled.stringRenderFns.map(code => { - return createFunction(code, fnGenErrors) - }) - } // check function generation errors. // this should only happen if there is a bug in the compiler itself. diff --git a/src/server/optimizing-compiler/codegen.js b/src/server/optimizing-compiler/codegen.js index 0c6b4d0e..c78ee650 100644 --- a/src/server/optimizing-compiler/codegen.js +++ b/src/server/optimizing-compiler/codegen.js @@ -16,11 +16,7 @@ import { CodegenState } from 'compiler/codegen/index' -type SSRCompileResult = { - render: string; - staticRenderFns: Array; - stringRenderFns: Array; -}; +import type { CodegenResult } from 'compiler/codegen/index' // segment types const RAW = 0 @@ -32,29 +28,19 @@ type StringSegment = { value: string; }; -class SSRCodegenState extends CodegenState { - stringRenderFns: Array; - - constructor (options: CompilerOptions) { - super(options) - this.stringRenderFns = [] - } -} - export function generate ( ast: ASTElement | void, options: CompilerOptions -): SSRCompileResult { - const state = new SSRCodegenState(options) +): CodegenResult { + const state = new CodegenState(options) const code = ast ? genSSRElement(ast, state) : '_c("div")' return { render: `with(this){return ${code}}`, - staticRenderFns: state.staticRenderFns, - stringRenderFns: state.stringRenderFns + staticRenderFns: state.staticRenderFns } } -function genSSRElement (el: ASTElement, state: SSRCodegenState): string { +function genSSRElement (el: ASTElement, state: CodegenState): string { if (el.for && !el.forProcessed) { return genFor(el, state, genSSRElement) } else if (el.if && !el.ifProcessed) { diff --git a/src/server/optimizing-compiler/index.js b/src/server/optimizing-compiler/index.js index dabe398f..893630d6 100644 --- a/src/server/optimizing-compiler/index.js +++ b/src/server/optimizing-compiler/index.js @@ -15,7 +15,6 @@ export const createCompiler = createCompilerCreator(function baseCompile ( return { ast, render: code.render, - staticRenderFns: code.staticRenderFns, - stringRenderFns: code.stringRenderFns + staticRenderFns: code.staticRenderFns } }) diff --git a/src/server/optimizing-compiler/runtime-helpers.js b/src/server/optimizing-compiler/runtime-helpers.js index d2b349b3..775b6717 100644 --- a/src/server/optimizing-compiler/runtime-helpers.js +++ b/src/server/optimizing-compiler/runtime-helpers.js @@ -1,15 +1,35 @@ /* @flow */ +import { escape } from 'he' import { isObject } from 'shared/util' -function StringNode (open, close, children) { - this.isString = true - this.open = open - this.close = close - this.children = children +export function installSSRHelpers (vm: Component) { + let Ctor = vm.constructor + while (Ctor.super) { + Ctor = Ctor.super + } + if (!Ctor.prototype._ssrNode) { + Ctor.prototype._ssrNode = createStringNode + Ctor.prototype._ssrList = createStringList + Ctor.prototype._ssrEscape = escape + } +} + +export class StringNode { + isString: boolean; + open: string; + close: ?string; + children: ?Array; + + constructor (open: string, close?: string, children?: Array) { + this.isString = true + this.open = open + this.close = close + this.children = children + } } -export function createStringNode ( +function createStringNode ( open: string, close?: string, children?: Array @@ -17,7 +37,7 @@ export function createStringNode ( return new StringNode(open, close, children) } -export function createStringList (val: any, render: () => string): string { +function createStringList (val: any, render: () => string): string { let ret = '' let i, l, keys, key if (Array.isArray(val) || typeof val === 'string') { diff --git a/src/server/render.js b/src/server/render.js index e7b46127..db10c92d 100644 --- a/src/server/render.js +++ b/src/server/render.js @@ -5,15 +5,11 @@ const { escape } = require('he') import { SSR_ATTR } from 'shared/constants' import { RenderContext } from './render-context' import { ssrCompileToFunctions } from 'web/server/compiler' +import { installSSRHelpers } from './optimizing-compiler/runtime-helpers' import { createComponentInstanceForVnode } from 'core/vdom/create-component' import { isDef, isUndef, isTrue } from 'shared/util' -import { - createStringNode, - createStringList -} from './optimizing-compiler/runtime-helpers' - let warned = Object.create(null) const warnOnce = msg => { if (!warned[msg]) { @@ -23,9 +19,6 @@ const warnOnce = msg => { } const normalizeRender = vm => { - vm._ssrEscape = escape - vm._ssrNode = createStringNode - vm._ssrList = createStringList const { render, template } = vm.$options if (isUndef(render)) { if (template) { @@ -310,6 +303,7 @@ export function createRenderFunction ( isUnaryTag, modules, directives, cache }) + installSSRHelpers(component) normalizeRender(component) renderNode(component._render(), true, context) }