Skip to content

Conversation

@daveycodez
Copy link

@daveycodez daveycodez commented Oct 30, 2025

Adds a call to import.meta.hot.invalidate() after cloning the Route during hot module replacement. This ensures the module is properly reloaded when routes are updated.

Fixes #5698

Summary by CodeRabbit

  • Bug Fixes
    • Improved hot module replacement behavior so route updates trigger proper module invalidation and a full page reload, ensuring updated routes are applied reliably during development.

Adds a call to import.meta.hot.invalidate() after cloning the Route during hot module replacement. This ensures the module is properly reloaded when routes are updated.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 30, 2025

Walkthrough

Adds an import.meta.hot?.invalidate() call inside the HMR accept callback immediately after newModule.Route.clone(Route) (when Route.clone exists), ensuring the route module is invalidated following the clone during hot updates.

Changes

Cohort / File(s) Summary
HMR Invalidation for Route Updates
packages/router-plugin/src/core/route-hmr-statement.ts
Inserted import.meta.hot?.invalidate() after newModule.Route.clone(Route) within the import.meta.hot.accept callback to force module invalidation on HMR when Route.clone is invoked.

Sequence Diagram(s)

sequenceDiagram
    participant Vite as Vite HMR
    participant RouteMod as Route Module
    participant VClient as Vite Client

    Vite->>RouteMod: File change -> HMR update
    RouteMod->>RouteMod: import.meta.hot.accept(callback)
    RouteMod->>RouteMod: newModule.Route.clone(Route)
    rect rgba(220,240,255,0.35)
      Note over RouteMod: New step: invalidate after clone (if clone exists)
      RouteMod->>Vite: import.meta.hot?.invalidate()
    end
    Vite->>VClient: Trigger reload / re-evaluate modules
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Single small, localized change in HMR callback logic.
  • Review attention:
    • Confirm Route.clone conditional is correctly guarded.
    • Verify no unintended double-invalidations in rapid HMR cycles.
    • Ensure optional chaining matches surrounding defensive patterns.

Poem

🐰 Hop, hopped a tiny line of code,

Clone then nudge the HMR road.
A gentle poke, a soft invalidate,
Loaders wake and gladly migrate.
Cheers — the dev-refresh parade!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Invalidate HMR after route clone in router plugin" directly describes the main code change documented in the raw summary. It accurately captures what the modification does—adding an import.meta.hot.invalidate() call after Route.clone() in the HMR accept callback within the router plugin. The title is concise, specific, and free of vague language or noise, making it clear to anyone reviewing the git history what this change accomplishes.
Linked Issues Check ✅ Passed The PR directly addresses issue #5698 by implementing a solution to ensure HMR properly invalidates and reloads when route code changes. The issue describes the problem that HMR does not re-run beforeLoad or loader functions when source code changes, and the workaround of manually adding import.meta.hot.invalidate() to route files. The PR implements this invalidation at the plugin level in route-hmr-statement.ts by adding the import.meta.hot.invalidate() call within the HMR accept callback after Route.clone(), which should automate the workaround and prevent the need for manual implementation in every route file, thereby meeting the core objective of enabling proper HMR behavior for route changes.
Out of Scope Changes Check ✅ Passed The changes are entirely within scope and directly related to the linked issue #5698. The modification to packages/router-plugin/src/core/route-hmr-statement.ts involves only adding an import.meta.hot.invalidate() call to the HMR accept callback, which is a surgical change that directly addresses the issue of HMR not properly refreshing route loaders and beforeLoad functions. No new features, unrelated files, or alterations to public API declarations are introduced, as indicated by the "None" entry in the alterations section of the summary.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9c89d82 and 72ec9fe.

📒 Files selected for processing (1)
  • packages/router-plugin/src/core/route-hmr-statement.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with extensive type safety across the codebase

Files:

  • packages/router-plugin/src/core/route-hmr-statement.ts
packages/{router-cli,router-generator,router-plugin,virtual-file-routes}/**

📄 CodeRabbit inference engine (AGENTS.md)

Keep CLI, generators, bundler plugins, and virtual file routing utilities in their dedicated tooling package directories

Files:

  • packages/router-plugin/src/core/route-hmr-statement.ts
packages/router-plugin/**

📄 CodeRabbit inference engine (AGENTS.md)

Use unplugin for universal bundler plugins in the router-plugin package

Files:

  • packages/router-plugin/src/core/route-hmr-statement.ts
🔇 Additional comments (1)
packages/router-plugin/src/core/route-hmr-statement.ts (1)

9-9: The HMR pattern is correct and recommended by Vite.

Vite officially supports calling import.meta.hot.invalidate() inside an accept() callback to force the update to propagate when the module cannot safely apply the HMR update. Your implementation correctly applies this pattern: after Route.clone() succeeds, invalidate() ensures loaders and beforeLoad functions are properly refreshed, which addresses issue #5698.

The test snapshots in packages/router-plugin/tests/add-hmr/snapshots/ confirm this is the expected output, and this pattern will not cause reload loops and is designed for exactly this use case.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 (1)
packages/router-plugin/src/core/route-hmr-statement.ts (1)

9-9: Consider removing optional chaining for consistency.

The optional chaining (?.) is technically redundant since we're already inside the if (import.meta.hot) block at line 5, which guarantees import.meta.hot is truthy. You could use import.meta.hot.invalidate() directly for consistency with line 6.

Apply this diff if you prefer consistency:

-      import.meta.hot?.invalidate()
+      import.meta.hot.invalidate()
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a62499 and 9c89d82.

📒 Files selected for processing (1)
  • packages/router-plugin/src/core/route-hmr-statement.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with extensive type safety across the codebase

Files:

  • packages/router-plugin/src/core/route-hmr-statement.ts
packages/{router-cli,router-generator,router-plugin,virtual-file-routes}/**

📄 CodeRabbit inference engine (AGENTS.md)

Keep CLI, generators, bundler plugins, and virtual file routing utilities in their dedicated tooling package directories

Files:

  • packages/router-plugin/src/core/route-hmr-statement.ts
packages/router-plugin/**

📄 CodeRabbit inference engine (AGENTS.md)

Use unplugin for universal bundler plugins in the router-plugin package

Files:

  • packages/router-plugin/src/core/route-hmr-statement.ts
🧠 Learnings (1)
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
PR: TanStack/router#5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.

Applied to files:

  • packages/router-plugin/src/core/route-hmr-statement.ts
🔇 Additional comments (1)
packages/router-plugin/src/core/route-hmr-statement.ts (1)

3-14: LGTM! This correctly addresses the HMR issue.

The addition of invalidate() after cloning the Route ensures that updated loader and beforeLoad functions are properly re-executed during HMR, which fixes the issue where Vite reported updates but the runtime continued using old function behavior.

Replaces 'import.meta.hot?.invalidate()' with 'import.meta.hot.invalidate()' in the route HMR statement, as 'import.meta.hot' is already checked for existence.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Start: HMR does not refresh loaders or beforeLoad

1 participant