diff --git a/.changeset/fix-preset-future-flags.md b/.changeset/fix-preset-future-flags.md new file mode 100644 index 0000000000..58b8edc491 --- /dev/null +++ b/.changeset/fix-preset-future-flags.md @@ -0,0 +1,9 @@ +--- +"@react-router/dev": patch +--- + +Fix preset future flags being ignored during config resolution + +Fixes a bug where future flags defined by presets were completely ignored. The config resolution was incorrectly reading from `reactRouterUserConfig.future` instead of the merged `userAndPresetConfigs.future`, causing all preset-defined future flags to be lost. + +This fix ensures presets can properly enable experimental features as intended by the preset system design. \ No newline at end of file diff --git a/integration/vite-presets-test.ts b/integration/vite-presets-test.ts index 34a2c3933f..21627055da 100644 --- a/integration/vite-presets-test.ts +++ b/integration/vite-presets-test.ts @@ -114,6 +114,17 @@ const files = { }), }, + // Ensure presets can set future flags + { + name: "test-preset", + reactRouterConfig: async () => ({ + future: { + v8_middleware: true, + unstable_optimizeDeps: true, + }, + }), + }, + // Ensure presets can set buildEnd option (this is critical for Vercel support) { name: "test-preset", @@ -128,6 +139,7 @@ const files = { "export const buildManifest = " + serializeJs(buildManifest, { space: 2, unsafe: true }) + ";", "export const reactRouterConfig = " + serializeJs(reactRouterConfig, { space: 2, unsafe: true }) + ";", "export const assetsDir = " + JSON.stringify(viteConfig.build.assetsDir) + ";", + "export const futureFlags = " + JSON.stringify(reactRouterConfig.future) + ";", ].join("\\n"), "utf-8" ); @@ -229,6 +241,15 @@ test.describe("Vite / presets", async () => { "unstable_routeConfig", ]); + // Ensure future flags from presets are properly merged + expect(buildEndArgsMeta.futureFlags).toEqual({ + v8_middleware: true, + unstable_optimizeDeps: true, + unstable_splitRouteModules: false, + unstable_subResourceIntegrity: false, + unstable_viteEnvironmentApi: false, + }); + // Ensure we get a valid build manifest expect(buildEndArgsMeta.buildManifest).toEqual({ routeIdToServerBundleId: { diff --git a/packages/react-router-dev/config/config.ts b/packages/react-router-dev/config/config.ts index c0d92b2714..44f63824a0 100644 --- a/packages/react-router-dev/config/config.ts +++ b/packages/react-router-dev/config/config.ts @@ -587,15 +587,15 @@ async function resolveConfig({ } let future: FutureConfig = { - v8_middleware: reactRouterUserConfig.future?.v8_middleware ?? false, + v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false, unstable_optimizeDeps: - reactRouterUserConfig.future?.unstable_optimizeDeps ?? false, + userAndPresetConfigs.future?.unstable_optimizeDeps ?? false, unstable_splitRouteModules: - reactRouterUserConfig.future?.unstable_splitRouteModules ?? false, + userAndPresetConfigs.future?.unstable_splitRouteModules ?? false, unstable_subResourceIntegrity: - reactRouterUserConfig.future?.unstable_subResourceIntegrity ?? false, + userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false, unstable_viteEnvironmentApi: - reactRouterUserConfig.future?.unstable_viteEnvironmentApi ?? false, + userAndPresetConfigs.future?.unstable_viteEnvironmentApi ?? false, }; let reactRouterConfig: ResolvedReactRouterConfig = deepFreeze({