Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/ignore-external-vite-server-environments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@react-router/dev": patch
---

Avoid running React Router's server build cleanup hooks for unrelated Vite server environments when `future.v8_viteEnvironmentApi` is enabled.
1 change: 1 addition & 0 deletions contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@
- pyitphyoaung
- qu0b
- QzCurious
- raashish1601
- redabacha
- refusado
- remorses
Expand Down
56 changes: 56 additions & 0 deletions packages/react-router-dev/__tests__/vite-plugin-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {
getServerEnvironmentKeys,
isReactRouterServerEnvironmentName,
} from "../vite/plugin";

describe("React Router Vite server environment detection", () => {
it("only treats ssr as a React Router server environment without server bundles", () => {
let ctx = {
buildManifest: {
routes: {},
},
} as any;

expect(isReactRouterServerEnvironmentName(ctx, "ssr")).toBe(true);
expect(isReactRouterServerEnvironmentName(ctx, "client")).toBe(false);
expect(isReactRouterServerEnvironmentName(ctx, "nitro")).toBe(false);

expect(
getServerEnvironmentKeys(ctx, {
client: {},
ssr: {},
nitro: {},
}),
).toEqual(["ssr"]);
});

it("ignores external server environments when server bundles are enabled", () => {
let ctx = {
buildManifest: {
routes: {},
routeIdToServerBundleId: {},
serverBundles: {
admin: {
id: "admin",
file: "build/server/admin/index.js",
},
},
},
} as any;

expect(isReactRouterServerEnvironmentName(ctx, "ssrBundle_admin")).toBe(
true,
);
expect(isReactRouterServerEnvironmentName(ctx, "ssr")).toBe(false);
expect(isReactRouterServerEnvironmentName(ctx, "nitro")).toBe(false);

expect(
getServerEnvironmentKeys(ctx, {
client: {},
ssr: {},
ssrBundle_admin: {},
nitro: {},
}),
).toEqual(["ssrBundle_admin"]);
});
});
26 changes: 15 additions & 11 deletions packages/react-router-dev/vite/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,21 @@ export type EnvironmentBuildContext = {
resolveOptions: EnvironmentOptionsResolver;
};

export function isReactRouterServerEnvironmentName(
ctx: Pick<ReactRouterPluginContext, "buildManifest">,
name: string,
): name is SsrEnvironmentName {
return ctx.buildManifest?.serverBundles
? isSsrBundleEnvironmentName(name)
: name === "ssr";
}

function getServerEnvironmentEntries<T>(
ctx: ReactRouterPluginContext,
record: Record<string, T>,
): [SsrEnvironmentName, T][] {
return Object.entries(record).filter(([name]) =>
ctx.buildManifest?.serverBundles
? isSsrBundleEnvironmentName(name)
: name === "ssr",
isReactRouterServerEnvironmentName(ctx, name),
) as [SsrEnvironmentName, T][];
}

Expand Down Expand Up @@ -1458,9 +1465,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
configEnvironment(name, options) {
if (
ctx.reactRouterConfig.future.v8_viteEnvironmentApi &&
(ctx.buildManifest?.serverBundles
? isSsrBundleEnvironmentName(name)
: name === "ssr")
isReactRouterServerEnvironmentName(ctx, name)
) {
const vite = getVite();

Expand Down Expand Up @@ -1855,12 +1860,11 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
// the SSR build and move server-only assets to client assets directory
async handler() {
let { future } = ctx.reactRouterConfig;
let isReactRouterServerBuild = future.v8_viteEnvironmentApi
? isReactRouterServerEnvironmentName(ctx, this.environment.name)
: viteConfigEnv.isSsrBuild;

if (
future.v8_viteEnvironmentApi
? this.environment.name === "client"
: !viteConfigEnv.isSsrBuild
) {
if (!isReactRouterServerBuild) {
return;
}
invariant(viteConfig);
Expand Down
Loading