diff --git a/.changeset/nice-cobras-sparkle.md b/.changeset/nice-cobras-sparkle.md new file mode 100644 index 0000000000..43405684f3 --- /dev/null +++ b/.changeset/nice-cobras-sparkle.md @@ -0,0 +1,5 @@ +--- +"@react-router/dev": patch +--- + +Ensure typegen file watcher is cleaned up when Vite dev server restarts diff --git a/packages/react-router-dev/typegen/index.ts b/packages/react-router-dev/typegen/index.ts index 95d980dcb1..06a1df81fc 100644 --- a/packages/react-router-dev/typegen/index.ts +++ b/packages/react-router-dev/typegen/index.ts @@ -15,10 +15,14 @@ export async function run(rootDirectory: string) { await writeAll(ctx); } +export type Watcher = { + close: () => Promise; +}; + export async function watch( rootDirectory: string, { logger }: { logger?: vite.Logger } = {} -) { +): Promise { const ctx = await createContext({ rootDirectory, watch: true }); await writeAll(ctx); logger?.info(pc.green("generated types"), { timestamp: true, clear: true }); @@ -38,6 +42,10 @@ export async function watch( }); } }); + + return { + close: async () => await ctx.configLoader.close(), + }; } async function createContext({ diff --git a/packages/react-router-dev/vite/plugin.ts b/packages/react-router-dev/vite/plugin.ts index f8bd39c0c4..f2f08f1bd6 100644 --- a/packages/react-router-dev/vite/plugin.ts +++ b/packages/react-router-dev/vite/plugin.ts @@ -409,6 +409,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => { let cssModulesManifest: Record = {}; let viteChildCompiler: Vite.ViteDevServer | null = null; let reactRouterConfigLoader: ConfigLoader; + let typegenWatcherPromise: Promise | undefined; let logger: Vite.Logger; let firstLoad = true; @@ -748,7 +749,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => { viteUserConfig.root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd(); if (viteCommand === "serve") { - Typegen.watch(rootDirectory, { + typegenWatcherPromise = Typegen.watch(rootDirectory, { // ignore `info` logs from typegen since they are redundant when Vite plugin logs are active logger: vite.createLogger("warn", { prefix: "[react-router]" }), }); @@ -1246,6 +1247,9 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => { async buildEnd() { await viteChildCompiler?.close(); await reactRouterConfigLoader.close(); + + let typegenWatcher = await typegenWatcherPromise; + await typegenWatcher?.close(); }, }, {