fix(runtime-core/hmr): only use cloneNode mount optimization in prod

fix #1626
This commit is contained in:
Evan You 2020-07-19 13:22:58 -04:00
parent b3af5dbe5d
commit 4655d69983

View File

@ -10,8 +10,7 @@ import {
isSameVNodeType,
Static,
VNodeNormalizedRef,
VNodeHook,
isVNode
VNodeHook
} from './vnode'
import {
ComponentInternalInstance,
@ -639,31 +638,7 @@ function baseCreateRenderer(
optimized
)
} else {
if (
__DEV__ &&
isHmrUpdating &&
hostCloneNode !== undefined &&
n2.patchFlag === PatchFlags.HOISTED
) {
// https://github.com/vitejs/vite/issues/514
// reused hoisted trees are inserted with cloneNode
// which makes them not patch-able. In production hoisted trees are
// never patched (because they are not collected as dynamic nodes), but
// they can be udpated during HMR. In this case just mount it as new
// and remove the stale DOM tree.
mountElement(
n2,
container,
n1.el,
parentComponent,
parentSuspense,
isSVG,
optimized
)
hostRemove(n1.el!)
} else {
patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized)
}
patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized)
}
}
@ -688,6 +663,7 @@ function baseCreateRenderer(
dirs
} = vnode
if (
!__DEV__ &&
vnode.el &&
hostCloneNode !== undefined &&
patchFlag === PatchFlags.HOISTED
@ -695,6 +671,7 @@ function baseCreateRenderer(
// If a vnode has non-null el, it means it's being reused.
// Only static vnodes can be reused, so its mounted DOM nodes should be
// exactly the same, and we can simply do a clone here.
// only do this in production since cloned trees cannot be HMR updated.
el = vnode.el = hostCloneNode(vnode.el)
} else {
el = vnode.el = hostCreateElement(
@ -2107,14 +2084,11 @@ function baseCreateRenderer(
const ch2 = n2.children
if (isArray(ch1) && isArray(ch2)) {
for (let i = 0; i < ch1.length; i++) {
const c1 = ch1[i]
const c2 = ch2[i]
if (
isVNode(c1) &&
isVNode(c2) &&
c2.shapeFlag & ShapeFlags.ELEMENT &&
!c2.dynamicChildren
) {
// this is only called in the optimized path so array children are
// guaranteed to be vnodes
const c1 = ch1[i] as VNode
const c2 = (ch2[i] = cloneIfMounted(ch2[i] as VNode))
if (c2.shapeFlag & ShapeFlags.ELEMENT && !c2.dynamicChildren) {
if (c2.patchFlag <= 0) {
c2.el = c1.el
}