test('on component', () => {
expect(compile(`<Comp v-skip="foo"/>`).code).toMatchInlineSnapshot(`
"const { withCtx: _withCtx, createCommentVNode: _createCommentVNode, resolveComponent: _resolveComponent } = require("vue")
- const { ssrRenderComponent: _ssrRenderComponent, ssrRenderSkipComponent: _ssrRenderSkipComponent } = require("vue/server-renderer")
+ const { ssrRenderComponent: _ssrRenderComponent } = require("vue/server-renderer")
return function ssrRender(_ctx, _push, _parent, _attrs) {
const _component_Comp = _resolveComponent("Comp")
if (_ctx.foo) {
_createCommentVNode("v-skip", true)
} else {
- _push(_ssrRenderSkipComponent(_push, _ctx.foo, _component_Comp, _attrs, null, _parent))
+ _push(_ssrRenderComponent(_component_Comp, _attrs, null, _parent))
}
}"
`)
`).code,
).toMatchInlineSnapshot(`
"const { withCtx: _withCtx, resolveComponent: _resolveComponent, createVNode: _createVNode } = require("vue")
- const { ssrRenderComponent: _ssrRenderComponent, ssrRenderSkipComponent: _ssrRenderSkipComponent } = require("vue/server-renderer")
+ const { ssrRenderComponent: _ssrRenderComponent } = require("vue/server-renderer")
return function ssrRender(_ctx, _push, _parent, _attrs) {
const _component_Comp = _resolveComponent("Comp")
if (_ctx.ok) {
_push(\`<span></span>\`)
} else {
- _push(_ssrRenderSkipComponent(_push, _ctx.ok, _component_Comp, null, {
+ _push(_ssrRenderComponent(_component_Comp, null, {
default: _withCtx((_, _push, _parent, _scopeId) => {
if (_push) {
_push(\`<span\${_scopeId}></span>\`)
export const SSR_INTERPOLATE: unique symbol = Symbol(`ssrInterpolate`)
export const SSR_RENDER_VNODE: unique symbol = Symbol(`ssrRenderVNode`)
+export const SSR_RENDER_SKIP_VNODE: unique symbol = Symbol(`ssrRenderSkipVNode`)
export const SSR_RENDER_COMPONENT: unique symbol = Symbol(`ssrRenderComponent`)
export const SSR_RENDER_SKIP_COMPONENT: unique symbol = Symbol(
`ssrRenderSkipComponent`,
export const ssrHelpers: Record<symbol, string> = {
[SSR_INTERPOLATE]: `ssrInterpolate`,
[SSR_RENDER_VNODE]: `ssrRenderVNode`,
+ [SSR_RENDER_SKIP_VNODE]: `ssrRenderSkipVNode`,
[SSR_RENDER_COMPONENT]: `ssrRenderComponent`,
[SSR_RENDER_SKIP_COMPONENT]: `ssrRenderSkipComponent`,
[SSR_RENDER_SLOT]: `ssrRenderSlot`,
import {
- ElementTypes,
+ type ComponentNode,
type NodeTransform,
NodeTypes,
type SkipNode,
import {
SSR_RENDER_COMPONENT,
SSR_RENDER_SKIP_COMPONENT,
+ SSR_RENDER_SKIP_VNODE,
SSR_RENDER_VNODE,
} from '../runtimeHelpers'
export const ssrTransformSkip: NodeTransform =
createStructuralDirectiveTransform('skip', (node, dir, context) => {
- processSkip(node, dir, context)
- return () => {
- if (node.tagType === ElementTypes.COMPONENT && node.ssrCodegenNode) {
- const { callee, arguments: args, loc } = node.ssrCodegenNode
- if (callee === SSR_RENDER_COMPONENT) {
- node.ssrCodegenNode = createCallExpression(
- context.helper(SSR_RENDER_SKIP_COMPONENT),
- [`_push`, dir.exp!, ...args],
+ return processSkip(node, dir, context, (skipNode?: SkipNode) => {
+ return () => {
+ // for non-skipNode, rewrite the ssrCodegenNode
+ // `ssrRenderComponent` -> `ssrRenderSkipComponent`
+ // `ssrRenderVNode` -> `ssrRenderSkipVNode`
+ if (!skipNode && node && (node as ComponentNode).ssrCodegenNode) {
+ const {
+ callee,
+ arguments: args,
loc,
- )
- } else if (callee === SSR_RENDER_VNODE) {
- // TODO
+ } = (node as ComponentNode).ssrCodegenNode!
+ if (callee === SSR_RENDER_COMPONENT) {
+ ;(node as ComponentNode).ssrCodegenNode = createCallExpression(
+ context.helper(SSR_RENDER_SKIP_COMPONENT),
+ [`_push`, dir.exp!, ...args],
+ loc,
+ )
+ } else if (callee === SSR_RENDER_VNODE) {
+ ;(node as ComponentNode).ssrCodegenNode = createCallExpression(
+ context.helper(SSR_RENDER_SKIP_VNODE),
+ [dir.exp!, ...args],
+ loc,
+ )
+ }
}
}
- }
+ })
})
export function ssrProcessSkip(
type Component,
type ComponentInternalInstance,
type Slots,
+ type VNode,
createVNode,
} from 'vue'
import {
renderComponentVNode,
} from '../render'
import { type SSRSlots, ssrRenderSlot } from './ssrRenderSlot'
+import { ssrRenderVNode } from '@vue/server-renderer'
export function ssrRenderSkipComponent(
push: PushFn,
slotScopeId,
)
}
+
+export function ssrRenderSkipVNode(
+ isSkip: boolean,
+ push: PushFn,
+ vnode: VNode,
+ parentComponent: ComponentInternalInstance,
+ slotScopeId?: string,
+): void {
+ if (isSkip) {
+ ssrRenderSlot(
+ vnode.children as Slots,
+ 'default',
+ {},
+ null,
+ push,
+ parentComponent,
+ slotScopeId,
+ )
+ } else {
+ ssrRenderVNode(push, vnode, parentComponent, slotScopeId)
+ }
+}
// internal runtime helpers
export { renderVNode as ssrRenderVNode } from './render'
export { ssrRenderComponent } from './helpers/ssrRenderComponent'
-export { ssrRenderSkipComponent } from './helpers/ssrRenderSkipComponent'
+export {
+ ssrRenderSkipComponent,
+ ssrRenderSkipVNode,
+} from './helpers/ssrRenderSkipComponent'
export { ssrRenderSlot, ssrRenderSlotInner } from './helpers/ssrRenderSlot'
export { ssrRenderTeleport } from './helpers/ssrRenderTeleport'
export {