From 4655d699831b3356bb8be5b41c45da830dac9eb2 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 19 Jul 2020 13:22:58 -0400 Subject: [PATCH] fix(runtime-core/hmr): only use cloneNode mount optimization in prod fix #1626 --- packages/runtime-core/src/renderer.ts | 44 ++++++--------------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts index 7f74d434..42e7f050 100644 --- a/packages/runtime-core/src/renderer.ts +++ b/packages/runtime-core/src/renderer.ts @@ -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 }