Skip to content

Commit 0ee1d14

Browse files
Fix root route pre-bundle warnings in RSC Framework Mode (#14315)
1 parent 11e28a9 commit 0ee1d14

File tree

5 files changed

+54
-16
lines changed

5 files changed

+54
-16
lines changed

integration/vite-presets-test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ test.describe("Vite / presets", async () => {
226226
"serverBundles",
227227
"serverModuleFormat",
228228
"ssr",
229+
"unstable_rootRouteFile",
229230
"unstable_routeConfig",
230231
]);
231232

packages/react-router-dev/config/config.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,10 @@ export type ResolvedReactRouterConfig = Readonly<{
264264
* SPA without server-rendering. Default's to `true`.
265265
*/
266266
ssr: boolean;
267+
/**
268+
* The absolute path to the root route file.
269+
*/
270+
unstable_rootRouteFile: string;
267271
/**
268272
* The resolved array of route config entries exported from `routes.ts`
269273
*/
@@ -345,6 +349,8 @@ type Result<T> =
345349
error: string;
346350
};
347351

352+
type ConfigResult = Result<ResolvedReactRouterConfig>;
353+
348354
function ok<T>(value: T): Result<T> {
349355
return { ok: true, value };
350356
}
@@ -365,7 +371,7 @@ async function resolveConfig({
365371
reactRouterConfigFile?: string;
366372
skipRoutes?: boolean;
367373
validateConfig?: ValidateConfigFunction;
368-
}): Promise<Result<ResolvedReactRouterConfig>> {
374+
}): Promise<ConfigResult> {
369375
let reactRouterUserConfig: ReactRouterConfig = {};
370376

371377
if (reactRouterConfigFile) {
@@ -506,7 +512,7 @@ async function resolveConfig({
506512
let appDirectory = Path.resolve(root, userAppDirectory || "app");
507513
let buildDirectory = Path.resolve(root, userBuildDirectory);
508514

509-
let rootRouteFile = findEntry(appDirectory, "root");
515+
let rootRouteFile = findEntry(appDirectory, "root", { absolute: true });
510516
if (!rootRouteFile) {
511517
let rootRouteDisplayPath = Path.relative(
512518
root,
@@ -556,7 +562,7 @@ async function resolveConfig({
556562
{
557563
id: "root",
558564
path: "",
559-
file: rootRouteFile,
565+
file: Path.relative(appDirectory, rootRouteFile),
560566
children: result.routeConfig,
561567
},
562568
];
@@ -609,6 +615,7 @@ async function resolveConfig({
609615
serverBundles,
610616
serverModuleFormat,
611617
ssr,
618+
unstable_rootRouteFile: rootRouteFile,
612619
unstable_routeConfig: routeConfig,
613620
} satisfies ResolvedReactRouterConfig);
614621

@@ -622,7 +629,7 @@ async function resolveConfig({
622629
type ChokidarEventName = ChokidarEmitArgs[0];
623630

624631
type ChangeHandler = (args: {
625-
result: Result<ResolvedReactRouterConfig>;
632+
result: ConfigResult;
626633
configCodeChanged: boolean;
627634
routeConfigCodeChanged: boolean;
628635
configChanged: boolean;
@@ -632,7 +639,7 @@ type ChangeHandler = (args: {
632639
}) => void;
633640

634641
export type ConfigLoader = {
635-
getConfig: () => Promise<Result<ResolvedReactRouterConfig>>;
642+
getConfig: () => Promise<ConfigResult>;
636643
onChange: (handler: ChangeHandler) => () => void;
637644
close: () => Promise<void>;
638645
};

packages/react-router-dev/vite/rsc/plugin.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ export function reactRouterRSCVitePlugin(): Vite.PluginOption[] {
315315
id,
316316
viteCommand,
317317
routeIdByFile,
318+
rootRouteFile: config.unstable_rootRouteFile,
318319
viteEnvironment: this.environment,
319320
});
320321
},

packages/react-router-dev/vite/rsc/virtual-route-config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export function createVirtualRouteConfig({
2828
const routeId = route.id || createRouteId(route.file, appDirectory);
2929
routeIdByFile.set(routeFile, routeId);
3030
code += `lazy: () => import(${JSON.stringify(
31-
`${routeFile}?route-module${routeId === "root" ? "&root-route=true" : ""}`,
31+
`${routeFile}?route-module`,
3232
)}),`;
3333

3434
code += `id: ${JSON.stringify(routeId)},`;

packages/react-router-dev/vite/rsc/virtual-route-modules.ts

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,40 +97,54 @@ export function transformVirtualRouteModules({
9797
code,
9898
viteCommand,
9999
routeIdByFile,
100+
rootRouteFile,
100101
viteEnvironment,
101102
}: {
102103
id: string;
103104
code: string;
104105
viteCommand: ViteCommand;
105106
routeIdByFile: Map<string, string>;
107+
rootRouteFile: string;
106108
viteEnvironment: Vite.Environment;
107109
}) {
108110
if (isVirtualRouteModuleId(id) || routeIdByFile.has(id)) {
109111
return createVirtualRouteModuleCode({
110112
id,
111113
code,
114+
rootRouteFile,
112115
viteCommand,
113116
viteEnvironment,
114117
});
115118
}
116119

117120
if (isVirtualServerRouteModuleId(id)) {
118-
return createVirtualServerRouteModuleCode({ id, code, viteEnvironment });
121+
return createVirtualServerRouteModuleCode({
122+
id,
123+
code,
124+
viteEnvironment,
125+
});
119126
}
120127

121128
if (isVirtualClientRouteModuleId(id)) {
122-
return createVirtualClientRouteModuleCode({ id, code, viteCommand });
129+
return createVirtualClientRouteModuleCode({
130+
id,
131+
code,
132+
rootRouteFile,
133+
viteCommand,
134+
});
123135
}
124136
}
125137

126138
async function createVirtualRouteModuleCode({
127139
id,
128140
code: routeSource,
141+
rootRouteFile,
129142
viteCommand,
130143
viteEnvironment,
131144
}: {
132145
id: string;
133146
code: string;
147+
rootRouteFile: string;
134148
viteCommand: ViteCommand;
135149
viteEnvironment: Vite.Environment;
136150
}) {
@@ -183,7 +197,10 @@ async function createVirtualRouteModuleCode({
183197
}
184198
}
185199

186-
if (isRootRouteId(id) && !staticExports.includes("ErrorBoundary")) {
200+
if (
201+
isRootRouteFile({ id, rootRouteFile }) &&
202+
!staticExports.includes("ErrorBoundary")
203+
) {
187204
code += `export { ErrorBoundary } from "${clientModuleId}";\n`;
188205
}
189206

@@ -236,10 +253,12 @@ function createVirtualServerRouteModuleCode({
236253
function createVirtualClientRouteModuleCode({
237254
id,
238255
code: routeSource,
256+
rootRouteFile,
239257
viteCommand,
240258
}: {
241259
id: string;
242260
code: string;
261+
rootRouteFile: string;
243262
viteCommand: ViteCommand;
244263
}) {
245264
const { staticExports, isServerFirstRoute, hasClientExports } =
@@ -256,7 +275,10 @@ function createVirtualClientRouteModuleCode({
256275
const generatorResult = babel.generate(clientRouteModuleAst);
257276
generatorResult.code = '"use client";' + generatorResult.code;
258277

259-
if (isRootRouteId(id) && !staticExports.includes("ErrorBoundary")) {
278+
if (
279+
isRootRouteFile({ id, rootRouteFile }) &&
280+
!staticExports.includes("ErrorBoundary")
281+
) {
260282
const hasRootLayout = staticExports.includes("Layout");
261283
generatorResult.code += `\nimport { createElement as __rr_createElement } from "react";\n`;
262284
generatorResult.code += `import { UNSAFE_RSCDefaultRootErrorBoundary } from "react-router";\n`;
@@ -288,15 +310,11 @@ export function parseRouteExports(code: string) {
288310
}
289311

290312
function getVirtualClientModuleId(id: string): string {
291-
return `${id.split("?")[0]}?client-route-module${isRootRouteId(id) ? "&root-route=true" : ""}`;
313+
return `${id.split("?")[0]}?client-route-module`;
292314
}
293315

294316
function getVirtualServerModuleId(id: string): string {
295-
return `${id.split("?")[0]}?server-route-module${isRootRouteId(id) ? "&root-route=true" : ""}`;
296-
}
297-
298-
function isRootRouteId(id: string): boolean {
299-
return /(\?|&)root-route=true(&|$)/.test(id);
317+
return `${id.split("?")[0]}?server-route-module`;
300318
}
301319

302320
function isVirtualRouteModuleId(id: string): boolean {
@@ -310,3 +328,14 @@ export function isVirtualClientRouteModuleId(id: string): boolean {
310328
function isVirtualServerRouteModuleId(id: string): boolean {
311329
return /(\?|&)server-route-module(&|$)/.test(id);
312330
}
331+
332+
function isRootRouteFile({
333+
id,
334+
rootRouteFile,
335+
}: {
336+
id: string;
337+
rootRouteFile: string;
338+
}): boolean {
339+
const filePath = id.split("?")[0];
340+
return filePath === rootRouteFile;
341+
}

0 commit comments

Comments
 (0)