Skip to content

Commit

Permalink
feat(react-server): add RouteProps.request (#189)
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa authored Mar 15, 2024
1 parent 5900928 commit e69700f
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 50 deletions.
7 changes: 7 additions & 0 deletions packages/react-server/examples/basic/e2e/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ test("use client > lib 3rd party lib", async ({ page }) => {
await page.getByText("react-wrap-balancer default import").click();
});

test("RouteProps.request", async ({ page }) => {
await page.goto("/test/other");
await page.getByText("searchParams = {}").click();
await page.getByRole("link", { name: "hello" }).click();
await page.getByText('searchParams = {"hello":""}').click();
});

async function setupCheckClientState(page: Page) {
// setup client state
await page.getByPlaceholder("test-input").fill("hello");
Expand Down
3 changes: 2 additions & 1 deletion packages/react-server/examples/basic/src/routes/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { LayoutRouteProps } from "@hiogawa/react-server/server";
import { Header } from "../components/header";
import { NavMenu } from "../components/nav-menu";

export default async function Layout(props: React.PropsWithChildren) {
export default async function Layout(props: LayoutRouteProps) {
return (
<div className="p-4 flex flex-col gap-2">
<Header />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
import { Link } from "@hiogawa/react-server/client";
import type { PageRouteProps } from "@hiogawa/react-server/server";
import { LinkInClientComponent } from "./client";

export default function Page() {
export default function Page(props: PageRouteProps) {
return (
<div className="flex flex-col gap-2">
<h4 className="font-bold">Other Page</h4>
<div>
<LinkInClientComponent />
</div>
<h5 className="font-bold">props.request</h5>
<div className="flex flex-col gap-2">
<pre className="text-sm">
searchParams ={" "}
{JSON.stringify(
Object.fromEntries(
new URL(props.request.url).searchParams.entries()
)
)}
</pre>
<div className="flex gap-2">
<Link className="antd-btn antd-btn-default px-2" href="?hello">
hello
</Link>
<Link className="antd-btn antd-btn-default px-2" href="?world">
world
</Link>
</div>
</div>
</div>
);
}
23 changes: 15 additions & 8 deletions packages/react-server/src/entry/react-server.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// @ts-ignore
import rscGlobRoutes from "virtual:rsc-glob-routes";
import { objectMapKeys } from "@hiogawa/utils";
import reactServerDomServer from "react-server-dom-webpack/server.edge";
import { generateRouteTree, matchRoute, renderMatchRoute } from "../lib/router";
Expand All @@ -11,8 +9,7 @@ import { ejectActionId } from "../lib/shared";
//

export function render({ request }: { request: Request }) {
const url = new URL(request.url);
const result = router.run(url.pathname);
const result = router.run(request);
const rscStream = reactServerDomServer.renderToReadableStream(
result.node,
createBundlerConfig()
Expand All @@ -27,14 +24,24 @@ export function render({ request }: { request: Request }) {
const router = createRouter();

function createRouter() {
const glob = rscGlobRoutes as Record<string, unknown>;
// for now hard code /src/routes as convention
const glob = import.meta.glob(
"/src/routes/**/(page|layout).(js|jsx|ts|tsx)",
{
eager: true,
}
);
const tree = generateRouteTree(
objectMapKeys(glob, (_v, k) => k.slice("/src/routes".length))
);

function run(pathname: string) {
const match = matchRoute(pathname, tree);
const node = renderMatchRoute(match, <div>Not Found: {pathname}</div>);
function run(request: Request) {
const url = new URL(request.url);
const match = matchRoute(url.pathname, tree);
const node = renderMatchRoute(
{ request, match },
<div>Not Found: {url.pathname}</div>
);
return { node, match };
}

Expand Down
10 changes: 4 additions & 6 deletions packages/react-server/src/lib/router.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { objectHas, tinyassert } from "@hiogawa/utils";
import type React from "react";

// TODO: rename to router

// cf. similar to vite-glob-routes
// https://github.com/hi-ogawa/vite-plugins/blob/c2d22f9436ef868fc413f05f243323686a7aa143/packages/vite-glob-routes/src/react-router/route-utils.ts#L15-L22

Expand Down Expand Up @@ -73,14 +71,13 @@ export function matchRoute(

// TODO: separate react code in a different file
export function renderMatchRoute(
match: MatchRouteResult,
props: RouteProps,
fallback: React.ReactNode
): React.ReactNode {
const nodes = [...match.nodes].reverse();
const props: RouteProps = { match };
const nodes = [...props.match.nodes].reverse();

let acc: React.ReactNode = fallback;
if (!match.notFound) {
if (!props.match.notFound) {
// TODO: assert?
const Page = nodes[0]?.value?.page?.default;
if (Page) {
Expand All @@ -99,6 +96,7 @@ export function renderMatchRoute(
}

interface RouteProps {
request: Request;
match: MatchRouteResult;
}

Expand Down
34 changes: 0 additions & 34 deletions packages/react-server/src/plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,30 +136,6 @@ export function vitePluginReactServer(options?: {
},
},

// expose glob import for routs
{
name: "virtual-rsc-glob-routes",
resolveId(source, _importer, _options) {
if (source === "virtual:rsc-glob-routes") {
return "\0" + source;
}
return;
},
async load(id, _options) {
if (id === "\0virtual:rsc-glob-routes") {
return /* js */ `
export default import.meta.glob(
"/src/routes/**/(page|layout).(js|jsx|ts|tsx)",
{
eager: true,
}
)
`;
}
return;
},
},

...(options?.plugins ?? []),
],
build: {
Expand Down Expand Up @@ -295,8 +271,6 @@ export function vitePluginReactServer(options?: {
];
}

// TODO: refactor ast utils

/*
transform "use client" directive
Expand Down Expand Up @@ -561,11 +535,3 @@ function vitePluginServerUseServer(): Plugin {
},
};
}

// extend types for rollup ast with node position
declare module "estree" {
interface BaseNode {
start: number;
end: number;
}
}

0 comments on commit e69700f

Please sign in to comment.