Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 29 additions & 22 deletions packages/rsc/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# @hiogawa/vite-rsc

This package provides [React Server Components](https://react.dev/reference/rsc/server-components) (RSC) support for Vite.
Any feedback is welcome, please feel free to share an idea in [the discussion](https://github.com/hi-ogawa/vite-plugins/discussions/979).

## Features

Expand All @@ -22,12 +21,14 @@ npx degit hi-ogawa/vite-plugins/packages/rsc/examples/starter my-app

- [`./examples/starter`](./examples/starter)
- This example provides an in-depth overview of API with inline comments to explain how they function within RSC-powered React application.
- [`./examples/starter-cf-single`](./examples/starter-cf-single)
- [`@cloudflare/vite-plugin`](https://github.com/cloudflare/workers-sdk/tree/main/packages/vite-plugin-cloudflare) integration example with a single worker setup.
- [`./examples/react-router`](./examples/react-router)
- This demonstrates how to integrate [experimental React Router RSC API](https://remix.run/blog/rsc-preview) with this plugin. It also includes `@cloudflare/vite-plugin` integration with multi workers setup.
- This demonstrates how to integrate [experimental React Router RSC API](https://remix.run/blog/rsc-preview) with this plugin.
It also includes `@cloudflare/vite-plugin` integration.
- [`./examples/basic`](./examples/basic)
- This is mainly used for e2e testing and include various edge cases. It also uses a high level `@hiogawa/vite-rsc/extra/{rsc,ssr,browser}` API for quick setup.
- This is mainly used for e2e testing and include various advanced RSC usages (e.g. `"use cache"` example).
It also uses a high level `@hiogawa/vite-rsc/extra/{rsc,ssr,browser}` API for quick setup.
- [`./examples/ssg`](./examples/ssg)
- Static site generation (SSG) example with MDX and client components for interactivity.

## Basic Concepts

Expand Down Expand Up @@ -68,9 +69,10 @@ graph TD
- [`vite.config.ts`](./examples/starter/vite.config.ts)

```js
import rsc from "@hiogawa/vite-rsc/plugin";
import rsc from "@hiogawa/vite-rsc";
import { defineConfig } from "vite";

export default defineConfig() {
export default defineConfig({
plugins: [
// add plugin
rsc(),
Expand Down Expand Up @@ -123,7 +125,7 @@ export default defineConfig() {
},
},
},
}
});
```

- [`entry.rsc.tsx`](./examples/starter/src/framework/entry.rsc.tsx)
Expand All @@ -141,14 +143,14 @@ export default async function handler(request: Request): Promise<Response> {
if (request.url.endsWith(".rsc")) {
return new Response(rscStream, {
headers: {
'Content-type': 'text/html'
'Content-type': 'text/x-component;charset=utf-8'
}
})
});
}

// delegate to SSR environment for html rendering
// `loadSsrModule` is a helper API provided by the plugin for multi environment interaction.
const ssrEntry = await import.meta.viteRsc.loadSsrModule<typeof import("./entry.ssr.tsx")>();
// `loadModule` is a helper API provided by the plugin for multi environment interaction.
const ssrEntry = await import.meta.viteRsc.loadModule<typeof import("./entry.ssr.tsx")>("ssr", "index");
const htmlStream = await ssrEntry.handleSsr(rscStream);

// respond html
Expand Down Expand Up @@ -176,7 +178,7 @@ export async function handleSsr(rscStream: ReadableStream) {
// render html (traditional SSR)
const htmlStream = ReactDOMServer.renderToReadableStream(root, {
bootstrapScriptContent,
})
});

return htmlStream;
}
Expand All @@ -190,7 +192,7 @@ import * as ReactDOMClient from "react-dom/client";

async function main() {
// fetch and deserialize RSC stream back to React VDOM
const rscResponse = await fetch(window.location.href + ".rsc");
const rscResponse = await fetch(window.location.href + ".rsc);
const root = await ReactClient.createFromReadableStream(rscResponse.body);

// hydration (traditional CSR)
Expand Down Expand Up @@ -325,12 +327,6 @@ function __Page(props) {
export { __Page as Page }
```

Underlying transform utility is available from `@hiogawa/vite-rsc/plugin`:

```tsx
import { transformRscCssExport } from "@hiogawa/vite-rsc/plugin";
```

### available on `ssr` environment

#### `import.meta.viteRsc.loadBootstrapScriptContent("index")`
Expand Down Expand Up @@ -363,10 +359,10 @@ import.meta.hot.on("rsc:update", async () => {

## Plugin API

### `@hiogawa/vite-rsc/plugin`
### `@hiogawa/vite-rsc`

```js
import rsc from "@hiogawa/vite-rsc/plugin";
import rsc from "@hiogawa/vite-rsc";
import { defineConfig } from "vite";

export default defineConfig({
Expand Down Expand Up @@ -420,3 +416,14 @@ This is a wrapper of `react-server-dom` API and helper API to setup a minimal RS
### `@hiogawa/vite-rsc/extra/browser`

- `hydrate`

## Credits

This project builds on fundamental techniques and insights from pioneering Vite RSC implementations.
Additionally, Parcel and React Router's work on standardizing the RSC bundler/app responsibility has guided this plugin's API design:

- [Waku](https://github.com/wakujs/waku)
- [@lazarv/react-server](https://github.com/lazarv/react-server)
- [@jacob-ebey/vite-react-server-dom](https://github.com/jacob-ebey/vite-plugins/tree/main/packages/vite-react-server-dom)
- [React Router RSC](https://remix.run/blog/rsc-preview)
- [Parcel RSC](https://parceljs.org/recipes/rsc)
Loading