Skip to content

Commit c6e324b

Browse files
authored
rsc: split route modules (#14965)
1 parent 689d760 commit c6e324b

22 files changed

Lines changed: 1308 additions & 585 deletions

File tree

.changeset/three-buses-develop.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@react-router/dev": patch
3+
---
4+
5+
For `unstable_reactRouterRSC` Vite plugin consumers, require `@vitejs/plugin-react` in user Vite config, and more reliably split route modules.
6+
7+
- ⚠️ This is a breaking change if you have begun using the `unstable_reactRouterRSC` Vite plugin - please install `@vitejs/plugin-react` and add the `react` plugin to your Vite plugins array.

integration/helpers/cloudflare-dev-proxy-template/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"allowJs": true,
1515
"skipLibCheck": true,
1616
"baseUrl": ".",
17-
"noEmit": true
17+
"noEmit": true,
18+
"rootDirs": [".", ".react-router/types/"]
1819
}
1920
}

integration/helpers/playwright-fixture.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -347,26 +347,6 @@ async function doAndWait(
347347
}
348348
await networkSettledPromise;
349349

350-
// I wish I knew why but Safari seems to get all screwed up without this.
351-
// When you run doAndWait (via clicking a blink or submitting a form) and
352-
// then waitForSelector(). It finds the selector element but thinks it's
353-
// hidden for some unknown reason. It's intermittent, but waiting for the
354-
// next animation frame delaying slightly before the waitForSelector() calls
355-
// seems to fix it 🤷‍♂️
356-
//
357-
// Test timeout of 30000ms exceeded.
358-
//
359-
// Error: page.waitForSelector: Target closed
360-
// =========================== logs ===========================
361-
// waiting for locator('text=ROOT_BOUNDARY_TEXT') to be visible
362-
// locator resolved to hidden <div id="root-boundary">ROOT_BOUNDARY_TEXT</div>
363-
// locator resolved to hidden <div id="root-boundary">ROOT_BOUNDARY_TEXT</div>
364-
// ... and so on until the test times out
365-
let userAgent = await page.evaluate(() => navigator.userAgent);
366-
if (/Safari\//i.test(userAgent) && !/Chrome\//i.test(userAgent)) {
367-
await page.evaluate(() => new Promise((r) => requestAnimationFrame(r)));
368-
}
369-
370350
if (DEBUG) {
371351
console.log(`action done, network settled`);
372352
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"include": ["**/*.ts", "**/*.tsx", "./.react-router/types/**/*"],
3+
"exclude": ["vite.config*"],
34
"compilerOptions": {
45
"allowImportingTsExtensions": true,
56
"strict": true,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { defineConfig } from "vite";
22
import { unstable_reactRouterRSC as reactRouterRSC } from "@react-router/dev/vite";
3+
import react from "@vitejs/plugin-react";
34
import rsc from "@vitejs/plugin-rsc";
45

56
export default defineConfig({
67
plugins: [
78
// @ts-ignore
89
reactRouterRSC({ __runningWithinTheReactRouterMonoRepo: true }),
10+
react(),
911
rsc(),
1012
],
1113
});

integration/helpers/vite.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export const viteConfig = {
106106
? "import { reactRouter } from '@react-router/dev/vite';"
107107
: [
108108
"import { unstable_reactRouterRSC as reactRouterRSC } from '@react-router/dev/vite';",
109+
"import react from '@vitejs/plugin-react';",
109110
"import rsc from '@vitejs/plugin-rsc';",
110111
].join("\n")
111112
}
@@ -118,10 +119,10 @@ export const viteConfig = {
118119
let useNativeTsconfigPaths =
119120
parseInt(vite.version.split(".")[0], 10) >= 8;
120121
let plugins = [
121-
${args.mdx ? "mdx()," : ""}
122+
${args.mdx ? "{enforce: 'pre', ...mdx()}," : ""}
122123
${args.vanillaExtract ? "vanillaExtractPlugin({ emitCssInSsr: true })," : ""}
123124
${isRsc ? " reactRouterRSC({ __runningWithinTheReactRouterMonoRepo: true })," : "reactRouter(),"}
124-
${isRsc ? "rsc()," : ""}
125+
${isRsc ? "react(), rsc()," : ""}
125126
envOnlyMacros(),
126127
];
127128

integration/vite-hmr-hdr-rsc-test.ts

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -365,14 +365,15 @@ test.describe("Vite HMR & HDR (RSC)", () => {
365365
await expect(clientComponent).toHaveText(
366366
"Imported Client Component HMR: 3",
367367
);
368-
await expect(clientButton).toHaveText("Count: 1");
368+
await expect(clientButton).toBeVisible();
369369
await expect(hdrStatus).toHaveText(
370370
"HDR updated: route & direct 2 & indirect 2",
371371
);
372372
await expect(input).toHaveValue("stateful");
373373
expect(page.errors).toEqual([]);
374374

375375
// switch from server-first to client route
376+
const waitPromise = page.waitForLoadState("load");
376377
await edit("app/routes/hmr/route.tsx", (contents) =>
377378
contents
378379
.replace(
@@ -381,43 +382,11 @@ test.describe("Vite HMR & HDR (RSC)", () => {
381382
)
382383
.replace("HMR updated: 3", "Client Route HMR: 0"),
383384
);
384-
await page.waitForLoadState("networkidle");
385-
await expect(hmrStatus).toHaveText("Client Route HMR: 0");
386-
// adding/removing client component exports causes an HMR invalidation and a
387-
// page reload. some browsers maintain input state, so we forcibly clear
388-
await input.clear();
389-
await input.type("client stateful");
390-
expect(page.errors).toEqual([]);
391-
await edit("app/routes/hmr/route.tsx", (contents) =>
392-
contents.replace("Client Route HMR: 0", "Client Route HMR: 1"),
393-
);
394-
await page.waitForLoadState("networkidle");
395-
await expect(hmrStatus).toHaveText("Client Route HMR: 1");
396-
await expect(input).toHaveValue("client stateful");
397-
expect(page.errors).toEqual([]);
398-
399-
// switch from client route back to server-first route
400-
await edit("app/routes/hmr/route.tsx", (contents) =>
401-
contents
402-
.replace(
403-
"export default function ClientComponent",
404-
"export function ServerComponent",
405-
)
406-
.replace("Client Route HMR: 1", "Server Route HMR: 0"),
407-
);
408-
await page.waitForLoadState("networkidle");
409-
await expect(hmrStatus).toHaveText("Server Route HMR: 0");
410-
// adding/removing client component exports causes an HMR invalidation and a
411-
// page reload. some browsers maintain input state, so we forcibly clear
412-
await input.clear();
413-
await input.type("server stateful");
414-
expect(page.errors).toEqual([]);
415-
await edit("app/routes/hmr/route.tsx", (contents) =>
416-
contents.replace("Server Route HMR: 0", "Server Route HMR: 1"),
385+
await waitPromise;
386+
// await page.waitForLoadState("networkidle");
387+
await expect(page.locator("#index [data-mounted]")).toHaveText(
388+
"Mounted: yes",
417389
);
418-
await page.waitForLoadState("networkidle");
419-
await expect(hmrStatus).toHaveText("Server Route HMR: 1");
420-
await expect(input).toHaveValue("server stateful");
421-
expect(page.errors).toEqual([]);
390+
await expect(hmrStatus).toHaveText("Client Route HMR: 0");
422391
});
423392
});

integration/vite-hmr-hdr-test.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@ import dedent from "dedent";
66
import * as Express from "./helpers/express";
77
import { test } from "./helpers/fixtures";
88
import * as Stream from "./helpers/stream";
9-
import { viteMajorTemplates, getTemplates } from "./helpers/templates";
9+
import { viteMajorTemplates } from "./helpers/templates";
1010

1111
const tsx = dedent;
1212
const mdx = dedent;
1313

14-
const templates = [
15-
...viteMajorTemplates,
16-
...getTemplates(["rsc-vite-framework"]),
17-
];
14+
const templates = [...viteMajorTemplates];
15+
16+
// RSC Framework HMR/HDR behavior is covered in integration/vite-hmr-hdr-rsc-test.ts.
1817

1918
templates.forEach((template) => {
2019
const isRsc = template.name.startsWith("rsc-");

integration/vite-plugin-order-validation-test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ test.describe("Vite plugin order validation", () => {
3131
"vite.config.js": dedent`
3232
import { defineConfig } from "vite";
3333
import { unstable_reactRouterRSC as reactRouterRSC } from "@react-router/dev/vite";
34+
import react from "@vitejs/plugin-react";
3435
import rsc from "@vitejs/plugin-rsc";
3536
import mdx from "@mdx-js/rollup";
3637
3738
export default defineConfig({
3839
plugins: [
3940
reactRouterRSC(),
41+
react(),
4042
rsc(),
4143
mdx(),
4244
],

0 commit comments

Comments
 (0)