Skip to content

Commit

Permalink
feat: add react-server-dom-vite-example (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa authored Dec 19, 2024
1 parent ecb5541 commit ba78d17
Show file tree
Hide file tree
Showing 26 changed files with 2,333 additions and 0 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,22 @@ jobs:
- run: pnpm -C examples/react test-e2e
- run: pnpm -C examples/mpa test-e2e
- run: pnpm -C examples/ssr test-e2e

react-server-dom-vite:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./react-server-dom-vite-example
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: corepack enable
- run: pnpm i
- run: pnpm lint-check
- run: pnpm tsc
- run: pnpm exec playwright install chromium
- run: pnpm test-e2e
- run: pnpm build
- run: pnpm test-e2e-preview
4 changes: 4 additions & 0 deletions react-server-dom-vite-example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
dist
test-results
*.tsbuildinfo
16 changes: 16 additions & 0 deletions react-server-dom-vite-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Bare minimal example of `react-server-dom-vite` https://github.com/facebook/react/pull/31768

## implemented

- client component
- server action
- browser hmr
- server hmr

## to be improved

- "use client" transform
- "use server" transform
- normalize reference id
- css on server
- ...
9 changes: 9 additions & 0 deletions react-server-dom-vite-example/biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://biomejs.dev/schemas/1.8.1/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"linter": { "enabled": false }
}
93 changes: 93 additions & 0 deletions react-server-dom-vite-example/e2e/basic.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { type Page, test } from "@playwright/test";
import { createEditor } from "./helper";

test("client reference", async ({ page }) => {
await page.goto("/");
await page.getByText("[hydrated: 1]").click();
await page.getByText("Client counter: 0").click();
await page
.getByTestId("client-counter")
.getByRole("button", { name: "+" })
.click();
await page.getByText("Client counter: 1").click();
await page.reload();
await page.getByText("Client counter: 0").click();
});

test("server reference @js", async ({ page }) => {
await testServerAction(page);
});

test.describe(() => {
test.use({ javaScriptEnabled: false });
test("server reference @nojs", async ({ page }) => {
await testServerAction(page);
});
});

async function testServerAction(page: Page) {
await page.goto("/");
await page.getByText("Server counter: 0").click();
await page
.getByTestId("server-counter")
.getByRole("button", { name: "+" })
.click();
await page.getByText("Server counter: 1").click();
await page.goto("/");
await page.getByText("Server counter: 1").click();
await page
.getByTestId("server-counter")
.getByRole("button", { name: "-" })
.click();
await page.getByText("Server counter: 0").click();
}

test("client hmr @dev", async ({ page }) => {
await page.goto("/");
await page.getByText("[hydrated: 1]").click();
// client +1
await page.getByText("Client counter: 0").click();
await page
.getByTestId("client-counter")
.getByRole("button", { name: "+" })
.click();
await page.getByText("Client counter: 1").click();
// edit client
using file = createEditor("src/app/client.tsx");
file.edit((s) => s.replace("Client counter", "Client [EDIT] counter"));
await page.getByText("Client [EDIT] counter: 1").click();
});

test("server hmr @dev", async ({ page }) => {
await page.goto("/");
await page.getByText("[hydrated: 1]").click();

// server +1
await page.getByText("Server counter: 0").click();
await page
.getByTestId("server-counter")
.getByRole("button", { name: "+" })
.click();
await page.getByText("Server counter: 1").click();

// client +1
await page.getByText("Client counter: 0").click();
await page
.getByTestId("client-counter")
.getByRole("button", { name: "+" })
.click();
await page.getByText("Client counter: 1").click();

// edit server
using file = createEditor("src/app/index.tsx");
file.edit((s) => s.replace("Server counter", "Server [EDIT] counter"));
await page.getByText("Server [EDIT] counter: 1").click();
await page.getByText("Client counter: 1").click();

// server -1
await page
.getByTestId("server-counter")
.getByRole("button", { name: "-" })
.click();
await page.getByText("Server [EDIT] counter: 0").click();
});
15 changes: 15 additions & 0 deletions react-server-dom-vite-example/e2e/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import fs from "node:fs";

export function createEditor(filepath: string) {
let init = fs.readFileSync(filepath, "utf-8");
let data = init;
return {
edit(editFn: (data: string) => string) {
data = editFn(data);
fs.writeFileSync(filepath, data);
},
[Symbol.dispose]() {
fs.writeFileSync(filepath, init);
},
};
}
30 changes: 30 additions & 0 deletions react-server-dom-vite-example/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"private": true,
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build --app",
"preview": "vite preview",
"tsc": "tsc -b",
"test-e2e": "playwright test",
"test-e2e-preview": "E2E_PREVIEW=1 playwright test",
"lint": "biome check --write .",
"lint-check": "biome check ."
},
"dependencies": {
"@jacob-ebey/react-server-dom-vite": "19.0.0-experimental.14",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@playwright/test": "^1.49.1",
"@types/node": "^22.10.2",
"@types/react": "^19.0.1",
"@types/react-dom": "^19.0.1",
"@vitejs/plugin-react": "^4.3.4",
"typescript": "^5.7.2",
"vite": "6.0.3"
},
"packageManager": "[email protected]+sha512.76e2379760a4328ec4415815bcd6628dee727af3779aaa4c914e3944156c4299921a89f976381ee107d41f12cfa4b66681ca9c718f0668fa0831ed4c6d8ba56c"
}
32 changes: 32 additions & 0 deletions react-server-dom-vite-example/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { defineConfig, devices } from "@playwright/test";

const port = Number(process.env.E2E_PORT || 6174);
const isPreview = Boolean(process.env.E2E_PREVIEW);
const command = isPreview
? `pnpm preview --port ${port} --strict-port`
: `pnpm dev --port ${port} --strict-port`;

export default defineConfig({
testDir: "e2e",
use: {
trace: "on-first-retry",
},
projects: [
{
name: "chromium",
use: {
...devices["Desktop Chrome"],
viewport: null,
deviceScaleFactor: undefined,
},
},
],
webServer: {
command,
port,
},
grepInvert: isPreview ? /@dev/ : /@build/,
forbidOnly: !!process.env["CI"],
retries: process.env["CI"] ? 2 : 0,
reporter: "list",
});
Loading

0 comments on commit ba78d17

Please sign in to comment.