Skip to content

Commit 9f0964a

Browse files
authored
feat(HMR):update client routes by HMR (#472)
1 parent a4ba64c commit 9f0964a

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

framework/react/router.ts

+29-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import FetchError from "../core/fetch_error.ts";
55
import { redirect } from "../core/redirect.ts";
66
import type { Route, RouteMeta, RouteModule, RouteRecord } from "../core/route.ts";
77
import { matchRoutes } from "../core/route.ts";
8-
import { URLPatternCompat } from "../core/url_pattern.ts";
8+
import { URLPatternCompat, URLPatternInput } from "../core/url_pattern.ts";
99
import { ForwardPropsContext, RouterContext, type RouterContextProps } from "./context.ts";
1010
import { DataProvider, type RouteData } from "./data.ts";
1111
import { Err, ErrorBoundary } from "./error.ts";
@@ -199,12 +199,39 @@ export const Router: FC<RouterProps> = ({ ssrContext, suspense, createPortal })
199199
events.on("moduleprefetch", onmoduleprefetch);
200200
events.emit("routerready", { type: "routerready" });
201201

202-
// todo: update routes by hmr
202+
const oncreate = (e: Record<string, unknown>) => {
203+
const route: Route = [
204+
new URLPatternCompat(e.routePattern as URLPatternInput),
205+
{
206+
filename: e.specifier as string,
207+
pattern: e.routePattern as URLPatternInput,
208+
},
209+
];
210+
const pathname = (e.routePattern as URLPatternInput).pathname.slice(1);
211+
if (pathname === "_app" || pathname === "_404" || pathname === "_error") {
212+
routeRecord[pathname] = route;
213+
}
214+
routeRecord.routes.push(route);
215+
};
216+
events.on("hmr:create", oncreate);
217+
218+
const onremove = (e: Record<string, unknown>) => {
219+
const route = routeRecord.routes.find((v) => v[1].filename === e.specifier);
220+
const pathname = (route?.[1].pattern.pathname)?.slice(1);
221+
if (pathname === "_app" || pathname === "_404" || pathname === "_error") {
222+
routeRecord[pathname] = undefined;
223+
}
224+
routeRecord.routes = routeRecord.routes.filter((v) => v[1].filename != e.specifier);
225+
onpopstate({ type: "popstate" });
226+
};
227+
events.on("hmr:remove", onremove);
203228

204229
return () => {
205230
removeEventListener("popstate", onpopstate as unknown as EventListener);
206231
events.off("popstate", onpopstate);
207232
events.off("moduleprefetch", onmoduleprefetch);
233+
events.off("hmr:create", oncreate);
234+
events.off("hmr:remove", onremove);
208235
};
209236
}, []);
210237

0 commit comments

Comments
 (0)