Skip to content

Commit e76ed4c

Browse files
committed
refactor(hmr): simplify hmr force update check
1 parent 8f2a748 commit e76ed4c

File tree

6 files changed

+24
-43
lines changed

6 files changed

+24
-43
lines changed

packages/runtime-core/src/component.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,6 @@ export interface ComponentInternalOptions {
7171
* @internal
7272
*/
7373
__hmrId?: string
74-
/**
75-
* @internal
76-
*/
77-
__hmrUpdated?: boolean
7874
/**
7975
* This one should be exposed so that devtools can make use of it
8076
*/
@@ -325,12 +321,6 @@ export interface ComponentInternalInstance {
325321
* @internal
326322
*/
327323
[LifecycleHooks.ERROR_CAPTURED]: LifecycleHook
328-
329-
/**
330-
* hmr marker (dev only)
331-
* @internal
332-
*/
333-
hmrUpdated?: boolean
334324
}
335325

336326
const emptyAppContext = createAppContext()

packages/runtime-core/src/componentRenderUtils.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
import { handleError, ErrorCodes } from './errorHandling'
1717
import { PatchFlags, ShapeFlags, isOn } from '@vue/shared'
1818
import { warn } from './warning'
19+
import { isHmrUpdating } from './hmr'
1920

2021
// mark the current rendering instance for asset resolution (e.g.
2122
// resolveComponent, resolveDirective) during render
@@ -247,13 +248,8 @@ export function shouldUpdateComponent(
247248
// Parent component's render function was hot-updated. Since this may have
248249
// caused the child component's slots content to have changed, we need to
249250
// force the child to update as well.
250-
if (__DEV__ && (prevChildren || nextChildren) && parentComponent) {
251-
let parent: ComponentInternalInstance | null = parentComponent
252-
do {
253-
if (parent.hmrUpdated) {
254-
return true
255-
}
256-
} while ((parent = parent.parent))
251+
if (__DEV__ && (prevChildren || nextChildren) && isHmrUpdating) {
252+
return true
257253
}
258254

259255
// force child update for runtime directive or transition on component vnode.

packages/runtime-core/src/componentSlots.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
import { warn } from './warning'
1919
import { isKeepAlive } from './components/KeepAlive'
2020
import { withCtx } from './helpers/withRenderContext'
21-
import { queuePostFlushCb } from './scheduler'
21+
import { isHmrUpdating } from './hmr'
2222

2323
export type Slot = (...args: any[]) => VNode[]
2424

@@ -125,14 +125,10 @@ export const updateSlots = (
125125
if (vnode.shapeFlag & ShapeFlags.SLOTS_CHILDREN) {
126126
if ((children as RawSlots)._ === 1) {
127127
// compiled slots.
128-
if (__DEV__ && instance.parent && instance.parent.hmrUpdated) {
128+
if (__DEV__ && isHmrUpdating) {
129129
// Parent was HMR updated so slot content may have changed.
130130
// force update slots and mark instance for hmr as well
131131
extend(slots, children as Slots)
132-
instance.hmrUpdated = true
133-
queuePostFlushCb(() => {
134-
instance.hmrUpdated = false
135-
})
136132
} else if (
137133
// bail on dynamic slots (v-if, v-for, reference of scope variables)
138134
!(vnode.patchFlag & PatchFlags.DYNAMIC_SLOTS)

packages/runtime-core/src/hmr.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
/* eslint-disable no-restricted-globals */
22
import {
3+
Component,
34
ComponentInternalInstance,
45
ComponentOptions,
56
InternalRenderFunction
67
} from './component'
78
import { queueJob, queuePostFlushCb } from './scheduler'
89
import { extend } from '@vue/shared'
910

11+
export let isHmrUpdating = false
12+
13+
export const hmrDirtyComponents = new Set<Component>()
14+
1015
export interface HMRRuntime {
1116
createRecord: typeof createRecord
1217
rerender: typeof rerender
@@ -72,9 +77,9 @@ function rerender(id: string, newRender?: Function) {
7277
}
7378
instance.renderCache = []
7479
// this flag forces child components with slot content to update
75-
instance.hmrUpdated = true
80+
isHmrUpdating = true
7681
instance.update()
77-
instance.hmrUpdated = false
82+
isHmrUpdating = false
7883
})
7984
}
8085

@@ -85,7 +90,7 @@ function reload(id: string, newComp: ComponentOptions) {
8590
// updates
8691
Array.from(record).forEach(instance => {
8792
const comp = instance.type
88-
if (!comp.__hmrUpdated) {
93+
if (!hmrDirtyComponents.has(comp)) {
8994
// 1. Update existing comp definition to match new one
9095
extend(comp, newComp)
9196
for (const key in comp) {
@@ -95,10 +100,10 @@ function reload(id: string, newComp: ComponentOptions) {
95100
}
96101
// 2. Mark component dirty. This forces the renderer to replace the component
97102
// on patch.
98-
comp.__hmrUpdated = true
103+
hmrDirtyComponents.add(comp)
99104
// 3. Make sure to unmark the component after the reload.
100105
queuePostFlushCb(() => {
101-
comp.__hmrUpdated = false
106+
hmrDirtyComponents.delete(comp)
102107
})
103108
}
104109

packages/runtime-core/src/renderer.ts

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ import {
5656
} from './components/Suspense'
5757
import { TeleportImpl } from './components/Teleport'
5858
import { isKeepAlive, KeepAliveContext } from './components/KeepAlive'
59-
import { registerHMR, unregisterHMR } from './hmr'
59+
import { registerHMR, unregisterHMR, isHmrUpdating } from './hmr'
6060
import {
6161
ErrorCodes,
6262
callWithErrorHandling,
@@ -791,18 +791,11 @@ function baseCreateRenderer(
791791
invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate')
792792
}
793793

794-
// check if any component of the parent chain has `hmrUpdated`
795-
if (__DEV__ && parentComponent) {
796-
let parent: ComponentInternalInstance | null = parentComponent
797-
do {
798-
if (parent.hmrUpdated) {
799-
// HMR updated, force full diff
800-
patchFlag = 0
801-
optimized = false
802-
dynamicChildren = null
803-
break
804-
}
805-
} while ((parent = parent.parent))
794+
if (__DEV__ && isHmrUpdating) {
795+
// HMR updated, force full diff
796+
patchFlag = 0
797+
optimized = false
798+
dynamicChildren = null
806799
}
807800

808801
if (patchFlag > 0) {
@@ -1025,7 +1018,7 @@ function baseCreateRenderer(
10251018
optimized = true
10261019
}
10271020

1028-
if (__DEV__ && parentComponent && parentComponent.hmrUpdated) {
1021+
if (__DEV__ && isHmrUpdating) {
10291022
// HMR updated, force full diff
10301023
patchFlag = 0
10311024
optimized = false

packages/runtime-core/src/vnode.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { TeleportImpl, isTeleport } from './components/Teleport'
3232
import { currentRenderingInstance } from './componentRenderUtils'
3333
import { RendererNode, RendererElement } from './renderer'
3434
import { NULL_DYNAMIC_COMPONENT } from './helpers/resolveAssets'
35+
import { hmrDirtyComponents } from './hmr'
3536

3637
export const Fragment = (Symbol(__DEV__ ? 'Fragment' : undefined) as any) as {
3738
__isFragment: true
@@ -236,7 +237,7 @@ export function isSameVNodeType(n1: VNode, n2: VNode): boolean {
236237
if (
237238
__DEV__ &&
238239
n2.shapeFlag & ShapeFlags.COMPONENT &&
239-
(n2.type as Component).__hmrUpdated
240+
hmrDirtyComponents.has(n2.type as Component)
240241
) {
241242
// HMR only: if the component has been hot-updated, force a reload.
242243
return false

0 commit comments

Comments
 (0)