Skip to content

Commit 9ca0c35

Browse files
committed
ssr: inject userContext into vnode to ensure correctness
1 parent 67d02fb commit 9ca0c35

File tree

6 files changed

+26
-38
lines changed

6 files changed

+26
-38
lines changed

src/core/instance/render.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,9 @@ import { renderStatic, markOnce } from './render-helpers/render-static'
2727
import { resolveSlots, resolveScopedSlots } from './render-helpers/resolve-slots'
2828

2929
export function initRender (vm: Component) {
30-
vm.$vnode = null // the placeholder node in parent tree
3130
vm._vnode = null // the root of the child tree
3231
vm._staticTrees = null
33-
const parentVnode = vm.$options._parentVnode
32+
const parentVnode = vm.$vnode = vm.$options._parentVnode // the placeholder node in parent tree
3433
const renderContext = parentVnode && parentVnode.context
3534
vm.$slots = resolveSlots(vm.$options._renderChildren, renderContext)
3635
vm.$scopedSlots = emptyObject

src/server/bundle-renderer/create-bundle-runner.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ export function createBundleRunner (entry, files, basedir, runInNewContext) {
104104
// slightly differently.
105105
const initialContext = {}
106106
const sharedContext = createContext(initialContext)
107+
delete sharedContext.__VUE_SSR_CONTEXT__
107108
let runner // lazy creation so that errors can be caught by user
108109
return (userContext = {}) => new Promise(resolve => {
109110
if (!runner) {
@@ -115,7 +116,6 @@ export function createBundleRunner (entry, files, basedir, runInNewContext) {
115116
)
116117
}
117118
}
118-
sharedContext.__VUE_SSR_CONTEXT__ = userContext
119119
userContext._registeredComponents = new Set()
120120
// vue-style-loader styles imported outside of component lifecycle hooks
121121
if (initialContext._styles) {

src/server/render.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,13 @@ function renderComponentWithCache (node, isRoot, key, context) {
141141

142142
function renderComponentInner (node, isRoot, context) {
143143
const prevActive = context.activeInstance
144+
// expose userContext on vnode
145+
node.ssrContext = context.userContext
144146
const child = context.activeInstance = createComponentInstanceForVnode(
145147
node,
146148
context.activeInstance
147149
)
150+
node.ssrContext = null
148151
normalizeRender(child)
149152
const childNode = child._render()
150153
childNode.parent = node

test/ssr/fixtures/async-bar.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
/* globals __VUE_SSR_CONTEXT__ */
2-
31
module.exports = {
42
beforeCreate () {
5-
__VUE_SSR_CONTEXT__._registeredComponents.add('__MODULE_ID__')
3+
this.$vnode.ssrContext._registeredComponents.add('__MODULE_ID__')
64
},
75
render (h) {
86
return h('div', 'async bar')

test/ssr/fixtures/async-foo.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
/* globals __VUE_SSR_CONTEXT__ */
2-
31
// import image and font
42
import font from './test.woff2'
53
import image from './test.png'
64

75
module.exports = {
86
beforeCreate () {
9-
__VUE_SSR_CONTEXT__._registeredComponents.add('__MODULE_ID__')
7+
this.$vnode.ssrContext._registeredComponents.add('__MODULE_ID__')
108
},
119
render (h) {
1210
return h('div', `async ${font} ${image}`)

test/ssr/fixtures/nested-cache.js

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,46 @@
1-
/* globals __VUE_SSR_CONTEXT__ */
2-
31
import Vue from '../../../dist/vue.runtime.common.js'
42

5-
function register (id, context) {
6-
context = context || __VUE_SSR_CONTEXT__
7-
context.registered.push(id)
3+
function createRegisterFn (id) {
4+
return function (context) {
5+
context = context || this.$vnode.ssrContext
6+
context.registered.push(id)
7+
}
8+
}
9+
10+
function addHooks (comp) {
11+
const hook = createRegisterFn(comp.name)
12+
return Object.assign(comp, {
13+
_ssrRegister: hook,
14+
beforeCreate: hook
15+
})
816
}
917

10-
const grandchild = {
18+
const grandchild = addHooks({
1119
name: 'grandchild',
1220
props: ['id'],
13-
_ssrRegister: context => {
14-
register('grandchild', context)
15-
},
16-
beforeCreate () {
17-
register('grandchild')
18-
},
1921
serverCacheKey: props => props.id,
2022
render (h) {
2123
return h('div', '/test')
2224
}
23-
}
25+
})
2426

25-
const child = {
27+
const child = addHooks({
2628
name: 'child',
2729
props: ['id'],
28-
_ssrRegister: context => {
29-
register('child', context)
30-
},
31-
beforeCreate () {
32-
register('child')
33-
},
3430
serverCacheKey: props => props.id,
3531
render (h) {
3632
return h(grandchild, { props: { id: this.id }})
3733
}
38-
}
34+
})
3935

40-
const app = {
36+
const app = addHooks({
4137
name: 'app',
4238
props: ['id'],
43-
_ssrRegister: context => {
44-
register('app', context)
45-
},
46-
beforeCreate () {
47-
register('app')
48-
},
4939
serverCacheKey: props => props.id,
5040
render (h) {
5141
return h(child, { props: { id: this.id }})
5242
}
53-
}
43+
})
5444

5545
export default () => {
5646
return Promise.resolve(new Vue({

0 commit comments

Comments
 (0)