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

fix #4174
This commit is contained in:
Evan You 2021-07-22 10:53:59 -04:00
parent fe58bae412
commit db3f57a392
2 changed files with 44 additions and 1 deletions

View File

@ -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)
})
}) })

View File

@ -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