|
@@ -1,22 +1,17 @@
|
|
|
import {
|
|
import {
|
|
|
- isKeepAlive,
|
|
|
|
|
popWarningContext,
|
|
popWarningContext,
|
|
|
pushWarningContext,
|
|
pushWarningContext,
|
|
|
setCurrentInstance,
|
|
setCurrentInstance,
|
|
|
} from '@vue/runtime-dom'
|
|
} from '@vue/runtime-dom'
|
|
|
-import { type Block, findBlockBoundary, insert, remove } from './block'
|
|
|
|
|
|
|
+import { findBlockBoundary, insert, remove } from './block'
|
|
|
import {
|
|
import {
|
|
|
type VaporComponent,
|
|
type VaporComponent,
|
|
|
type VaporComponentInstance,
|
|
type VaporComponentInstance,
|
|
|
createComponent,
|
|
createComponent,
|
|
|
devRender,
|
|
devRender,
|
|
|
- isVaporComponent,
|
|
|
|
|
mountComponent,
|
|
mountComponent,
|
|
|
unmountComponent,
|
|
unmountComponent,
|
|
|
} from './component'
|
|
} from './component'
|
|
|
-import { isArray } from '@vue/shared'
|
|
|
|
|
-import { isFragment } from './fragment'
|
|
|
|
|
-import { isKeepAliveEnabled } from './keepAlive'
|
|
|
|
|
|
|
|
|
|
export function hmrRerender(instance: VaporComponentInstance): void {
|
|
export function hmrRerender(instance: VaporComponentInstance): void {
|
|
|
const { parentNode, nextNode: anchor } = findBlockBoundary(instance.block)
|
|
const { parentNode, nextNode: anchor } = findBlockBoundary(instance.block)
|
|
@@ -39,16 +34,20 @@ export function hmrReload(
|
|
|
instance: VaporComponentInstance,
|
|
instance: VaporComponentInstance,
|
|
|
newComp: VaporComponent,
|
|
newComp: VaporComponent,
|
|
|
): void {
|
|
): void {
|
|
|
- // If parent is KeepAlive, rerender it so new component goes through
|
|
|
|
|
- // KeepAlive's slot rendering flow to receive activated hooks properly
|
|
|
|
|
- if (isKeepAliveEnabled && instance.parent && isKeepAlive(instance.parent)) {
|
|
|
|
|
- instance.parent.hmrRerender!()
|
|
|
|
|
|
|
+ const parentInstance = instance.parent
|
|
|
|
|
+
|
|
|
|
|
+ // Align child reloads with VDOM HMR: rerender the parent instead of
|
|
|
|
|
+ // surgically swapping the child instance. A local swap can leave parent
|
|
|
|
|
+ // block ownership, component refs, or exposed instances pointing at the old
|
|
|
|
|
+ // instance.
|
|
|
|
|
+ if (parentInstance) {
|
|
|
|
|
+ parentInstance.hmrRerender!()
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
const { parentNode, nextNode: anchor } = findBlockBoundary(instance.block)
|
|
const { parentNode, nextNode: anchor } = findBlockBoundary(instance.block)
|
|
|
const parent = parentNode as ParentNode
|
|
const parent = parentNode as ParentNode
|
|
|
unmountComponent(instance, parent)
|
|
unmountComponent(instance, parent)
|
|
|
- const parentInstance = instance.parent as VaporComponentInstance | null
|
|
|
|
|
const prev = setCurrentInstance(parentInstance)
|
|
const prev = setCurrentInstance(parentInstance)
|
|
|
let newInstance: VaporComponentInstance
|
|
let newInstance: VaporComponentInstance
|
|
|
try {
|
|
try {
|
|
@@ -65,78 +64,8 @@ export function hmrReload(
|
|
|
}
|
|
}
|
|
|
mountComponent(newInstance, parent, anchor)
|
|
mountComponent(newInstance, parent, anchor)
|
|
|
|
|
|
|
|
- if (!parentInstance) {
|
|
|
|
|
- const app = instance.appContext.app
|
|
|
|
|
- if (app && app._instance === instance) {
|
|
|
|
|
- app._instance = newInstance
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- updateParentBlockOnHmrReload(parentInstance, instance, newInstance)
|
|
|
|
|
- updateParentTeleportOnHmrReload(instance, newInstance)
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/**
|
|
|
|
|
- * dev only
|
|
|
|
|
- * update parentInstance.block to ensure that the correct parent and
|
|
|
|
|
- * anchor are found during parentInstance HMR rerender/reload, as
|
|
|
|
|
- * `findBlockBoundary` relies on the current instance.block
|
|
|
|
|
- */
|
|
|
|
|
-function updateParentBlockOnHmrReload(
|
|
|
|
|
- parentInstance: VaporComponentInstance | null,
|
|
|
|
|
- instance: VaporComponentInstance,
|
|
|
|
|
- newInstance: VaporComponentInstance,
|
|
|
|
|
-): void {
|
|
|
|
|
- if (parentInstance) {
|
|
|
|
|
- parentInstance.block = replaceBlockInstance(
|
|
|
|
|
- parentInstance.block,
|
|
|
|
|
- instance,
|
|
|
|
|
- newInstance,
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/**
|
|
|
|
|
- * dev only
|
|
|
|
|
- * during root component HMR reload, since the old component will be unmounted
|
|
|
|
|
- * and a new one will be mounted, we need to update the teleport's nodes
|
|
|
|
|
- * to ensure that the correct parent and anchor are found during parentInstance
|
|
|
|
|
- * HMR rerender/reload, as `findBlockBoundary` relies on the current instance.block
|
|
|
|
|
- */
|
|
|
|
|
-export function updateParentTeleportOnHmrReload(
|
|
|
|
|
- instance: VaporComponentInstance,
|
|
|
|
|
- newInstance: VaporComponentInstance,
|
|
|
|
|
-): void {
|
|
|
|
|
- const teleport = instance.parentTeleport
|
|
|
|
|
- if (teleport) {
|
|
|
|
|
- newInstance.parentTeleport = teleport
|
|
|
|
|
- teleport.nodes = replaceBlockInstance(teleport.nodes, instance, newInstance)
|
|
|
|
|
|
|
+ const app = instance.appContext.app
|
|
|
|
|
+ if (app && app._instance === instance) {
|
|
|
|
|
+ app._instance = newInstance
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-function replaceBlockInstance(
|
|
|
|
|
- block: Block,
|
|
|
|
|
- instance: VaporComponentInstance,
|
|
|
|
|
- newInstance: VaporComponentInstance,
|
|
|
|
|
-): Block {
|
|
|
|
|
- if (block === instance) return newInstance
|
|
|
|
|
-
|
|
|
|
|
- if (isArray(block)) {
|
|
|
|
|
- for (let i = 0; i < block.length; i++) {
|
|
|
|
|
- block[i] = replaceBlockInstance(block[i], instance, newInstance)
|
|
|
|
|
- }
|
|
|
|
|
- return block
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (isVaporComponent(block)) {
|
|
|
|
|
- block.block = replaceBlockInstance(block.block, instance, newInstance)
|
|
|
|
|
- return block
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (isFragment(block)) {
|
|
|
|
|
- block.nodes = replaceBlockInstance(block.nodes, instance, newInstance)
|
|
|
|
|
- return block
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return block
|
|
|
|
|
-}
|
|
|