Skip to content

Commit 9ca65e8

Browse files
authored
fix: ts type error (#43)
1 parent 4268c86 commit 9ca65e8

14 files changed

Lines changed: 181 additions & 35 deletions

File tree

.github/workflows/lint.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,11 @@ jobs:
2929
- name: Install dependencies
3030
run: pnpm install
3131

32+
- name: Build RSC plugin
33+
run: pnpm build
34+
35+
- name: Run typecheck
36+
run: pnpm typecheck
37+
3238
- name: Run lint
3339
run: pnpm lint

examples/client/rsbuild.config.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { defineConfig } from '@rsbuild/core';
22
import { pluginReact } from '@rsbuild/plugin-react';
33
import { Layers, pluginRSC } from 'rsbuild-plugin-rsc';
4-
import type NodeHandler from './server';
4+
5+
type NodeHandler = typeof import('./server/index').default;
56

67
export default defineConfig({
78
plugins: [pluginReact(), pluginRSC()],
@@ -25,7 +26,11 @@ export default defineConfig({
2526
},
2627
},
2728
server: {
28-
setup: ({ server }) => {
29+
setup: ({ action, server }) => {
30+
if (action !== 'dev') {
31+
return;
32+
}
33+
2934
// Custom middleware to handle RSC (React Server Components) requests
3035
server.middlewares.use(async (req, res, next) => {
3136
const indexModule = await server.environments.server.loadBundle<{

examples/client/server/index.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import type { IncomingMessage, ServerResponse } from 'node:http';
12
import type { ReactFormState } from 'react-dom/client';
23
import {
34
renderToReadableStream,
5+
type ServerEntry,
46
type TemporaryReferenceSet,
57
} from 'react-server-dom-rspack/server.node';
68
import { toNodeHandler } from 'srvx/node';
@@ -15,10 +17,11 @@ export type RscPayload = {
1517
async function handler(): Promise<Response> {
1618
let temporaryReferences: TemporaryReferenceSet | undefined;
1719
const rscOptions = { temporaryReferences };
20+
const RscEntry = RSC as ServerEntry<typeof RSC>;
1821
const root = (
1922
<>
20-
{RSC.entryCssFiles
21-
? RSC.entryCssFiles.map((href) => (
23+
{RscEntry.entryCssFiles
24+
? RscEntry.entryCssFiles.map((href) => (
2225
<link
2326
key={href}
2427
rel="stylesheet"

examples/client/tsconfig.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"target": "ESNext",
1414
"lib": ["ESNext", "DOM", "DOM.Iterable"],
1515
"jsx": "react-jsx",
16-
"types": ["webpack-env"]
17-
}
16+
"types": ["webpack-env", "node"]
17+
},
18+
"include": ["client", "server", "rsbuild.config.ts", "../../types/**/*.d.ts"]
1819
}

examples/react-router/src/entry.rsc.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import {
55
decodeAction,
66
decodeFormState,
77
decodeReply,
8-
loadServerAction,
8+
loadServerAction as loadServerActionSync,
99
renderToReadableStream,
10+
type ServerEntry,
1011
} from 'react-server-dom-rspack/server.node';
1112
import { toNodeHandler } from 'srvx/node';
1213
import { generateHTML } from './entry.ssr';
@@ -20,7 +21,7 @@ async function fetchServer(request: Request) {
2021
decodeAction,
2122
decodeFormState,
2223
decodeReply,
23-
loadServerAction,
24+
loadServerAction: (id) => Promise.resolve(loadServerActionSync(id)),
2425
request,
2526
// The app routes.
2627
routes: routes(),
@@ -36,12 +37,16 @@ async function fetchServer(request: Request) {
3637

3738
async function handler(request: Request): Promise<Response> {
3839
const response = await fetchServer(request);
40+
const layoutEntry = Layout as ServerEntry<typeof Layout>;
3941
return generateHTML(request, response, {
40-
bootstrapScripts: Layout.entryJsFiles,
42+
bootstrapScripts: layoutEntry.entryJsFiles,
4143
});
4244
}
4345

44-
const handleNodeRequest = toNodeHandler((request) => handler(request));
46+
const handleNodeRequest = toNodeHandler((request) => handler(request)) as (
47+
req: IncomingMessage,
48+
res: ServerResponse<IncomingMessage>,
49+
) => void | Promise<void>;
4550

4651
function shouldBypassRequest(req: IncomingMessage) {
4752
if (!req.url) {

examples/react-router/src/entry.ssr.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { createFromReadableStream } from 'react-server-dom-rspack/client';
55

66
type PayloadPromise = Promise<RSCServerPayload> & {
77
_deepestRenderedBoundaryId?: string | null;
8-
formState?: Promise<unknown>;
8+
formState: Promise<unknown>;
99
};
1010

1111
const encoder = new TextEncoder();
@@ -20,9 +20,7 @@ function isManifestRequest(url: URL) {
2020
}
2121

2222
function escapeScript(script: string) {
23-
return script
24-
.replaceAll('<!--', '<\\!--')
25-
.replaceAll('</script', '</\\script');
23+
return script.replace(/<!--/g, '<\\!--').replace(/<\/script/g, '<\\/script');
2624
}
2725

2826
function writeChunk(

examples/react-router/src/routes/root/route.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
'use server-entry';
22

3+
import type { ServerEntry } from 'react-server-dom-rspack/server.node';
34
import { Outlet } from 'react-router';
45
import { Layout as ClientLayout } from './client';
56
import './styles.css';
67

78
export { ErrorBoundary } from './client';
89

910
export function Layout({ children }: { children: React.ReactNode }) {
11+
const layoutEntry = Layout as ServerEntry<typeof Layout>;
12+
1013
// This is required for the bundler to inject the necessary CSS assets.
1114
return (
1215
<>
13-
{
14-
// @ts-expect-error -- The plugin injects entryCssFiles on server-entry components at runtime.
15-
// Components annotated with 'use server-entry' can access the entryCssFiles property at runtime to inject CSS resources.
16-
Layout.entryCssFiles.map((href) => (
17-
<link key={href} rel="stylesheet" href={href} precedence="default" />
18-
))
19-
}
16+
{layoutEntry.entryCssFiles?.map((href) => (
17+
<link key={href} rel="stylesheet" href={href} precedence="default" />
18+
))}
2019
<ClientLayout>{children}</ClientLayout>
2120
</>
2221
);

examples/react-router/tsconfig.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
"allowImportingTsExtensions": true,
1515

1616
"noUnusedLocals": true,
17-
"noUnusedParameters": true,
18-
"typeRoots": ["./node_modules/@types", "./types"]
17+
"noUnusedParameters": true
1918
},
20-
"include": ["src"]
19+
"include": ["src", "../../types/**/*.d.ts"]
2120
}

examples/server/src/Dialog.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ export function Dialog({
1212
const ref = useRef<HTMLDialogElement | null>(null);
1313
return (
1414
<>
15-
<button onClick={() => ref.current?.showModal()}>{trigger}</button>
15+
<button type="button" onClick={() => ref.current?.showModal()}>
16+
{trigger}
17+
</button>
1618
<dialog ref={ref} onSubmit={() => ref.current?.close()}>
1719
{children}
1820
</dialog>

examples/server/tsconfig.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616

1717
/* type checking */
1818
"noUnusedLocals": true,
19-
"noUnusedParameters": true,
20-
"typeRoots": ["./node_modules/@types", "./types"]
19+
"noUnusedParameters": true
2120
},
22-
"include": ["src"]
21+
"include": ["src", "../../types/**/*.d.ts"]
2322
}

0 commit comments

Comments
 (0)