소스 검색

fix(hmr): support hmr for static nodes

Evan You 6 년 전
부모
커밋
386b093554
2개의 변경된 파일19개의 추가작업 그리고 2개의 파일을 삭제
  1. 10 2
      packages/runtime-core/src/renderer.ts
  2. 9 0
      packages/runtime-dom/src/nodeOps.ts

+ 10 - 2
packages/runtime-core/src/renderer.ts

@@ -115,6 +115,7 @@ export interface RendererOptions<
     anchor: HostNode | null,
     isSVG: boolean
   ): HostElement
+  setStaticContent?(node: HostElement, content: string): void
 }
 
 // Renderer Node can technically be any object in the context of core renderer
@@ -330,7 +331,8 @@ function baseCreateRenderer(
     nextSibling: hostNextSibling,
     setScopeId: hostSetScopeId = NOOP,
     cloneNode: hostCloneNode,
-    insertStaticContent: hostInsertStaticContent
+    insertStaticContent: hostInsertStaticContent,
+    setStaticContent: hostSetStaticContent
   } = options
 
   // Note: functions inside this closure should use `const xxx = () => {}`
@@ -363,7 +365,13 @@ function baseCreateRenderer(
       case Static:
         if (n1 == null) {
           mountStaticNode(n2, container, anchor, isSVG)
-        } // static nodes are noop on patch
+        } else if (__DEV__) {
+          // static nodes are only patched during dev for HMR
+          n2.el = n1.el
+          if (n2.children !== n1.children) {
+            hostSetStaticContent!(n2.el!, n2.children as string)
+          }
+        }
         break
       case Fragment:
         processFragment(

+ 9 - 0
packages/runtime-dom/src/nodeOps.ts

@@ -69,3 +69,12 @@ export const nodeOps: Omit<RendererOptions<Node, Element>, 'patchProp'> = {
     return node
   }
 }
+
+if (__DEV__) {
+  // __UNSAFE__
+  // Reason: innerHTML.
+  // same as `insertStaticContent`, but this is also dev only (for HMR).
+  nodeOps.setStaticContent = (el, content) => {
+    el.innerHTML = content
+  }
+}