From 541fee15d1436c3f5d68619367840218fb940fce Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Tue, 4 Mar 2025 14:46:35 +1100 Subject: [PATCH] Generate types for `virtual:react-router/server-build` --- .changeset/silver-peas-shop.md | 5 +++ .../workers/app.ts | 1 - integration/typegen-test.ts | 43 +++++++++++++++++++ packages/react-router-dev/typegen/index.ts | 20 +++++++++ packages/react-router-dev/vite/plugin.ts | 2 +- .../react-router/lib/server-runtime/build.ts | 2 +- .../react-router/lib/server-runtime/server.ts | 4 +- .../vite-plugin-cloudflare/workers/app.ts | 1 - 8 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 .changeset/silver-peas-shop.md diff --git a/.changeset/silver-peas-shop.md b/.changeset/silver-peas-shop.md new file mode 100644 index 0000000000..38fc4f1d61 --- /dev/null +++ b/.changeset/silver-peas-shop.md @@ -0,0 +1,5 @@ +--- +"@react-router/dev": minor +--- + +Generate types for `virtual:react-router/server-build` module diff --git a/integration/helpers/vite-plugin-cloudflare-template/workers/app.ts b/integration/helpers/vite-plugin-cloudflare-template/workers/app.ts index bf41f02ee2..df4d932d2b 100644 --- a/integration/helpers/vite-plugin-cloudflare-template/workers/app.ts +++ b/integration/helpers/vite-plugin-cloudflare-template/workers/app.ts @@ -14,7 +14,6 @@ declare module "react-router" { } const requestHandler = createRequestHandler( - // @ts-expect-error () => import("virtual:react-router/server-build"), import.meta.env.MODE ); diff --git a/integration/typegen-test.ts b/integration/typegen-test.ts index e1faa8f9a4..7b0ff85cee 100644 --- a/integration/typegen-test.ts +++ b/integration/typegen-test.ts @@ -444,4 +444,47 @@ test.describe("typegen", () => { expect(proc.stderr.toString()).toBe(""); expect(proc.status).toBe(0); }); + + test.describe("virtual:react-router/server-build", async () => { + test("static import matches 'createRequestHandler' argument type", async () => { + const cwd = await createProject({ + "vite.config.ts": viteConfig, + "app/routes.ts": tsx` + import { type RouteConfig } from "@react-router/dev/routes"; + export default [] satisfies RouteConfig; + `, + "app/handler.ts": tsx` + import { createRequestHandler } from "react-router"; + import * as serverBuild from "virtual:react-router/server-build"; + export default createRequestHandler(serverBuild); + `, + }); + + const proc = typecheck(cwd); + expect(proc.stdout.toString()).toBe(""); + expect(proc.stderr.toString()).toBe(""); + expect(proc.status).toBe(0); + }); + + test("dynamic import matches 'createRequestHandler' function argument type", async () => { + const cwd = await createProject({ + "vite.config.ts": viteConfig, + "app/routes.ts": tsx` + import { type RouteConfig } from "@react-router/dev/routes"; + export default [] satisfies RouteConfig; + `, + "app/handler.ts": tsx` + import { createRequestHandler } from "react-router"; + export default createRequestHandler( + () => import("virtual:react-router/server-build") + ); + `, + }); + + const proc = typecheck(cwd); + expect(proc.stdout.toString()).toBe(""); + expect(proc.stderr.toString()).toBe(""); + expect(proc.status).toBe(0); + }); + }); }); diff --git a/packages/react-router-dev/typegen/index.ts b/packages/react-router-dev/typegen/index.ts index 4436adac2f..393a0025d1 100644 --- a/packages/react-router-dev/typegen/index.ts +++ b/packages/react-router-dev/typegen/index.ts @@ -88,6 +88,9 @@ async function writeAll(ctx: Context): Promise { const registerPath = Path.join(typegenDir, "+register.ts"); fs.writeFileSync(registerPath, register(ctx)); + + const virtualPath = Path.join(typegenDir, "+virtual.ts"); + fs.writeFileSync(virtualPath, virtual); } function register(ctx: Context) { @@ -146,3 +149,20 @@ function register(ctx: Context) { return [register, Babel.generate(typeParams).code].join("\n\n"); } + +const virtual = ts` + declare module "virtual:react-router/server-build" { + import { ServerBuild } from "react-router"; + export const assets: ServerBuild["assets"]; + export const assetsBuildDirectory: ServerBuild["assetsBuildDirectory"]; + export const basename: ServerBuild["basename"]; + export const entry: ServerBuild["entry"]; + export const future: ServerBuild["future"]; + export const isSpaMode: ServerBuild["isSpaMode"]; + export const prerender: ServerBuild["prerender"]; + export const publicPath: ServerBuild["publicPath"]; + export const routes: ServerBuild["routes"]; + export const ssr: ServerBuild["ssr"]; + export const unstable_getCriticalCss: ServerBuild["unstable_getCriticalCss"]; + } +`; diff --git a/packages/react-router-dev/vite/plugin.ts b/packages/react-router-dev/vite/plugin.ts index 7e5dee1900..fd1a7664c2 100644 --- a/packages/react-router-dev/vite/plugin.ts +++ b/packages/react-router-dev/vite/plugin.ts @@ -756,7 +756,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => { ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteCommand === "serve" ? ` - export const getCriticalCss = ({ pathname }) => { + export const unstable_getCriticalCss = ({ pathname }) => { return { rel: "stylesheet", href: "${ diff --git a/packages/react-router/lib/server-runtime/build.ts b/packages/react-router/lib/server-runtime/build.ts index e21b2b76b1..1381600352 100644 --- a/packages/react-router/lib/server-runtime/build.ts +++ b/packages/react-router/lib/server-runtime/build.ts @@ -24,7 +24,7 @@ export interface ServerBuild { assetsBuildDirectory: string; future: FutureConfig; ssr: boolean; - getCriticalCss?: (args: { + unstable_getCriticalCss?: (args: { pathname: string; }) => OptionalCriticalCss | Promise; /** diff --git a/packages/react-router/lib/server-runtime/server.ts b/packages/react-router/lib/server-runtime/server.ts index 3bafec01fa..39b329ddd0 100644 --- a/packages/react-router/lib/server-runtime/server.ts +++ b/packages/react-router/lib/server-runtime/server.ts @@ -267,8 +267,8 @@ export const createRequestHandler: CreateRequestHandlerFunction = ( let { pathname } = url; let criticalCss: CriticalCss | undefined = undefined; - if (_build.getCriticalCss) { - criticalCss = await _build.getCriticalCss({ pathname }); + if (_build.unstable_getCriticalCss) { + criticalCss = await _build.unstable_getCriticalCss({ pathname }); } else if ( mode === ServerMode.Development && getDevServerHooks()?.getCriticalCss diff --git a/playground/vite-plugin-cloudflare/workers/app.ts b/playground/vite-plugin-cloudflare/workers/app.ts index bf41f02ee2..df4d932d2b 100644 --- a/playground/vite-plugin-cloudflare/workers/app.ts +++ b/playground/vite-plugin-cloudflare/workers/app.ts @@ -14,7 +14,6 @@ declare module "react-router" { } const requestHandler = createRequestHandler( - // @ts-expect-error () => import("virtual:react-router/server-build"), import.meta.env.MODE );