diff --git a/integration/action-test.ts b/integration/action-test.ts index 6f56313bd2..ab4b629573 100644 --- a/integration/action-test.ts +++ b/integration/action-test.ts @@ -7,7 +7,7 @@ import { } from "./helpers/create-fixture.js"; import type { Fixture, AppFixture } from "./helpers/create-fixture.js"; import { PlaywrightFixture, selectHtml } from "./helpers/playwright-fixture.js"; -import { type TemplateName, reactRouterConfig } from "./helpers/vite.js"; +import { type TemplateName } from "./helpers/vite.js"; const templateNames = [ "vite-5-template", @@ -31,9 +31,6 @@ test.describe("actions", () => { fixture = await createFixture({ templateName, files: { - "react-router.config.ts": reactRouterConfig({ - viteEnvironmentApi: templateName.includes("rsc"), - }), "app/routes/urlencoded.tsx": js` import { Form, useActionData } from "react-router"; diff --git a/integration/catch-boundary-data-test.ts b/integration/catch-boundary-data-test.ts index 068efecdc8..c930c23cd2 100644 --- a/integration/catch-boundary-data-test.ts +++ b/integration/catch-boundary-data-test.ts @@ -7,7 +7,7 @@ import { } from "./helpers/create-fixture.js"; import type { Fixture, AppFixture } from "./helpers/create-fixture.js"; import { PlaywrightFixture } from "./helpers/playwright-fixture.js"; -import { reactRouterConfig, type TemplateName } from "./helpers/vite.js"; +import { type TemplateName } from "./helpers/vite.js"; const templateNames = [ "vite-5-template", @@ -48,9 +48,6 @@ test.describe("ErrorBoundary (thrown responses)", () => { fixture = await createFixture({ templateName, files: { - "react-router.config.ts": reactRouterConfig({ - viteEnvironmentApi: templateName.includes("rsc"), - }), "app/root.tsx": js` import { Links, diff --git a/integration/client-data-test.ts b/integration/client-data-test.ts index c02bc20317..fa31e0c92e 100644 --- a/integration/client-data-test.ts +++ b/integration/client-data-test.ts @@ -150,7 +150,6 @@ test.describe("Client Data", () => { files: { "react-router.config.ts": reactRouterConfig({ splitRouteModules, - viteEnvironmentApi: templateName.includes("rsc"), }), "app/root.tsx": js` import { Form, Outlet, Scripts } from "react-router" diff --git a/integration/deduped-route-modules-test.ts b/integration/deduped-route-modules-test.ts index cb09d61ac4..c84d77ed49 100644 --- a/integration/deduped-route-modules-test.ts +++ b/integration/deduped-route-modules-test.ts @@ -3,11 +3,7 @@ import { test, expect } from "@playwright/test"; import { createFixture, createAppFixture } from "./helpers/create-fixture.js"; import type { Fixture, AppFixture } from "./helpers/create-fixture.js"; import { PlaywrightFixture } from "./helpers/playwright-fixture.js"; -import { - type TemplateName, - reactRouterConfig, - viteConfig, -} from "./helpers/vite.js"; +import { type TemplateName, viteConfig } from "./helpers/vite.js"; const templateNames = [ "vite-5-template", @@ -30,9 +26,6 @@ test.describe("Deduped route modules", () => { "vite.config.js": await viteConfig.basic({ templateName, }), - "react-router.config.ts": reactRouterConfig({ - viteEnvironmentApi: templateName.includes("rsc"), - }), "app/routes/client-first.a.tsx": ` import { Link } from "react-router"; diff --git a/integration/link-test.ts b/integration/link-test.ts index 658466f04c..227df7b72c 100644 --- a/integration/link-test.ts +++ b/integration/link-test.ts @@ -7,7 +7,7 @@ import { createAppFixture, } from "./helpers/create-fixture.js"; import type { Fixture, AppFixture } from "./helpers/create-fixture.js"; -import { reactRouterConfig, type TemplateName } from "./helpers/vite.js"; +import { type TemplateName } from "./helpers/vite.js"; import { PlaywrightFixture } from "./helpers/playwright-fixture.js"; const templateNames = [ @@ -42,10 +42,6 @@ test.describe("route module link export", () => { fixture = await createFixture({ templateName, files: { - "react-router.config.ts": reactRouterConfig({ - viteEnvironmentApi: templateName.includes("rsc"), - }), - "app/favicon.ico": js``, "app/guitar.jpg": js``, diff --git a/integration/mdx-test.ts b/integration/mdx-test.ts index 7c80317a47..d5a8992afa 100644 --- a/integration/mdx-test.ts +++ b/integration/mdx-test.ts @@ -7,11 +7,7 @@ import { } from "./helpers/create-fixture.js"; import type { Fixture, AppFixture } from "./helpers/create-fixture.js"; import { PlaywrightFixture } from "./helpers/playwright-fixture.js"; -import { - type TemplateName, - reactRouterConfig, - viteConfig, -} from "./helpers/vite.js"; +import { type TemplateName, viteConfig } from "./helpers/vite.js"; const templateNames = [ "vite-5-template", @@ -32,9 +28,6 @@ test.describe("MDX", () => { templateName, mdx: true, }), - "react-router.config.ts": reactRouterConfig({ - viteEnvironmentApi: templateName.includes("rsc"), - }), "app/root.tsx": js` import { Outlet, Scripts } from "react-router" diff --git a/integration/vite-basename-test.ts b/integration/vite-basename-test.ts index 53085cebf3..96c2892296 100644 --- a/integration/vite-basename-test.ts +++ b/integration/vite-basename-test.ts @@ -76,7 +76,6 @@ async function configFiles({ }) { return { "react-router.config.ts": reactRouterConfig({ - viteEnvironmentApi: templateName.includes("rsc"), basename: basename !== "/" ? basename : undefined, }), "vite.config.ts": await viteConfig.basic({ diff --git a/integration/vite-hmr-hdr-rsc-test.ts b/integration/vite-hmr-hdr-rsc-test.ts index 0fd031af35..13e7a90464 100644 --- a/integration/vite-hmr-hdr-rsc-test.ts +++ b/integration/vite-hmr-hdr-rsc-test.ts @@ -3,12 +3,7 @@ import path from "node:path"; import { expect } from "@playwright/test"; import type { Files, TemplateName } from "./helpers/vite.js"; -import { - test, - createEditor, - viteConfig, - reactRouterConfig, -} from "./helpers/vite.js"; +import { test, createEditor, viteConfig } from "./helpers/vite.js"; const templateName = "rsc-vite-framework" as const satisfies TemplateName; @@ -16,9 +11,6 @@ test.describe("Vite HMR & HDR (RSC)", () => { test("vite dev", async ({ page, dev }) => { let files: Files = async ({ port }) => ({ "vite.config.js": await viteConfig.basic({ port, templateName }), - "react-router.config.ts": reactRouterConfig({ - viteEnvironmentApi: templateName.includes("rsc"), - }), "app/routes/hmr/route.tsx": ` // imports import { Mounted } from "./route.client"; diff --git a/integration/vite-hmr-hdr-test.ts b/integration/vite-hmr-hdr-test.ts index bdd8390f46..4c5e795e8f 100644 --- a/integration/vite-hmr-hdr-test.ts +++ b/integration/vite-hmr-hdr-test.ts @@ -10,7 +10,6 @@ import { EXPRESS_SERVER, viteConfig, viteMajorTemplates, - reactRouterConfig, } from "./helpers/vite.js"; const templates = [ @@ -57,9 +56,6 @@ test.describe("Vite HMR & HDR", () => { test("vite dev", async ({ page, browserName, dev }) => { let files: Files = async ({ port }) => ({ "vite.config.js": await viteConfig.basic({ port, templateName }), - "react-router.config.ts": reactRouterConfig({ - viteEnvironmentApi: templateName.includes("rsc"), - }), "app/routes/_index.tsx": indexRoute, }); let { cwd, port } = await dev(files, templateName); @@ -70,9 +66,6 @@ test.describe("Vite HMR & HDR", () => { test.skip(templateName.includes("rsc"), "RSC is not supported"); let files: Files = async ({ port }) => ({ "vite.config.js": await viteConfig.basic({ port, templateName }), - "react-router.config.ts": reactRouterConfig({ - viteEnvironmentApi: templateName.includes("rsc"), - }), "server.mjs": EXPRESS_SERVER({ port }), "app/routes/_index.tsx": indexRoute, }); diff --git a/packages/react-router-dev/vite/build.ts b/packages/react-router-dev/vite/build.ts index 2d79aa6cb3..6a859b9664 100644 --- a/packages/react-router-dev/vite/build.ts +++ b/packages/react-router-dev/vite/build.ts @@ -48,16 +48,19 @@ export async function build(root: string, viteBuildOptions: ViteBuildOptions) { } let config = configResult.value; - let unstable_viteEnvironmentApi = config.future.unstable_viteEnvironmentApi; - let viteMajor = parseInt(vite.version.split(".")[0], 10); - if (unstable_viteEnvironmentApi && viteMajor === 5) { + let viteMajor = parseInt(vite.version.split(".")[0], 10); + if (config.future.unstable_viteEnvironmentApi && viteMajor === 5) { throw new Error( "The future.unstable_viteEnvironmentApi option is not supported in Vite 5", ); } - return await (unstable_viteEnvironmentApi + const useViteEnvironmentApi = + config.future.unstable_viteEnvironmentApi || + (await hasReactRouterRscPlugin({ root, viteBuildOptions })); + + return await (useViteEnvironmentApi ? viteAppBuild(root, viteBuildOptions) : viteBuild(root, viteBuildOptions)); } @@ -231,3 +234,27 @@ async function viteBuild( viteConfig, }); } + +async function hasReactRouterRscPlugin({ + root, + viteBuildOptions: { config, logLevel, mode }, +}: { + root: string; + viteBuildOptions: ViteBuildOptions; +}): Promise { + const vite = await import("vite"); + const viteConfig = await vite.resolveConfig( + { + configFile: config, + logLevel, + mode: mode ?? "production", + root, + }, + "build", // command + "production", // default mode + "production", // default NODE_ENV + ); + return viteConfig.plugins.some( + (plugin) => plugin?.name === "react-router/rsc", + ); +} diff --git a/playground/rsc-vite-framework/react-router.config.ts b/playground/rsc-vite-framework/react-router.config.ts index ef164520d8..8fcafa6494 100644 --- a/playground/rsc-vite-framework/react-router.config.ts +++ b/playground/rsc-vite-framework/react-router.config.ts @@ -1,7 +1,3 @@ import type { Config } from "@react-router/dev/config"; -export default { - future: { - unstable_viteEnvironmentApi: true, - }, -} satisfies Config; +export default {} satisfies Config;