refactor(ssr): make hydration logic tree-shakeable
This commit is contained in:
@@ -91,7 +91,7 @@ export type CreateAppFunction<HostElement> = (
|
||||
|
||||
export function createAppAPI<HostNode, HostElement>(
|
||||
render: RootRenderFunction<HostNode, HostElement>,
|
||||
hydrate: (vnode: VNode, container: Element) => void
|
||||
hydrate?: (vnode: VNode, container: Element) => void
|
||||
): CreateAppFunction<HostElement> {
|
||||
return function createApp(rootComponent: Component, rootProps = null) {
|
||||
if (rootProps != null && !isObject(rootProps)) {
|
||||
@@ -200,7 +200,7 @@ export function createAppAPI<HostNode, HostElement>(
|
||||
}
|
||||
}
|
||||
|
||||
if (isHydrate) {
|
||||
if (isHydrate && hydrate) {
|
||||
hydrate(vnode, rootContainer as any)
|
||||
} else {
|
||||
render(vnode, rootContainer)
|
||||
|
||||
@@ -15,9 +15,11 @@ import { warn } from './warning'
|
||||
import { PatchFlags, isReservedProp, isOn } from '@vue/shared'
|
||||
|
||||
// Note: hydration is DOM-specific
|
||||
// but we have to place it in core due to tight coupling with core - splitting
|
||||
// But we have to place it in core due to tight coupling with core - splitting
|
||||
// it out creates a ton of unnecessary complexity.
|
||||
export function createHydrateFn(
|
||||
// Hydration also depends on some renderer internal logic which needs to be
|
||||
// passed in via arguments.
|
||||
export function createHydrationFunctions(
|
||||
mountComponent: any, // TODO
|
||||
patchProp: any // TODO
|
||||
) {
|
||||
|
||||
@@ -65,7 +65,7 @@ export { useCSSModule } from './helpers/useCssModule'
|
||||
// Internal API ----------------------------------------------------------------
|
||||
|
||||
// For custom renderers
|
||||
export { createRenderer } from './renderer'
|
||||
export { createRenderer, createHydrationRenderer } from './renderer'
|
||||
export { warn } from './warning'
|
||||
export {
|
||||
handleError,
|
||||
|
||||
@@ -62,7 +62,7 @@ import {
|
||||
import { ErrorCodes, callWithErrorHandling } from './errorHandling'
|
||||
import { KeepAliveSink, isKeepAlive } from './components/KeepAlive'
|
||||
import { registerHMR, unregisterHMR } from './hmr'
|
||||
import { createHydrateFn } from './hydration'
|
||||
import { createHydrationFunctions } from './hydration'
|
||||
|
||||
const __HMR__ = __BUNDLER__ && __DEV__
|
||||
|
||||
@@ -186,6 +186,32 @@ export function createRenderer<
|
||||
HostNode extends object = any,
|
||||
HostElement extends HostNode = any
|
||||
>(options: RendererOptions<HostNode, HostElement>) {
|
||||
const res = baseCreateRenderer(options)
|
||||
return res as typeof res & {
|
||||
hydrate: undefined
|
||||
}
|
||||
}
|
||||
|
||||
// Separate API for creating hydration-enabled renderer.
|
||||
// Hydration logic is only used when calling this function, making it
|
||||
// tree-shakable.
|
||||
export function createHydrationRenderer<
|
||||
HostNode extends object = any,
|
||||
HostElement extends HostNode = any
|
||||
>(options: RendererOptions<HostNode, HostElement>) {
|
||||
const res = baseCreateRenderer(options, createHydrationFunctions)
|
||||
return res as typeof res & {
|
||||
hydrate: ReturnType<typeof createHydrationFunctions>[0]
|
||||
}
|
||||
}
|
||||
|
||||
function baseCreateRenderer<
|
||||
HostNode extends object = any,
|
||||
HostElement extends HostNode = any
|
||||
>(
|
||||
options: RendererOptions<HostNode, HostElement>,
|
||||
createHydrationFns?: typeof createHydrationFunctions
|
||||
) {
|
||||
type HostVNode = VNode<HostNode, HostElement>
|
||||
type HostVNodeChildren = VNodeArrayChildren<HostNode, HostElement>
|
||||
type HostSuspenseBoundary = SuspenseBoundary<HostNode, HostElement>
|
||||
@@ -215,6 +241,12 @@ export function createRenderer<
|
||||
options
|
||||
}
|
||||
|
||||
let hydrate: ReturnType<typeof createHydrationFunctions>[0] | undefined
|
||||
let hydrateNode: ReturnType<typeof createHydrationFunctions>[1] | undefined
|
||||
if (createHydrationFns) {
|
||||
;[hydrate, hydrateNode] = createHydrationFns(mountComponent, hostPatchProp)
|
||||
}
|
||||
|
||||
function patch(
|
||||
n1: HostVNode | null, // null means this is a mount
|
||||
n2: HostVNode,
|
||||
@@ -1054,7 +1086,7 @@ export function createRenderer<
|
||||
if (instance.bm !== null) {
|
||||
invokeHooks(instance.bm)
|
||||
}
|
||||
if (initialVNode.el) {
|
||||
if (initialVNode.el && hydrateNode) {
|
||||
// vnode has adopted host node - perform hydration instead of mount.
|
||||
hydrateNode(initialVNode.el as Node, subTree, instance)
|
||||
} else {
|
||||
@@ -1823,8 +1855,6 @@ export function createRenderer<
|
||||
container._vnode = vnode
|
||||
}
|
||||
|
||||
const [hydrate, hydrateNode] = createHydrateFn(mountComponent, hostPatchProp)
|
||||
|
||||
return {
|
||||
render,
|
||||
hydrate,
|
||||
|
||||
Reference in New Issue
Block a user