Skip to content

Commit 6df9b21

Browse files
authored
Use alternative to ssrLoadModule when Vite Environment API is enabled (#13008)
1 parent f28c1d1 commit 6df9b21

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

.changeset/new-houses-hug.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+
Fix `future.unstable_viteEnvironmentApi` when the `ssr` environment has been configured by another plugin to be a custom `Vite.DevEnvironment` rather than a `Vite.RunnableDevEnvironment`

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

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ import {
6464
} from "../config/config";
6565
import * as WithProps from "./with-props";
6666

67+
export type LoadModule = (
68+
viteDevServer: Vite.ViteDevServer,
69+
url: string
70+
) => Promise<any>;
71+
6772
export async function resolveViteConfig({
6873
configFile,
6974
mode,
@@ -913,6 +918,31 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
913918
};
914919
};
915920

921+
// We use a separate environment for loading the server manifest and inlined
922+
// CSS during development. This is because "ssrLoadModule" isn't available if
923+
// the "ssr" environment has been defined by another plugin (e.g.
924+
// vite-plugin-cloudflare) as a custom Vite.DevEnvironment rather than a
925+
// Vite.RunnableDevEnvironment:
926+
// https://vite.dev/guide/api-environment-frameworks.html#runtime-agnostic-ssr
927+
const HELPER_ENVIRONMENT_NAME = "__react_router_helper__";
928+
929+
const loadModule: LoadModule = (viteDevServer, url) => {
930+
if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi) {
931+
const vite = getVite();
932+
const helperEnvironment =
933+
viteDevServer.environments[HELPER_ENVIRONMENT_NAME];
934+
935+
invariant(
936+
helperEnvironment && vite.isRunnableDevEnvironment(helperEnvironment),
937+
"Missing helper environment"
938+
);
939+
940+
return helperEnvironment.runner.import(url);
941+
}
942+
943+
return viteDevServer.ssrLoadModule(url);
944+
};
945+
916946
return [
917947
{
918948
name: "react-router",
@@ -1064,7 +1094,10 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
10641094

10651095
...(ctx.reactRouterConfig.future.unstable_viteEnvironmentApi
10661096
? {
1067-
environments,
1097+
environments: {
1098+
...environments,
1099+
[HELPER_ENVIRONMENT_NAME]: {},
1100+
},
10681101
build: {
10691102
// This isn't honored by the SSR environment config (which seems
10701103
// to be a Vite bug?) so we set it here too.
@@ -1268,6 +1301,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
12681301
cssModulesManifest,
12691302
build,
12701303
url,
1304+
loadModule,
12711305
});
12721306
},
12731307
// If an error is caught within the request handler, let Vite fix the
@@ -1944,7 +1978,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
19441978
if (route) {
19451979
// invalidate manifest on route exports change
19461980
let serverManifest = (
1947-
await server.ssrLoadModule(virtual.serverManifest.id)
1981+
await loadModule(server, virtual.serverManifest.id)
19481982
).default as ReactRouterManifest;
19491983

19501984
let oldRouteMetadata = serverManifest.routes[route.id];

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { ModuleNode, ViteDevServer } from "vite";
66
import type { ResolvedReactRouterConfig } from "../config/config";
77
import { resolveFileUrl } from "./resolve-file-url";
88
import { getVite } from "./vite";
9+
import type { LoadModule } from "./plugin";
910

1011
type ServerRouteManifest = ServerBuild["routes"];
1112
type ServerRoute = ServerRouteManifest[string];
@@ -57,11 +58,13 @@ const getStylesForFiles = async ({
5758
rootDirectory,
5859
cssModulesManifest,
5960
files,
61+
loadModule,
6062
}: {
6163
viteDevServer: ViteDevServer;
6264
rootDirectory: string;
6365
cssModulesManifest: Record<string, string>;
6466
files: string[];
67+
loadModule: LoadModule;
6568
}): Promise<string | undefined> => {
6669
let vite = getVite();
6770
let viteMajor = parseInt(vite.version.split(".")[0], 10);
@@ -111,7 +114,8 @@ const getStylesForFiles = async ({
111114
let css = isCssModulesFile(dep.file)
112115
? cssModulesManifest[dep.file]
113116
: (
114-
await viteDevServer.ssrLoadModule(
117+
await loadModule(
118+
viteDevServer,
115119
// We need the ?inline query in Vite v6 when loading CSS in SSR
116120
// since it does not expose the default export for CSS in a
117121
// server environment. This is to align with non-SSR
@@ -224,6 +228,7 @@ export const getStylesForUrl = async ({
224228
cssModulesManifest,
225229
build,
226230
url,
231+
loadModule,
227232
}: {
228233
viteDevServer: ViteDevServer;
229234
rootDirectory: string;
@@ -232,6 +237,7 @@ export const getStylesForUrl = async ({
232237
cssModulesManifest: Record<string, string>;
233238
build: ServerBuild;
234239
url: string | undefined;
240+
loadModule: LoadModule;
235241
}): Promise<string | undefined> => {
236242
if (url === undefined || url.includes("?_data=")) {
237243
return undefined;
@@ -254,6 +260,7 @@ export const getStylesForUrl = async ({
254260
// Then include any styles from the matched routes
255261
...documentRouteFiles,
256262
],
263+
loadModule,
257264
});
258265

259266
return styles;

0 commit comments

Comments
 (0)