Skip to content

Commit 50c99a2

Browse files
Support basic build options in RSC Framework Mode (#14295)
1 parent e1d98d9 commit 50c99a2

File tree

4 files changed

+88
-32
lines changed

4 files changed

+88
-32
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { escapePath as escapePathAsGlob } from "tinyglobby";
2+
import type { ResolvedReactRouterConfig } from "../config/config";
3+
import { resolveRelativeRouteFilePath } from "./resolve-relative-route-file-path";
4+
import { getVite } from "./vite";
5+
6+
export function getOptimizeDepsEntries({
7+
entryClientFilePath,
8+
reactRouterConfig,
9+
}: {
10+
entryClientFilePath: string;
11+
reactRouterConfig: ResolvedReactRouterConfig;
12+
}) {
13+
if (!reactRouterConfig.future.unstable_optimizeDeps) {
14+
return [];
15+
}
16+
17+
const vite = getVite();
18+
const viteMajorVersion = parseInt(vite.version.split(".")[0], 10);
19+
20+
return [
21+
vite.normalizePath(entryClientFilePath),
22+
...Object.values(reactRouterConfig.routes).map((route) =>
23+
resolveRelativeRouteFilePath(route, reactRouterConfig),
24+
),
25+
].map((entry) =>
26+
// In Vite 7, the `optimizeDeps.entries` option only accepts glob patterns.
27+
// In prior versions, absolute file paths were treated differently.
28+
viteMajorVersion >= 7 ? escapePathAsGlob(entry) : entry,
29+
);
30+
}

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

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import {
5555
} from "./styles";
5656
import * as VirtualModule from "./virtual-module";
5757
import { resolveFileUrl } from "./resolve-file-url";
58+
import { resolveRelativeRouteFilePath } from "./resolve-relative-route-file-path";
5859
import { combineURLs } from "./combine-urls";
5960
import { removeExports } from "./remove-exports";
6061
import { ssrExternals } from "./ssr-externals";
@@ -79,6 +80,7 @@ import {
7980
resolveEntryFiles,
8081
configRouteToBranchRoute,
8182
} from "../config/config";
83+
import { getOptimizeDepsEntries } from "./optimize-deps-entries";
8284
import { decorateComponentExportsWithProps } from "./with-props";
8385
import validatePluginOrder from "./plugins/validate-plugin-order";
8486

@@ -263,17 +265,6 @@ const normalizeRelativeFilePath = (
263265
return vite.normalizePath(relativePath).split("?")[0];
264266
};
265267

266-
const resolveRelativeRouteFilePath = (
267-
route: RouteManifestEntry,
268-
reactRouterConfig: ResolvedReactRouterConfig,
269-
) => {
270-
let vite = getVite();
271-
let file = route.file;
272-
let fullPath = path.resolve(reactRouterConfig.appDirectory, file);
273-
274-
return vite.normalizePath(fullPath);
275-
};
276-
277268
let virtual = {
278269
serverBuild: VirtualModule.create("server-build"),
279270
serverManifest: VirtualModule.create("server-manifest"),
@@ -1177,7 +1168,6 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
11771168

11781169
// Ensure sync import of Vite works after async preload
11791170
let vite = getVite();
1180-
let viteMajorVersion = parseInt(vite.version.split(".")[0], 10);
11811171

11821172
viteUserConfig = _viteUserConfig;
11831173
viteConfigEnv = _viteConfigEnv;
@@ -1259,18 +1249,10 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
12591249
resolve: serverEnvironment.resolve,
12601250
},
12611251
optimizeDeps: {
1262-
entries: ctx.reactRouterConfig.future.unstable_optimizeDeps
1263-
? [
1264-
vite.normalizePath(ctx.entryClientFilePath),
1265-
...Object.values(ctx.reactRouterConfig.routes).map((route) =>
1266-
resolveRelativeRouteFilePath(route, ctx.reactRouterConfig),
1267-
),
1268-
].map((entry) =>
1269-
// In Vite 7, the `optimizeDeps.entries` option only accepts glob patterns.
1270-
// In prior versions, absolute file paths were treated differently.
1271-
viteMajorVersion >= 7 ? escapePathAsGlob(entry) : entry,
1272-
)
1273-
: [],
1252+
entries: getOptimizeDepsEntries({
1253+
entryClientFilePath: ctx.entryClientFilePath,
1254+
reactRouterConfig: ctx.reactRouterConfig,
1255+
}),
12741256
include: [
12751257
// Pre-bundle React dependencies to avoid React duplicates,
12761258
// even if React dependencies are not direct dependencies.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import path from "pathe";
2+
import type { ResolvedReactRouterConfig } from "../config/config";
3+
import type { RouteManifestEntry } from "../config/routes";
4+
import { getVite } from "./vite";
5+
6+
export function resolveRelativeRouteFilePath(
7+
route: RouteManifestEntry,
8+
reactRouterConfig: ResolvedReactRouterConfig,
9+
) {
10+
let vite = getVite();
11+
let file = route.file;
12+
let fullPath = path.resolve(reactRouterConfig.appDirectory, file);
13+
return vite.normalizePath(fullPath);
14+
}

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

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ import {
1313
type ResolvedReactRouterConfig,
1414
createConfigLoader,
1515
} from "../../config/config";
16+
import { preloadVite } from "../vite";
1617
import { hasDependency } from "../has-dependency";
18+
import { getOptimizeDepsEntries } from "../optimize-deps-entries";
1719
import { createVirtualRouteConfig } from "./virtual-route-config";
1820
import {
1921
transformVirtualRouteModules,
@@ -38,6 +40,7 @@ export function reactRouterRSCVitePlugin(): Vite.PluginOption[] {
3840
name: "react-router/rsc",
3941
async config(viteUserConfig, { command, mode }) {
4042
await initEsModuleLexer;
43+
await preloadVite();
4144

4245
viteCommand = command;
4346
const rootDirectory = getRootDirectory(viteUserConfig);
@@ -84,6 +87,10 @@ export function reactRouterRSCVitePlugin(): Vite.PluginOption[] {
8487
],
8588
},
8689
optimizeDeps: {
90+
entries: getOptimizeDepsEntries({
91+
entryClientFilePath: defaultEntries.client,
92+
reactRouterConfig: config,
93+
}),
8794
esbuildOptions: {
8895
jsx: "automatic",
8996
},
@@ -106,19 +113,46 @@ export function reactRouterRSCVitePlugin(): Vite.PluginOption[] {
106113
environments: {
107114
client: {
108115
build: {
109-
rollupOptions: { input: { index: virtual.clientEntry.id } },
116+
rollupOptions: {
117+
input: {
118+
index: defaultEntries.client,
119+
},
120+
},
110121
outDir: join(config.buildDirectory, "client"),
111122
},
112123
},
113124
rsc: {
114125
build: {
115-
rollupOptions: { input: { index: virtual.rscEntry.id } },
126+
rollupOptions: {
127+
input: {
128+
// We use a virtual entry here so that consumers can import
129+
// it as `virtual:react-router/unstable_rsc/rsc-entry`
130+
// without needing to know the actual file path, which is
131+
// important when using the default entries.
132+
index: defaultEntries.rsc,
133+
},
134+
output: {
135+
entryFileNames: config.serverBuildFile,
136+
format: config.serverModuleFormat,
137+
},
138+
},
116139
outDir: join(config.buildDirectory, "server"),
117140
},
118141
},
119142
ssr: {
120143
build: {
121-
rollupOptions: { input: { index: virtual.ssrEntry.id } },
144+
rollupOptions: {
145+
input: {
146+
index: defaultEntries.ssr,
147+
},
148+
output: {
149+
// Note: We don't set `entryFileNames` here because it's
150+
// considered private to the RSC environment build, and
151+
// @vitejs/plugin-rsc currently breaks if it's set to
152+
// something other than `index.js`.
153+
format: config.serverModuleFormat,
154+
},
155+
},
122156
outDir: join(config.buildDirectory, "server/__ssr_build"),
123157
},
124158
},
@@ -223,11 +257,9 @@ export function reactRouterRSCVitePlugin(): Vite.PluginOption[] {
223257
},
224258

225259
{
226-
name: "react-router/rsc/virtual-entries",
260+
name: "react-router/rsc/virtual-rsc-entry",
227261
resolveId(id) {
228262
if (id === virtual.rscEntry.id) return defaultEntries.rsc;
229-
if (id === virtual.ssrEntry.id) return defaultEntries.ssr;
230-
if (id === virtual.clientEntry.id) return defaultEntries.client;
231263
},
232264
},
233265
{
@@ -433,8 +465,6 @@ const virtual = {
433465
hmrRuntime: create("unstable_rsc/runtime"),
434466
basename: create("unstable_rsc/basename"),
435467
rscEntry: create("unstable_rsc/rsc-entry"),
436-
ssrEntry: create("unstable_rsc/ssr-entry"),
437-
clientEntry: create("unstable_rsc/client-entry"),
438468
};
439469

440470
function invalidateVirtualModules(viteDevServer: Vite.ViteDevServer) {

0 commit comments

Comments
 (0)