From 9b22d86ab315a3c6061a6a4776eab1964304f92e Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 8 Mar 2018 09:51:03 -0500 Subject: [PATCH] fix: install ssr helpers for functional context during SSR close #7443, ref nuxt/nuxt.js#2565 --- flow/component.js | 2 ++ scripts/config.js | 2 +- src/core/index.js | 6 ++++ src/core/vdom/create-functional-component.js | 12 +++---- .../optimizing-compiler/runtime-helpers.js | 35 +++++++++++-------- test/ssr/ssr-string.spec.js | 19 ++++++++++ 6 files changed, 55 insertions(+), 21 deletions(-) diff --git a/flow/component.js b/flow/component.js index e3326bd3..0dc67a48 100644 --- a/flow/component.js +++ b/flow/component.js @@ -16,6 +16,8 @@ declare interface Component { static directive: (id: string, def?: Function | Object) => Function | Object | void; static component: (id: string, def?: Class | Object) => Class; static filter: (id: string, def?: Function) => Function | void; + // functional context constructor + static FunctionalRenderContext: Function; // public properties $el: any; // so that we can attach __vue__ to it diff --git a/scripts/config.js b/scripts/config.js index b0c705e4..4fe40552 100644 --- a/scripts/config.js +++ b/scripts/config.js @@ -123,7 +123,7 @@ const builds = { format: 'cjs', external: Object.keys(require('../packages/vue-server-renderer/package.json').dependencies) }, - 'web-server-basic-renderer': { + 'web-server-renderer-basic': { entry: resolve('web/entry-server-basic-renderer.js'), dest: resolve('packages/vue-server-renderer/basic.js'), format: 'umd', diff --git a/src/core/index.js b/src/core/index.js index b2a0cb8c..daf6203b 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -1,6 +1,7 @@ import Vue from './instance/index' import { initGlobalAPI } from './global-api/index' import { isServerRendering } from 'core/util/env' +import { FunctionalRenderContext } from 'core/vdom/create-functional-component' initGlobalAPI(Vue) @@ -15,6 +16,11 @@ Object.defineProperty(Vue.prototype, '$ssrContext', { } }) +// expose FunctionalRenderContext for ssr runtime helper installation +Object.defineProperty(Vue, 'FunctionalRenderContext', { + value: FunctionalRenderContext +}) + Vue.version = '__VERSION__' export default Vue diff --git a/src/core/vdom/create-functional-component.js b/src/core/vdom/create-functional-component.js index d0cbd0a2..c4e4cf9e 100644 --- a/src/core/vdom/create-functional-component.js +++ b/src/core/vdom/create-functional-component.js @@ -15,12 +15,12 @@ import { validateProp } from '../util/index' -function FunctionalRenderContext ( - data, - props, - children, - parent, - Ctor +export function FunctionalRenderContext ( + data: VNodeData, + props: Object, + children: ?Array, + parent: Component, + Ctor: Class ) { const options = Ctor.options this.data = data diff --git a/src/server/optimizing-compiler/runtime-helpers.js b/src/server/optimizing-compiler/runtime-helpers.js index b4f7c1f1..9abfe198 100644 --- a/src/server/optimizing-compiler/runtime-helpers.js +++ b/src/server/optimizing-compiler/runtime-helpers.js @@ -17,22 +17,29 @@ import { isRenderableAttr } from 'web/server/util' +const ssrHelpers = { + _ssrEscape: escape, + _ssrNode: renderStringNode, + _ssrList: renderStringList, + _ssrAttr: renderAttr, + _ssrAttrs: renderAttrs, + _ssrDOMProps: renderDOMProps, + _ssrClass: renderSSRClass, + _ssrStyle: renderSSRStyle +} + export function installSSRHelpers (vm: Component) { - if (vm._ssrNode) return - let Ctor = vm.constructor - while (Ctor.super) { - Ctor = Ctor.super + if (vm._ssrNode) { + return + } + let Vue = vm.constructor + while (Vue.super) { + Vue = Vue.super + } + extend(Vue.prototype, ssrHelpers) + if (Vue.FunctionalRenderContext) { + extend(Vue.FunctionalRenderContext.prototype, ssrHelpers) } - extend(Ctor.prototype, { - _ssrEscape: escape, - _ssrNode: renderStringNode, - _ssrList: renderStringList, - _ssrAttr: renderAttr, - _ssrAttrs: renderAttrs, - _ssrDOMProps: renderDOMProps, - _ssrClass: renderSSRClass, - _ssrStyle: renderSSRStyle - }) } class StringNode { diff --git a/test/ssr/ssr-string.spec.js b/test/ssr/ssr-string.spec.js index 66ed897c..f370618d 100644 --- a/test/ssr/ssr-string.spec.js +++ b/test/ssr/ssr-string.spec.js @@ -1145,6 +1145,25 @@ describe('SSR: renderToString', () => { done() }) }) + + it('should expose ssr helpers on functional context', done => { + let called = false + renderVmWithOptions({ + template: `
`, + components: { + foo: { + functional: true, + render (h, ctx) { + expect(ctx._ssrNode).toBeTruthy() + called = true + } + } + } + }, () => { + expect(called).toBe(true) + done() + }) + }) }) function renderVmWithOptions (options, cb) {