-
-
Notifications
You must be signed in to change notification settings - Fork 9k
fix(Suspence): handle Suspense + KeepAlive HMR updating edge case #13076
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Size ReportBundles
Usages
|
@vue/compiler-core
@vue/compiler-dom
@vue/compiler-sfc
@vue/compiler-ssr
@vue/reactivity
@vue/runtime-core
@vue/runtime-dom
@vue/server-renderer
@vue/shared
vue
@vue/compat
commit: |
|
https://github.com/vuejs/core/blob/main/packages/runtime-core/src/vnode.ts#L391-L401 |
WalkthroughAdds an HMR regression test for a child component wrapped in Suspense and KeepAlive. Adjusts isSameVNodeType argument order in Suspense and BaseTransition to modify vnode type comparison paths. No public API changes. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Dev as Dev Server (HMR)
participant App as App (KeepAlive > Suspense)
participant Child as Child Component
participant Renderer as Renderer
Dev->>App: HMR update (Child v1)
App->>Renderer: Mount Suspense + KeepAlive with Child
Renderer-->>App: Initial DOM shows count=0
Dev->>App: HMR reload (Child v2)
App->>Renderer: Patch Child under Suspense/KeepAlive
note over Renderer: Compare vnode types (updated checks)
Renderer-->>App: DOM updates count=1
Dev->>App: HMR reload (Child v3)
App->>Renderer: Patch Child again
Renderer-->>App: DOM updates count=2
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Assessment against linked issues
Suggested labels
Suggested reviewers
Poem
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
|
/ecosystem-ci run |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
packages/runtime-core/src/components/BaseTransition.ts (1)
203-210: Correct arg order for isSameVNodeType (old, new) — fixes HMR with KeepAlive+TransitionSwapping to
isSameVNodeType(oldInnerChild, innerChild)aligns with the function’s HMR guard which expects(oldVNode, newVNode). This prevents stale instances from being “kept alive” across HMR. Looks good.Consider an inline comment to prevent future regressions:
- if ( + // HMR note: pass (old, new) to isSameVNodeType + if ( oldInnerChild && oldInnerChild.type !== Comment && !isSameVNodeType(oldInnerChild, innerChild) && recursiveGetSubtree(instance).type !== Comment ) {packages/runtime-core/src/components/Suspense.ts (1)
236-244: All three comparisons now pass (old, new) into isSameVNodeType — matches HMR contract
- pending vs new branch
- active vs new branch (both pending and non-pending paths)
These swaps ensure the HMR dirty-instance check runs and the keep-alive flags are adjusted on the correct sides. Nice.
Add a short comment once to document the non-commutative intent:
- if (isSameVNodeType(pendingBranch, newBranch)) { + // HMR note: isSameVNodeType expects (old, new) + if (isSameVNodeType(pendingBranch, newBranch)) {Also applies to: 324-339, 358-372
packages/runtime-core/__tests__/hmr.spec.ts (1)
898-949: Good regression coverage for multi-reload with KeepAlive outside SuspenseThe test reproduces the “second reload doesn’t update” edge case and validates both successive updates. LGTM.
For tighter determinism (no macro-task dependency), consider
await nextTick()after eachreload(this test is fully sync aside from HMR scheduling):- await timeout() + await nextTick() ... - await timeout() + await nextTick()Optionally DRY the reload steps:
+ const reloadTo = (n: number) => + reload(id, { + __hmrId: id, + setup() { return { count: ref(n) } }, + render: compileToFunction(`<div>{{ count }}</div>`), + }) ... - reload(id, { ...count: ref(1)... }); await nextTick() + reloadTo(1); await nextTick() ... - reload(id, { ...count: ref(2)... }); await nextTick() + reloadTo(2); await nextTick()
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
packages/runtime-core/__tests__/hmr.spec.ts(1 hunks)packages/runtime-core/src/components/BaseTransition.ts(1 hunks)packages/runtime-core/src/components/Suspense.ts(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
packages/runtime-core/src/components/BaseTransition.ts (1)
packages/runtime-core/src/vnode.ts (1)
isSameVNodeType(391-404)
packages/runtime-core/src/components/Suspense.ts (1)
packages/runtime-core/src/vnode.ts (1)
isSameVNodeType(391-404)
packages/runtime-core/__tests__/hmr.spec.ts (2)
packages/runtime-test/src/serialize.ts (1)
serializeInner(22-33)packages/vue/__tests__/e2e/e2eUtils.ts (1)
timeout(16-17)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test / unit-test-windows
🔇 Additional comments (2)
packages/runtime-core/src/components/BaseTransition.ts (1)
389-397: Keep argument order as is: in this branchleavingVNodeis always an element VNode (itsshapeFlagdoesn’t include COMPONENT), so the HMR check inside isSameVNodeType (guarded byn2.shapeFlag & ShapeFlags.COMPONENT) never runs here—no swap needed.packages/runtime-core/src/components/Suspense.ts (1)
235-243: Update sanity sweep to check for 5 call sites, not 4
There are three in Suspense.ts (lines 238, 324, 358) and two in BaseTransition.ts (lines 207, 393).Likely an incorrect or invalid review comment.
|
📝 Ran ecosystem CI: Open
|

fix #13075
Summary by CodeRabbit
Bug Fixes
Tests