Skip to content

Commit edb5fbe

Browse files
Skip unused routes.ts eval before Vite build (#13513)
1 parent 034c0ef commit edb5fbe

File tree

3 files changed

+77
-54
lines changed

3 files changed

+77
-54
lines changed

.changeset/ten-pears-wash.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+
Skip unnecessary `routes.ts` evaluation before Vite build is started

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

Lines changed: 69 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -350,10 +350,12 @@ async function resolveConfig({
350350
root,
351351
viteNodeContext,
352352
reactRouterConfigFile,
353+
skipRoutes,
353354
}: {
354355
root: string;
355356
viteNodeContext: ViteNode.Context;
356357
reactRouterConfigFile?: string;
358+
skipRoutes?: boolean;
357359
}): Promise<Result<ResolvedReactRouterConfig>> {
358360
let reactRouterUserConfig: ReactRouterConfig = {};
359361

@@ -499,61 +501,67 @@ async function resolveConfig({
499501
);
500502
}
501503

502-
let routes: RouteManifest = {
503-
root: { path: "", id: "root", file: rootRouteFile },
504-
};
504+
let routes: RouteManifest = {};
505505

506-
let routeConfigFile = findEntry(appDirectory, "routes");
506+
if (!skipRoutes) {
507+
routes = {
508+
root: { path: "", id: "root", file: rootRouteFile },
509+
};
507510

508-
try {
509-
if (!routeConfigFile) {
510-
let routeConfigDisplayPath = Path.relative(
511-
root,
512-
Path.join(appDirectory, "routes.ts")
513-
);
514-
return err(`Route config file not found at "${routeConfigDisplayPath}".`);
515-
}
511+
let routeConfigFile = findEntry(appDirectory, "routes");
516512

517-
setAppDirectory(appDirectory);
518-
let routeConfigExport = (
519-
await viteNodeContext.runner.executeFile(
520-
Path.join(appDirectory, routeConfigFile)
521-
)
522-
).default;
523-
let routeConfig = await routeConfigExport;
524-
525-
let result = validateRouteConfig({
526-
routeConfigFile,
527-
routeConfig,
528-
});
513+
try {
514+
if (!routeConfigFile) {
515+
let routeConfigDisplayPath = Path.relative(
516+
root,
517+
Path.join(appDirectory, "routes.ts")
518+
);
519+
return err(
520+
`Route config file not found at "${routeConfigDisplayPath}".`
521+
);
522+
}
529523

530-
if (!result.valid) {
531-
return err(result.message);
532-
}
524+
setAppDirectory(appDirectory);
525+
let routeConfigExport = (
526+
await viteNodeContext.runner.executeFile(
527+
Path.join(appDirectory, routeConfigFile)
528+
)
529+
).default;
530+
let routeConfig = await routeConfigExport;
531+
532+
let result = validateRouteConfig({
533+
routeConfigFile,
534+
routeConfig,
535+
});
533536

534-
routes = {
535-
...routes,
536-
...configRoutesToRouteManifest(appDirectory, routeConfig),
537-
};
538-
} catch (error: any) {
539-
return err(
540-
[
541-
colors.red(`Route config in "${routeConfigFile}" is invalid.`),
542-
"",
543-
error.loc?.file && error.loc?.column && error.frame
544-
? [
545-
Path.relative(appDirectory, error.loc.file) +
546-
":" +
547-
error.loc.line +
548-
":" +
549-
error.loc.column,
550-
error.frame.trim?.(),
551-
]
552-
: error.stack,
553-
]
554-
.flat()
555-
.join("\n")
556-
);
537+
if (!result.valid) {
538+
return err(result.message);
539+
}
540+
541+
routes = {
542+
...routes,
543+
...configRoutesToRouteManifest(appDirectory, routeConfig),
544+
};
545+
} catch (error: any) {
546+
return err(
547+
[
548+
colors.red(`Route config in "${routeConfigFile}" is invalid.`),
549+
"",
550+
error.loc?.file && error.loc?.column && error.frame
551+
? [
552+
Path.relative(appDirectory, error.loc.file) +
553+
":" +
554+
error.loc.line +
555+
":" +
556+
error.loc.column,
557+
error.frame.trim?.(),
558+
]
559+
: error.stack,
560+
]
561+
.flat()
562+
.join("\n")
563+
);
564+
}
557565
}
558566

559567
let future: FutureConfig = {
@@ -613,10 +621,12 @@ export async function createConfigLoader({
613621
rootDirectory: root,
614622
watch,
615623
mode,
624+
skipRoutes,
616625
}: {
617626
watch: boolean;
618627
rootDirectory?: string;
619628
mode: string;
629+
skipRoutes?: boolean;
620630
}): Promise<ConfigLoader> {
621631
root = Path.normalize(root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd());
622632

@@ -641,7 +651,7 @@ export async function createConfigLoader({
641651
updateReactRouterConfigFile();
642652

643653
let getConfig = () =>
644-
resolveConfig({ root, viteNodeContext, reactRouterConfigFile });
654+
resolveConfig({ root, viteNodeContext, reactRouterConfigFile, skipRoutes });
645655

646656
let appDirectory: string;
647657

@@ -740,9 +750,11 @@ export async function createConfigLoader({
740750
filepath
741751
));
742752

743-
let routeConfigFile = findEntry(appDirectory, "routes", {
744-
absolute: true,
745-
});
753+
let routeConfigFile = !skipRoutes
754+
? findEntry(appDirectory, "routes", {
755+
absolute: true,
756+
})
757+
: undefined;
746758
let routeConfigCodeChanged =
747759
routeConfigFile !== undefined &&
748760
isEntryFileDependency(
@@ -793,13 +805,16 @@ export async function createConfigLoader({
793805
export async function loadConfig({
794806
rootDirectory,
795807
mode,
808+
skipRoutes,
796809
}: {
797810
rootDirectory: string;
798811
mode: string;
812+
skipRoutes?: boolean;
799813
}) {
800814
let configLoader = await createConfigLoader({
801815
rootDirectory,
802816
mode,
817+
skipRoutes,
803818
watch: false,
804819
});
805820
let config = await configLoader.getConfig();

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ export async function build(root: string, viteBuildOptions: ViteBuildOptions) {
3838
let configResult = await loadConfig({
3939
rootDirectory: root,
4040
mode: viteBuildOptions.mode ?? "production",
41+
// In this scope we only need future flags, so we can skip evaluating
42+
// routes.ts until we're within the Vite build context
43+
skipRoutes: true,
4144
});
4245

4346
if (!configResult.ok) {

0 commit comments

Comments
 (0)