Skip to content

Commit 93d64ad

Browse files
test(rsc): migrate Vite fixtures to @hiogawa/vite-rsc (#13819)
chore: enable vite tests on windows --------- Co-authored-by: Jacob Ebey <[email protected]>
1 parent 91dc3da commit 93d64ad

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+397
-1239
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dist
2+
node_modules

integration/helpers/rsc-vite/.wrangler/deploy/config.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

integration/helpers/rsc-vite/framework/references.browser.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

integration/helpers/rsc-vite/framework/references.rsc.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

integration/helpers/rsc-vite/framework/references.ssr.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

integration/helpers/rsc-vite/framework/server.ts

Lines changed: 0 additions & 19 deletions
This file was deleted.

integration/helpers/rsc-vite/package.json

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,24 @@
11
{
2-
"name": "@playground/rsc-vite",
2+
"name": "integration-rsc-vite",
33
"private": true,
44
"type": "module",
55
"scripts": {
66
"dev": "vite",
7-
"build": "vite build",
8-
"start": "node server.js",
7+
"build": "vite build --app",
8+
"start": "cross-env NODE_ENV=production node server.js",
99
"typecheck": "tsc"
1010
},
1111
"devDependencies": {
12-
"@biomejs/biome": "^1.9.4",
13-
"@cloudflare/vite-plugin": "0.1.7",
14-
"@cloudflare/workers-types": "^4.20250224.0",
15-
"@jacob-ebey/vite-react-server-dom": "0.0.12",
12+
"@hiogawa/vite-rsc": "0.4.1",
1613
"@types/express": "^5.0.0",
1714
"@types/node": "^22.13.1",
18-
"@types/react": "^19.0.8",
19-
"@types/react-dom": "^19.0.3",
15+
"@types/react": "^19.1.8",
16+
"@types/react-dom": "^19.1.6",
17+
"@vitejs/plugin-react": "^4.5.2",
2018
"typescript": "^5.1.6",
21-
"vite": "^6.2.0",
22-
"vite-tsconfig-paths": "^5.1.4",
23-
"wrangler": "^3.111.0"
19+
"vite": "^6.2.0"
2420
},
2521
"dependencies": {
26-
"@jacob-ebey/react-server-dom-vite": "19.0.0-experimental.14",
2722
"@mjackson/node-fetch-server": "0.6.1",
2823
"compression": "^1.8.0",
2924
"express": "^4.21.2",

integration/helpers/rsc-vite/server.js

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import { createRequestListener } from "@mjackson/node-fetch-server";
33
import compression from "compression";
44
import express from "express";
55

6-
import ssr from "./dist/ssr/entry.ssr.js";
7-
import server from "./dist/server/entry.rsc.js";
6+
import rscRequestHandler from "./dist/rsc/index.js";
87

98
const app = express();
109

@@ -16,17 +15,7 @@ app.get("/.well-known/appspecific/com.chrome.devtools.json", (req, res) => {
1615
res.end();
1716
});
1817

19-
app.use(
20-
createRequestListener((request) => {
21-
return ssr.fetch(request, {
22-
SERVER: {
23-
fetch(request) {
24-
return server.fetch(request);
25-
},
26-
},
27-
});
28-
})
29-
);
18+
app.use(createRequestListener(rscRequestHandler));
3019

3120
const { values } = parseArgs({
3221
options: { p: { type: "string", default: "3000" } },

integration/helpers/rsc-vite/src/entry.browser.tsx

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,34 @@ import { hydrateRoot } from "react-dom/client";
33
import {
44
createFromReadableStream,
55
encodeReply,
6-
// @ts-expect-error - no types
7-
} from "@jacob-ebey/react-server-dom-vite/client";
8-
// @ts-expect-error - no types yet
9-
import { manifest } from "virtual:react-manifest";
10-
6+
setServerCallback,
7+
} from "@hiogawa/vite-rsc/browser";
8+
import type { unstable_DecodeServerResponseFunction as DecodeServerResponseFunction } from "react-router";
119
import {
12-
type unstable_DecodeServerResponseFunction as DecodeServerResponseFunction,
13-
type unstable_EncodeActionFunction as EncodeActionFunction,
1410
unstable_createCallServer as createCallServer,
1511
unstable_getServerStream as getServerStream,
1612
unstable_RSCHydratedRouter as RSCHydratedRouter,
1713
} from "react-router";
18-
import { type unstable_ServerPayload as ServerPayload } from "react-router/rsc";
19-
20-
const encodeAction: EncodeActionFunction = (args: unknown[]) =>
21-
encodeReply(args);
14+
import type { unstable_ServerPayload as ServerPayload } from "react-router/rsc";
2215

23-
const decode: DecodeServerResponseFunction = (body) =>
24-
createFromReadableStream(body, manifest, { callServer });
16+
const decode: DecodeServerResponseFunction = (
17+
body: ReadableStream<Uint8Array>
18+
) => createFromReadableStream(body);
2519

26-
const callServer = createCallServer({ decode, encodeAction });
27-
28-
createFromReadableStream(getServerStream(), manifest, { callServer }).then(
29-
(payload: ServerPayload) => {
30-
startTransition(() => {
31-
hydrateRoot(
32-
document,
33-
<StrictMode>
34-
<RSCHydratedRouter decode={decode} payload={payload} />
35-
</StrictMode>
36-
);
37-
});
38-
}
20+
setServerCallback(
21+
createCallServer({
22+
decode,
23+
encodeAction: (args) => encodeReply(args),
24+
})
3925
);
26+
27+
createFromReadableStream<ServerPayload>(getServerStream()).then((payload) => {
28+
startTransition(() => {
29+
hydrateRoot(
30+
document,
31+
<StrictMode>
32+
<RSCHydratedRouter decode={decode} payload={payload as any} />
33+
</StrictMode>
34+
);
35+
});
36+
});
Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,46 @@
1-
/// <reference types="@cloudflare/workers-types" />
1+
import {
2+
decodeAction,
3+
decodeReply,
4+
loadServerAction,
5+
renderToReadableStream,
6+
} from "@hiogawa/vite-rsc/rsc";
27
import {
38
type unstable_DecodeCallServerFunction as DecodeCallServerFunction,
9+
type unstable_DecodeFormActionFunction as DecodeFormActionFunction,
410
unstable_matchRSCServerRequest as matchRSCServerRequest,
511
} from "react-router/rsc";
6-
// @ts-expect-error - no types yet
7-
import { manifest } from "virtual:react-manifest";
812

9-
import { decodeReply, renderToReadableStream } from "../framework/server";
1013
import { routes } from "./routes";
1114

1215
const decodeCallServer: DecodeCallServerFunction = async (actionId, reply) => {
1316
const args = await decodeReply(reply);
14-
const reference = manifest.resolveServerReference(actionId);
15-
await reference.preload();
16-
const action = reference.get() as (...args: unknown[]) => Promise<unknown>;
17+
const action = await loadServerAction(actionId);
1718
return action.bind(null, ...args);
1819
};
1920

20-
export default {
21-
fetch(request, env) {
22-
return matchRSCServerRequest({
23-
decodeCallServer,
24-
request,
25-
routes,
26-
generateResponse(match) {
27-
if (match instanceof Response) {
28-
return match;
29-
}
21+
const decodeFormAction: DecodeFormActionFunction = async (formData) => {
22+
return await decodeAction(formData);
23+
};
24+
25+
export async function callServer(request: Request) {
26+
return await matchRSCServerRequest({
27+
decodeCallServer,
28+
decodeFormAction,
29+
request,
30+
routes,
31+
generateResponse(match) {
32+
return new Response(renderToReadableStream(match.payload), {
33+
status: match.statusCode,
34+
headers: match.headers,
35+
});
36+
},
37+
});
38+
}
3039

31-
return new Response(renderToReadableStream(match.payload), {
32-
status: match.statusCode,
33-
headers: match.headers,
34-
});
35-
},
36-
});
37-
},
38-
} satisfies ExportedHandler;
40+
export default async function handler(request: Request) {
41+
const ssr = await import.meta.viteRsc.loadSsrModule<
42+
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
43+
typeof import("./entry.ssr")
44+
>("index");
45+
return ssr.default(request, callServer);
46+
}
Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,28 @@
1-
/// <reference types="@cloudflare/workers-types" />
2-
3-
// @ts-expect-error
4-
import RSD from "@jacob-ebey/react-server-dom-vite/client";
1+
import bootstrapScriptContent from "virtual:vite-rsc/bootstrap-script-content";
2+
import { createFromReadableStream } from "@hiogawa/vite-rsc/ssr";
53
// @ts-expect-error
6-
import RDS from "react-dom/server.edge";
7-
// @ts-expect-error
8-
import { bootstrapModules, manifest } from "virtual:react-manifest";
9-
4+
import * as ReactDomServer from "react-dom/server.edge";
105
import {
11-
unstable_routeRSCServerRequest as routeRSCServerRequest,
126
unstable_RSCStaticRouter as RSCStaticRouter,
7+
unstable_routeRSCServerRequest as routeRSCServerRequest,
138
} from "react-router";
149

15-
type CloudflareEnv = {
16-
ASSETS: Fetcher;
17-
SERVER: Fetcher;
18-
};
19-
20-
export default {
21-
async fetch(request, { SERVER }) {
22-
const callServer = async (request: Request) => await SERVER.fetch(request);
23-
try {
24-
return await routeRSCServerRequest({
25-
request,
26-
callServer,
27-
decode: (body) => RSD.createFromReadableStream(body, manifest),
28-
async renderHTML(getPayload) {
29-
return await RDS.renderToReadableStream(
30-
<RSCStaticRouter getPayload={getPayload} />,
31-
{
32-
bootstrapModules,
33-
signal: request.signal,
34-
}
35-
);
36-
},
37-
});
38-
} catch (reason) {
39-
console.error(reason);
40-
return new Response("Internal Server Error", { status: 500 });
41-
}
42-
},
43-
} satisfies ExportedHandler<CloudflareEnv>;
10+
export default async function handler(
11+
request: Request,
12+
callServer: (request: Request) => Promise<Response>
13+
) {
14+
return routeRSCServerRequest({
15+
request,
16+
callServer,
17+
decode: (body) => createFromReadableStream(body),
18+
renderHTML(getPayload) {
19+
return ReactDomServer.renderToReadableStream(
20+
<RSCStaticRouter getPayload={getPayload} />,
21+
{
22+
bootstrapScriptContent,
23+
signal: request.signal,
24+
}
25+
);
26+
},
27+
});
28+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export default function ServerComponent() {
1+
export default function HomeRoute() {
22
return <h2>Home</h2>;
33
}

integration/helpers/rsc-vite/src/routes/root.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ export function Layout({ children }: { children: React.ReactNode }) {
1717
);
1818
}
1919

20-
export default function ServerComponent() {
20+
export default function RootRoute() {
2121
return <Outlet />;
2222
}

integration/helpers/rsc-vite/src/wrangler.rsc.toml

Lines changed: 0 additions & 4 deletions
This file was deleted.

integration/helpers/rsc-vite/src/wrangler.ssr.toml

Lines changed: 0 additions & 6 deletions
This file was deleted.

integration/helpers/rsc-vite/tsconfig.client.json

Lines changed: 0 additions & 25 deletions
This file was deleted.
Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
{
2-
"files": [],
3-
"references": [
4-
{ "path": "./tsconfig.node.json" },
5-
{ "path": "./tsconfig.client.json" }
6-
]
2+
"compilerOptions": {
3+
"allowImportingTsExtensions": true,
4+
"strict": true,
5+
"noUnusedLocals": true,
6+
"noUnusedParameters": true,
7+
"skipLibCheck": true,
8+
"verbatimModuleSyntax": true,
9+
"noEmit": true,
10+
"moduleResolution": "Bundler",
11+
"module": "ESNext",
12+
"target": "ESNext",
13+
"lib": ["ESNext", "DOM", "DOM.Iterable"],
14+
"types": ["vite/client", "@hiogawa/vite-rsc/types"],
15+
"jsx": "react-jsx"
16+
}
717
}

0 commit comments

Comments
 (0)