refactor(ssr): adjust ssr fragment anchor content

This commit is contained in:
Evan You 2020-03-13 11:55:04 -04:00
parent cad5bcce40
commit a05d41c940
12 changed files with 57 additions and 56 deletions

View File

@ -98,7 +98,7 @@ describe('SSR hydration', () => {
const msg = ref('foo') const msg = ref('foo')
const fn = jest.fn() const fn = jest.fn()
const { vnode, container } = mountWithHydration( const { vnode, container } = mountWithHydration(
'<div><!----><span>foo</span><!----><span class="foo"></span><!----><!----></div>', '<div><!--[--><span>foo</span><!--[--><span class="foo"></span><!--]--><!--]--></div>',
() => () =>
h('div', [ h('div', [
[h('span', msg.value), [h('span', { class: msg.value, onClick: fn })]] [h('span', msg.value), [h('span', { class: msg.value, onClick: fn })]]
@ -106,6 +106,9 @@ describe('SSR hydration', () => {
) )
expect(vnode.el).toBe(container.firstChild) expect(vnode.el).toBe(container.firstChild)
// should remove anchors in dev mode
expect(vnode.el.innerHTML).toBe(`<span>foo</span><span class="foo"></span>`)
// start fragment 1 // start fragment 1
const fragment1 = (vnode.children as VNode[])[0] const fragment1 = (vnode.children as VNode[])[0]
expect(fragment1.el).toBe(vnode.el.childNodes[0]) expect(fragment1.el).toBe(vnode.el.childNodes[0])
@ -136,9 +139,7 @@ describe('SSR hydration', () => {
msg.value = 'bar' msg.value = 'bar'
await nextTick() await nextTick()
expect(vnode.el.innerHTML).toBe( expect(vnode.el.innerHTML).toBe(`<span>bar</span><span class="bar"></span>`)
`<!----><span>bar</span><!----><span class="bar"></span><!----><!---->`
)
}) })
test('portal', async () => { test('portal', async () => {

View File

@ -219,11 +219,11 @@ describe('ssr: components', () => {
foo: ({ list }, _push, _parent, _scopeId) => { foo: ({ list }, _push, _parent, _scopeId) => {
if (_push) { if (_push) {
if (_ctx.ok) { if (_ctx.ok) {
_push(\`<div\${_scopeId}><!--1-->\`) _push(\`<div\${_scopeId}><!--[-->\`)
_ssrRenderList(list, (i) => { _ssrRenderList(list, (i) => {
_push(\`<span\${_scopeId}></span>\`) _push(\`<span\${_scopeId}></span>\`)
}) })
_push(\`<!--0--></div>\`) _push(\`<!--]--></div>\`)
} else { } else {
_push(\`<!---->\`) _push(\`<!---->\`)
} }
@ -242,11 +242,11 @@ describe('ssr: components', () => {
bar: ({ ok }, _push, _parent, _scopeId) => { bar: ({ ok }, _push, _parent, _scopeId) => {
if (_push) { if (_push) {
if (ok) { if (ok) {
_push(\`<div\${_scopeId}><!--1-->\`) _push(\`<div\${_scopeId}><!--[-->\`)
_ssrRenderList(_ctx.list, (i) => { _ssrRenderList(_ctx.list, (i) => {
_push(\`<span\${_scopeId}></span>\`) _push(\`<span\${_scopeId}></span>\`)
}) })
_push(\`<!--0--></div>\`) _push(\`<!--]--></div>\`)
} else { } else {
_push(\`<!---->\`) _push(\`<!---->\`)
} }
@ -281,7 +281,7 @@ describe('ssr: components', () => {
.toMatchInlineSnapshot(` .toMatchInlineSnapshot(`
" "
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
_push(\`<!--1--><div></div><!--0-->\`) _push(\`<!--[--><div></div><!--]-->\`)
}" }"
`) `)

View File

@ -6,11 +6,11 @@ describe('ssr: v-for', () => {
"const { ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\") "const { ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\")
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
_push(\`<!--1-->\`) _push(\`<!--[-->\`)
_ssrRenderList(_ctx.list, (i) => { _ssrRenderList(_ctx.list, (i) => {
_push(\`<div></div>\`) _push(\`<div></div>\`)
}) })
_push(\`<!--0-->\`) _push(\`<!--]-->\`)
}" }"
`) `)
}) })
@ -21,11 +21,11 @@ describe('ssr: v-for', () => {
"const { ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\") "const { ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\")
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
_push(\`<!--1-->\`) _push(\`<!--[-->\`)
_ssrRenderList(_ctx.list, (i) => { _ssrRenderList(_ctx.list, (i) => {
_push(\`<div>foo<span>bar</span></div>\`) _push(\`<div>foo<span>bar</span></div>\`)
}) })
_push(\`<!--0-->\`) _push(\`<!--]-->\`)
}" }"
`) `)
}) })
@ -41,9 +41,9 @@ describe('ssr: v-for', () => {
"const { ssrInterpolate: _ssrInterpolate, ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\") "const { ssrInterpolate: _ssrInterpolate, ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\")
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
_push(\`<!--1-->\`) _push(\`<!--[-->\`)
_ssrRenderList(_ctx.list, (row, i) => { _ssrRenderList(_ctx.list, (row, i) => {
_push(\`<div><!--1-->\`) _push(\`<div><!--[-->\`)
_ssrRenderList(row, (j) => { _ssrRenderList(row, (j) => {
_push(\`<div>\${ _push(\`<div>\${
_ssrInterpolate(i) _ssrInterpolate(i)
@ -51,9 +51,9 @@ describe('ssr: v-for', () => {
_ssrInterpolate(j) _ssrInterpolate(j)
}</div>\`) }</div>\`)
}) })
_push(\`<!--0--></div>\`) _push(\`<!--]--></div>\`)
}) })
_push(\`<!--0-->\`) _push(\`<!--]-->\`)
}" }"
`) `)
}) })
@ -64,11 +64,11 @@ describe('ssr: v-for', () => {
"const { ssrInterpolate: _ssrInterpolate, ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\") "const { ssrInterpolate: _ssrInterpolate, ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\")
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
_push(\`<!--1-->\`) _push(\`<!--[-->\`)
_ssrRenderList(_ctx.list, (i) => { _ssrRenderList(_ctx.list, (i) => {
_push(\`<!--1-->\${_ssrInterpolate(i)}<!--0-->\`) _push(\`<!--[-->\${_ssrInterpolate(i)}<!--]-->\`)
}) })
_push(\`<!--0-->\`) _push(\`<!--]-->\`)
}" }"
`) `)
}) })
@ -81,11 +81,11 @@ describe('ssr: v-for', () => {
"const { ssrInterpolate: _ssrInterpolate, ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\") "const { ssrInterpolate: _ssrInterpolate, ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\")
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
_push(\`<!--1-->\`) _push(\`<!--[-->\`)
_ssrRenderList(_ctx.list, (i) => { _ssrRenderList(_ctx.list, (i) => {
_push(\`<span>\${_ssrInterpolate(i)}</span>\`) _push(\`<span>\${_ssrInterpolate(i)}</span>\`)
}) })
_push(\`<!--0-->\`) _push(\`<!--]-->\`)
}" }"
`) `)
}) })
@ -99,15 +99,15 @@ describe('ssr: v-for', () => {
"const { ssrInterpolate: _ssrInterpolate, ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\") "const { ssrInterpolate: _ssrInterpolate, ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\")
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
_push(\`<!--1-->\`) _push(\`<!--[-->\`)
_ssrRenderList(_ctx.list, (i) => { _ssrRenderList(_ctx.list, (i) => {
_push(\`<!--1--><span>\${ _push(\`<!--[--><span>\${
_ssrInterpolate(i) _ssrInterpolate(i)
}</span><span>\${ }</span><span>\${
_ssrInterpolate(i + 1) _ssrInterpolate(i + 1)
}</span><!--0-->\`) }</span><!--]-->\`)
}) })
_push(\`<!--0-->\`) _push(\`<!--]-->\`)
}" }"
`) `)
}) })
@ -123,11 +123,11 @@ describe('ssr: v-for', () => {
"const { ssrInterpolate: _ssrInterpolate, ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\") "const { ssrInterpolate: _ssrInterpolate, ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\")
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
_push(\`<!--1-->\`) _push(\`<!--[-->\`)
_ssrRenderList(_ctx.list, ({ foo }, index) => { _ssrRenderList(_ctx.list, ({ foo }, index) => {
_push(\`<div>\${_ssrInterpolate(foo + _ctx.bar + index)}</div>\`) _push(\`<div>\${_ssrInterpolate(foo + _ctx.bar + index)}</div>\`)
}) })
_push(\`<!--0-->\`) _push(\`<!--]-->\`)
}" }"
`) `)
}) })

View File

@ -80,7 +80,7 @@ describe('ssr: v-if', () => {
" "
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
if (_ctx.foo) { if (_ctx.foo) {
_push(\`<!--1-->hello<!--0-->\`) _push(\`<!--[-->hello<!--]-->\`)
} else { } else {
_push(\`<!---->\`) _push(\`<!---->\`)
} }
@ -110,7 +110,7 @@ describe('ssr: v-if', () => {
" "
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
if (_ctx.foo) { if (_ctx.foo) {
_push(\`<!--1--><div>hi</div><div>ho</div><!--0-->\`) _push(\`<!--[--><div>hi</div><div>ho</div><!--]-->\`)
} else { } else {
_push(\`<!---->\`) _push(\`<!---->\`)
} }
@ -126,11 +126,11 @@ describe('ssr: v-if', () => {
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
if (_ctx.foo) { if (_ctx.foo) {
_push(\`<!--1-->\`) _push(\`<!--[-->\`)
_ssrRenderList(_ctx.list, (i) => { _ssrRenderList(_ctx.list, (i) => {
_push(\`<div></div>\`) _push(\`<div></div>\`)
}) })
_push(\`<!--0-->\`) _push(\`<!--]-->\`)
} else { } else {
_push(\`<!---->\`) _push(\`<!---->\`)
} }
@ -147,7 +147,7 @@ describe('ssr: v-if', () => {
" "
return function ssrRender(_ctx, _push, _parent) { return function ssrRender(_ctx, _push, _parent) {
if (_ctx.foo) { if (_ctx.foo) {
_push(\`<!--1--><div>hi</div><div>ho</div><!--0-->\`) _push(\`<!--[--><div>hi</div><div>ho</div><!--]-->\`)
} else { } else {
_push(\`<div></div>\`) _push(\`<div></div>\`)
} }

View File

@ -111,7 +111,7 @@ export function processChildren(
asFragment = false asFragment = false
) { ) {
if (asFragment) { if (asFragment) {
context.pushStringPart(`<!--1-->`) context.pushStringPart(`<!--[-->`)
} }
for (let i = 0; i < children.length; i++) { for (let i = 0; i < children.length; i++) {
const child = children[i] const child = children[i]
@ -136,7 +136,7 @@ export function processChildren(
} }
} }
if (asFragment) { if (asFragment) {
context.pushStringPart(`<!--0-->`) context.pushStringPart(`<!--]-->`)
} }
} }

View File

@ -33,12 +33,12 @@ export function ssrProcessFor(node: ForNode, context: SSRTransformContext) {
needFragmentWrapper needFragmentWrapper
) )
// v-for always renders a fragment // v-for always renders a fragment
context.pushStringPart(`<!--1-->`) context.pushStringPart(`<!--[-->`)
context.pushStatement( context.pushStatement(
createCallExpression(context.helper(SSR_RENDER_LIST), [ createCallExpression(context.helper(SSR_RENDER_LIST), [
node.source, node.source,
renderLoop renderLoop
]) ])
) )
context.pushStringPart(`<!--0-->`) context.pushStringPart(`<!--]-->`)
} }

View File

@ -76,7 +76,7 @@ export function createHydrationFunctions(
parentSuspense: SuspenseBoundary | null, parentSuspense: SuspenseBoundary | null,
optimized = false optimized = false
): Node | null => { ): Node | null => {
const isFragmentStart = isComment(node) && node.data === '1' const isFragmentStart = isComment(node) && node.data === '['
if (__DEV__ && isFragmentStart) { if (__DEV__ && isFragmentStart) {
// in dev mode, replace comment anchors with invisible text nodes // in dev mode, replace comment anchors with invisible text nodes
// for easier debugging // for easier debugging
@ -403,8 +403,8 @@ export function createHydrationFunctions(
while (node) { while (node) {
node = nextSibling(node) node = nextSibling(node)
if (node && isComment(node)) { if (node && isComment(node)) {
if (node.data === '1') match++ if (node.data === '[') match++
if (node.data === '0') { if (node.data === ']') {
if (match === 0) { if (match === 0) {
return nextSibling(node) return nextSibling(node)
} else { } else {

View File

@ -257,7 +257,7 @@ describe('ssr: renderToString', () => {
) )
).toBe( ).toBe(
`<div>parent<div class="child">` + `<div>parent<div class="child">` +
`<!--1--><span>from slot</span><!--0-->` + `<!--[--><span>from slot</span><!--]-->` +
`</div></div>` `</div></div>`
) )
@ -273,7 +273,7 @@ describe('ssr: renderToString', () => {
}) })
) )
).toBe( ).toBe(
`<div>parent<div class="child"><!--1-->fallback<!--0--></div></div>` `<div>parent<div class="child"><!--[-->fallback<!--]--></div></div>`
) )
}) })
@ -318,7 +318,7 @@ describe('ssr: renderToString', () => {
) )
).toBe( ).toBe(
`<div>parent<div class="child">` + `<div>parent<div class="child">` +
`<!--1--><span>from slot</span><!--0-->` + `<!--[--><span>from slot</span><!--]-->` +
`</div></div>` `</div></div>`
) )
}) })
@ -336,7 +336,7 @@ describe('ssr: renderToString', () => {
expect(await renderToString(app)).toBe( expect(await renderToString(app)).toBe(
`<div>parent<div class="child">` + `<div>parent<div class="child">` +
`<!--1--><span>from slot</span><!--0-->` + `<!--[--><span>from slot</span><!--]-->` +
`</div></div>` `</div></div>`
) )
}) })
@ -460,7 +460,7 @@ describe('ssr: renderToString', () => {
]) ])
) )
).toBe( ).toBe(
`<div>foo<span>bar</span><!--1--><span>baz</span><!--0--><!--qux--></div>` `<div>foo<span>bar</span><!--[--><span>baz</span><!--]--><!--qux--></div>`
) )
}) })

View File

@ -33,7 +33,7 @@ describe('SSR Suspense', () => {
} }
}) })
expect(await renderToString(app)).toBe(`<!--1--><div>async</div><!--0-->`) expect(await renderToString(app)).toBe(`<!--[--><div>async</div><!--]-->`)
}) })
test('with async component', async () => { test('with async component', async () => {
@ -49,7 +49,7 @@ describe('SSR Suspense', () => {
} }
}) })
expect(await renderToString(app)).toBe(`<!--1--><div>async</div><!--0-->`) expect(await renderToString(app)).toBe(`<!--[--><div>async</div><!--]-->`)
}) })
test('fallback', async () => { test('fallback', async () => {
@ -69,7 +69,7 @@ describe('SSR Suspense', () => {
}) })
expect(await renderToString(app)).toBe( expect(await renderToString(app)).toBe(
`<!--1--><div>fallback</div><!--0-->` `<!--[--><div>fallback</div><!--]-->`
) )
expect('Uncaught error in async setup').toHaveBeenWarned() expect('Uncaught error in async setup').toHaveBeenWarned()
}) })

View File

@ -19,7 +19,7 @@ export function ssrRenderSlot(
parentComponent: ComponentInternalInstance parentComponent: ComponentInternalInstance
) { ) {
// template-compiled slots are always rendered as fragments // template-compiled slots are always rendered as fragments
push(`<!--1-->`) push(`<!--[-->`)
const slotFn = slots[slotName] const slotFn = slots[slotName]
if (slotFn) { if (slotFn) {
if (slotFn.length > 1) { if (slotFn.length > 1) {
@ -33,5 +33,5 @@ export function ssrRenderSlot(
} else if (fallbackRenderFn) { } else if (fallbackRenderFn) {
fallbackRenderFn() fallbackRenderFn()
} }
push(`<!--0-->`) push(`<!--]-->`)
} }

View File

@ -9,9 +9,9 @@ export async function ssrRenderSuspense({
try { try {
if (renderContent) { if (renderContent) {
const { push, getBuffer } = createBuffer() const { push, getBuffer } = createBuffer()
push(`<!--1-->`) push(`<!--[-->`)
renderContent(push) renderContent(push)
push(`<!--0-->`) push(`<!--]-->`)
return await getBuffer() return await getBuffer()
} else { } else {
return [] return []
@ -19,9 +19,9 @@ export async function ssrRenderSuspense({
} catch { } catch {
if (renderFallback) { if (renderFallback) {
const { push, getBuffer } = createBuffer() const { push, getBuffer } = createBuffer()
push(`<!--1-->`) push(`<!--[-->`)
renderFallback(push) renderFallback(push)
push(`<!--0-->`) push(`<!--]-->`)
return getBuffer() return getBuffer()
} else { } else {
return [] return []

View File

@ -256,9 +256,9 @@ function renderVNode(
push(children ? `<!--${children}-->` : `<!---->`) push(children ? `<!--${children}-->` : `<!---->`)
break break
case Fragment: case Fragment:
push(`<!--1-->`) // open push(`<!--[-->`) // open
renderVNodeChildren(push, children as VNodeArrayChildren, parentComponent) renderVNodeChildren(push, children as VNodeArrayChildren, parentComponent)
push(`<!--0-->`) // close push(`<!--]-->`) // close
break break
default: default:
if (shapeFlag & ShapeFlags.ELEMENT) { if (shapeFlag & ShapeFlags.ELEMENT) {