Skip to content

Commit fbf9d15

Browse files
review comments
1 parent 8391282 commit fbf9d15

File tree

3 files changed

+41
-18
lines changed

3 files changed

+41
-18
lines changed

.changeset/big-drinks-invite.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@react-router/dev": patch
3+
---
4+
5+
Introduce a `prerender.unstable_concurrency` option, to support running the prerendering concurrently, potentially speeding up the build.
6+
7+
RFC https://github.com/remix-run/react-router/discussions/14080
8+
fixes https://github.com/remix-run/react-router/issues/14383

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

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,18 @@ export type ReactRouterConfig = {
149149
/**
150150
* An array of URLs to prerender to HTML files at build time. Can also be a
151151
* function returning an array to dynamically generate URLs.
152+
*
153+
* `unstable_concurrency` defaults to 1, which means "no concurrency" - fully serial execution.
154+
* Setting it to a value more than 1 enables concurrent prerendering.
155+
* Setting it to a value higher than one can increase the speed of the build,
156+
* but may consume more resources, and send more concurrent requests to the
157+
* server/CMS.
152158
*/
153-
prerender?:
154-
| boolean
155-
| Array<string>
156-
| ((args: {
157-
getStaticPaths: () => string[];
158-
}) => Array<string> | Promise<Array<string>>);
159+
prerender?: PrerenderPaths
160+
| {
161+
paths: PrerenderPaths;
162+
unstable_concurrency?: number;
163+
};
159164
/**
160165
* An array of React Router plugin config presets to ease integration with
161166
* other platforms and tools.
@@ -200,6 +205,10 @@ export type ReactRouterConfig = {
200205
ssr?: boolean;
201206
};
202207

208+
export type PrerenderPaths = boolean
209+
| Array<string>
210+
| ((args: { getStaticPaths: () => string[] }) => Array<string> | Promise<Array<string>>);
211+
203212
export type ResolvedReactRouterConfig = Readonly<{
204213
/**
205214
* The absolute path to the application source directory.
@@ -226,16 +235,6 @@ export type ResolvedReactRouterConfig = Readonly<{
226235
* function returning an array to dynamically generate URLs.
227236
*/
228237
prerender: ReactRouterConfig["prerender"];
229-
/**
230-
* Defaults to 1, which means "no concurrency" - fully serial execution.
231-
* Setting it to a value more than 1 enables concurrent prerendering.
232-
* For example, prerenderConcurrency of 2 would run prerender with the
233-
* concurrency of 2 (two pages at a time).
234-
* Setting it to a value higher than one can increase the speed of the build,
235-
* but may consume more resources, and send more concurrent requests to the
236-
* server/CMS.
237-
*/
238-
prerenderConcurrency?: number;
239238
/**
240239
* Control the "Lazy Route Discovery" behavior
241240
*

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ import {
7979
createConfigLoader,
8080
resolveEntryFiles,
8181
configRouteToBranchRoute,
82+
type PrerenderPaths,
8283
} from "../config/config";
8384
import { getOptimizeDepsEntries } from "./optimize-deps-entries";
8485
import { decorateComponentExportsWithProps } from "./with-props";
@@ -2659,7 +2660,7 @@ async function handlePrerender(
26592660
}
26602661

26612662
let buildRoutes = createPrerenderRoutes(build.routes);
2662-
const { prerenderConcurrency = 1 } = reactRouterConfig
2663+
const concurrency = getPrerenderConcurrency(reactRouterConfig.prerender);
26632664
await pMap(build.prerender, async path => {
26642665
// Ensure we have a leading slash for matching
26652666
let matches = matchRoutes(buildRoutes, `/${path}/`.replace(/^\/\/+/, "/"));
@@ -2733,7 +2734,7 @@ async function handlePrerender(
27332734
: undefined,
27342735
);
27352736
}
2736-
}, { concurrency: prerenderConcurrency });
2737+
}, { concurrency });
27372738
}
27382739

27392740
function getStaticPrerenderPaths(routes: DataRouteObject[]) {
@@ -2921,6 +2922,10 @@ export async function getPrerenderPaths(
29212922
let prerenderPaths: string[] = [];
29222923
if (prerender != null && prerender !== false) {
29232924
let prerenderRoutes = createPrerenderRoutes(routes);
2925+
if (typeof prerender === "object") {
2926+
prerender = (prerender as { paths: PrerenderPaths }).paths
2927+
}
2928+
29242929
if (prerender === true) {
29252930
let { paths, paramRoutes } = getStaticPrerenderPaths(prerenderRoutes);
29262931
if (logWarning && !ssr && paramRoutes.length > 0) {
@@ -2947,6 +2952,17 @@ export async function getPrerenderPaths(
29472952
return prerenderPaths;
29482953
}
29492954

2955+
const DEFAULT_PRERENDER_CONCURRENCY = 1
2956+
2957+
function getPrerenderConcurrency(
2958+
prerender: ResolvedReactRouterConfig["prerender"],
2959+
): number {
2960+
if (typeof prerender === "object") {
2961+
return (prerender as { unstable_concurrency?: number }).unstable_concurrency || DEFAULT_PRERENDER_CONCURRENCY
2962+
}
2963+
return DEFAULT_PRERENDER_CONCURRENCY
2964+
}
2965+
29502966
// Note: Duplicated from react-router/lib/server-runtime
29512967
function groupRoutesByParentId(manifest: GenericRouteManifest) {
29522968
let routes: Record<string, Omit<RouteManifestEntry, "file">[]> = {};

0 commit comments

Comments
 (0)