Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@
- vladinator1000
- vonagam
- WalkAlone0325
- wanxiankai
- whxhlgy
- wilcoxmd
- willemarcel
Expand Down
22 changes: 22 additions & 0 deletions integration/vite-hmr-hdr-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ templates.forEach((template) => {
// imports
import { useState, useEffect } from "react";

if (typeof window !== "undefined") {
const global = window as typeof window & { __routeEvaluations?: number };
global.__routeEvaluations = (global.__routeEvaluations ?? 0) + 1;
}

export const meta = () => [{ title: "HMR updated title: 0" }]

// loader
Expand Down Expand Up @@ -170,6 +175,15 @@ async function workflow({

await expect(page).toHaveTitle("HMR updated title: 0");
await expect(hmrStatus).toHaveText("HMR updated: 0");
await expect
.poll(() =>
page.evaluate(
() =>
(window as typeof window & { __routeEvaluations?: number })
.__routeEvaluations,
),
)
.toBe(1);
let input = page.locator("#index input");
await expect(input).toBeVisible();
await input.fill("stateful");
Expand All @@ -187,6 +201,14 @@ async function workflow({
await expect(page).toHaveTitle("HMR updated title: 1");
await expect(hmrStatus).toHaveText("HMR updated: 1");
await expect(input).toHaveValue("stateful");
await page.waitForTimeout(100);
expect(
await page.evaluate(
() =>
(window as typeof window & { __routeEvaluations?: number })
.__routeEvaluations,
),
).toBe(2);
expect(page.errors).toEqual([]);

// route: add loader
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Avoid duplicate client HMR updates when source modules change in development
15 changes: 12 additions & 3 deletions packages/react-router-dev/vite/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2433,12 +2433,21 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
// each other, so we need to manually trigger client HMR updates if server
// code has changed.
hotUpdate(this, { server, modules }) {
if (this.environment.name !== "ssr" && modules.length <= 0) {
if (this.environment.name !== "ssr" || modules.length <= 0) {
return;
}

let clientModules = modules.flatMap((mod) =>
getParentClientNodes(server.environments.client.moduleGraph, mod),
let clientModuleGraph = server.environments.client.moduleGraph;
let clientModules = new Set(
modules.flatMap((mod) => {
// Modules that exist in the client graph already receive Vite's
// native client HMR update. Only propagate changes from modules
// that are exclusive to the server graph.
if (mod.id && clientModuleGraph.getModuleById(mod.id)) {
return [];
}
return getParentClientNodes(clientModuleGraph, mod);
}),
);

for (let clientModule of clientModules) {
Expand Down