Skip to content

Commit 4f885c4

Browse files
Fix validation of split route modules for root route (#13238)
1 parent cd50dc6 commit 4f885c4

File tree

3 files changed

+70
-4
lines changed

3 files changed

+70
-4
lines changed

.changeset/cuddly-dots-hear.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@react-router/dev": patch
3+
---
4+
5+
When `future.unstable_splitRouteModules` is set to `"enforce"`, allow both splittable and unsplittable root route exports since it's always in a single chunk.

integration/split-route-modules-test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,59 @@ test.describe("Split route modules", async () => {
462462
});
463463
});
464464

465+
test.describe("splittable routes with splittable root route exports", () => {
466+
test.beforeAll(async () => {
467+
port = await getPort();
468+
cwd = await createProject({
469+
"react-router.config.ts": reactRouterConfig({ splitRouteModules }),
470+
"vite.config.js": await viteConfig.basic({ port }),
471+
"app/root.tsx": js`
472+
import { Outlet } from "react-router";
473+
export const clientLoader = () => null;
474+
export const clientAction = () => null;
475+
export default function() {
476+
return <Outlet />;
477+
}
478+
`,
479+
// Make unsplittable routes valid so the build can pass
480+
"app/routes/unsplittable.tsx": "export default function(){}",
481+
"app/routes/mixed.tsx": "export default function(){}",
482+
});
483+
});
484+
485+
test("build passes", async () => {
486+
let { status } = build({ cwd });
487+
expect(status).toBe(0);
488+
});
489+
});
490+
491+
test.describe("splittable routes with unsplittable root route exports", () => {
492+
test.beforeAll(async () => {
493+
port = await getPort();
494+
cwd = await createProject({
495+
"react-router.config.ts": reactRouterConfig({ splitRouteModules }),
496+
"vite.config.js": await viteConfig.basic({ port }),
497+
"app/root.tsx": js`
498+
import { Outlet } from "react-router";
499+
const shared = null;
500+
export const clientLoader = () => shared;
501+
export const clientAction = () => shared;
502+
export default function() {
503+
return <Outlet />;
504+
}
505+
`,
506+
// Make unsplittable routes valid so the build can pass
507+
"app/routes/unsplittable.tsx": "export default function(){}",
508+
"app/routes/mixed.tsx": "export default function(){}",
509+
});
510+
});
511+
512+
test("build passes", async () => {
513+
let { status } = build({ cwd });
514+
expect(status).toBe(0);
515+
});
516+
});
517+
465518
test.describe("unsplittable routes", () => {
466519
test.beforeAll(async () => {
467520
port = await getPort();

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3056,6 +3056,13 @@ const resolveRouteFileCode = async (
30563056
);
30573057
};
30583058

3059+
function isRootRouteModuleId(ctx: ReactRouterPluginContext, id: string) {
3060+
return (
3061+
normalizeRelativeFilePath(id, ctx.reactRouterConfig) ===
3062+
ctx.reactRouterConfig.routes.root.file
3063+
);
3064+
}
3065+
30593066
async function detectRouteChunksIfEnabled(
30603067
cache: Cache,
30613068
ctx: ReactRouterPluginContext,
@@ -3082,10 +3089,7 @@ async function detectRouteChunksIfEnabled(
30823089
// for all requests, all of its chunks would always be loaded up front during
30833090
// the initial page load. Instead of firing off multiple requests to resolve
30843091
// the root route code, we want it to be downloaded in a single request.
3085-
if (
3086-
normalizeRelativeFilePath(id, ctx.reactRouterConfig) ===
3087-
ctx.reactRouterConfig.routes.root.file
3088-
) {
3092+
if (isRootRouteModuleId(ctx, id)) {
30893093
return noRouteChunks();
30903094
}
30913095

@@ -3130,6 +3134,10 @@ function validateRouteChunks({
31303134
id: string;
31313135
valid: Record<Exclude<RouteChunkName, "main">, boolean>;
31323136
}): void {
3137+
if (isRootRouteModuleId(ctx, id)) {
3138+
return;
3139+
}
3140+
31333141
let invalidChunks = Object.entries(valid)
31343142
.filter(([_, isValid]) => !isValid)
31353143
.map(([chunkName]) => chunkName);

0 commit comments

Comments
 (0)