Преглед изворни кода

fix(hmr): fix hmr when global mixins are used

fix #4174
Evan You пре 4 година
родитељ
комит
db3f57a392
2 измењених фајлова са 44 додато и 1 уклоњено
  1. 41 1
      packages/runtime-core/__tests__/hmr.spec.ts
  2. 3 0
      packages/runtime-core/src/hmr.ts

+ 41 - 1
packages/runtime-core/__tests__/hmr.spec.ts

@@ -11,12 +11,13 @@ import {
   nextTick
   nextTick
 } from '@vue/runtime-test'
 } from '@vue/runtime-test'
 import * as runtimeTest from '@vue/runtime-test'
 import * as runtimeTest from '@vue/runtime-test'
+import { registerRuntimeCompiler, createApp } from '@vue/runtime-test'
 import { baseCompile } from '@vue/compiler-core'
 import { baseCompile } from '@vue/compiler-core'
 
 
 declare var __VUE_HMR_RUNTIME__: HMRRuntime
 declare var __VUE_HMR_RUNTIME__: HMRRuntime
 const { createRecord, rerender, reload } = __VUE_HMR_RUNTIME__
 const { createRecord, rerender, reload } = __VUE_HMR_RUNTIME__
 
 
-runtimeTest.registerRuntimeCompiler(compileToFunction)
+registerRuntimeCompiler(compileToFunction)
 
 
 function compileToFunction(template: string) {
 function compileToFunction(template: string) {
   const { code } = baseCompile(template)
   const { code } = baseCompile(template)
@@ -395,4 +396,43 @@ describe('hot module replacement', () => {
       `<div style={}><div>1</div><div>2</div></div>`
       `<div style={}><div>1</div><div>2</div></div>`
     )
     )
   })
   })
+
+  // #4174
+  test('with global mixins', async () => {
+    const childId = 'hmr-global-mixin'
+    const createSpy1 = jest.fn()
+    const createSpy2 = jest.fn()
+
+    const Child: ComponentOptions = {
+      __hmrId: childId,
+      created: createSpy1,
+      render() {
+        return h('div')
+      }
+    }
+    createRecord(childId, Child)
+
+    const Parent: ComponentOptions = {
+      render: () => h(Child)
+    }
+
+    const app = createApp(Parent)
+    app.mixin({})
+
+    const root = nodeOps.createElement('div')
+    app.mount(root)
+    expect(createSpy1).toHaveBeenCalledTimes(1)
+    expect(createSpy2).toHaveBeenCalledTimes(0)
+
+    reload(childId, {
+      __hmrId: childId,
+      created: createSpy2,
+      render() {
+        return h('div')
+      }
+    })
+    await nextTick()
+    expect(createSpy1).toHaveBeenCalledTimes(1)
+    expect(createSpy2).toHaveBeenCalledTimes(1)
+  })
 })
 })

+ 3 - 0
packages/runtime-core/src/hmr.ts

@@ -130,6 +130,9 @@ function reload(id: string, newComp: ComponentOptions | ClassComponent) {
   }
   }
 
 
   Array.from(instances).forEach(instance => {
   Array.from(instances).forEach(instance => {
+    // invalidate options resolution cache
+    instance.appContext.optionsCache.delete(instance.type as any)
+
     if (instance.parent) {
     if (instance.parent) {
       // 4. Force the parent instance to re-render. This will cause all updated
       // 4. Force the parent instance to re-render. This will cause all updated
       // components to be unmounted and re-mounted. Queue the update so that we
       // components to be unmounted and re-mounted. Queue the update so that we