Skip to content

SSR: possible scopeId interference between two components in rendering #4002

@HerringtonDarkholme

Description

@HerringtonDarkholme

Vue.js version

2.0.2

Steps to reproduce

import Vue from 'vue/dist/vue.common.js'
import { createRenderer } from 'vue-server-renderer'
const { renderToStream } = createRenderer()

const padding = (new Array(20000)).join('x')
const component1 = new Vue({
  template: `<div>${padding}<div></div></div>`,
  _scopeId: '_component1'
})
const component2 = new Vue({
  template: `<div></div>`,
  _scopeId: '_component2'
})
var a = renderToStream(component1)
var b = renderToStream(component2)
var res = ''
a.on('data', (text) => {
  res += text.toString('utf-8').replace(/x/g, '')
})
a.on('end', () => {
  console.log(res)
})
a.read(1)
b.read(1)

What is Expected?

ScopeId should be independent

Thus should log

<div server-rendered="true" _component1><div _component1></div></div>

What is actually happening?

Component2's scopeId goes into Component1

<div server-rendered="true" _component1><div _component2 _component1></div></div>

I found this when reading server rendering code. The problem is activeInstance in src/server/render.js is shared across all render functions returned by createRenderFunction.

I don't know how nodejs schedules stream flowing, but this might be a pernicious bug if two streams' _read calls were interleaved....

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions