From 2feb39a7f218dc5722a9651632a57222bfed434e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Tue, 24 Jun 2025 11:42:12 +0200 Subject: [PATCH 1/5] fix(moduleResolution): fixed an issue with Vite's default server conditions being misapplied to `externalConditions` --- .changeset/rare-tables-smile.md | 5 +++++ contributors.yml | 1 + .../react-router-dev/vite/cloudflare-dev-proxy.ts | 11 ++++++----- packages/react-router-dev/vite/plugin.ts | 11 +++++------ 4 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 .changeset/rare-tables-smile.md diff --git a/.changeset/rare-tables-smile.md b/.changeset/rare-tables-smile.md new file mode 100644 index 0000000000..3956fd24ec --- /dev/null +++ b/.changeset/rare-tables-smile.md @@ -0,0 +1,5 @@ +--- +"@react-router/dev": patch +--- + +Fixed an issue with Vite's default server conditions being misapplied to `externalConditions`. This incorrectly enabled `module` condition for externals and broke builds with certain packages, like Emotion. diff --git a/contributors.yml b/contributors.yml index 8cbb9ba517..22ee406787 100644 --- a/contributors.yml +++ b/contributors.yml @@ -25,6 +25,7 @@ - amitdahan - AmRo045 - amsal +- Andarist - andreasottosson-polestar - andreiduca - antonmontrezor diff --git a/packages/react-router-dev/vite/cloudflare-dev-proxy.ts b/packages/react-router-dev/vite/cloudflare-dev-proxy.ts index 9d37690bf1..1f89d1edcb 100644 --- a/packages/react-router-dev/vite/cloudflare-dev-proxy.ts +++ b/packages/react-router-dev/vite/cloudflare-dev-proxy.ts @@ -59,7 +59,6 @@ export const cloudflareDevProxyVitePlugin = ( name: PLUGIN_NAME, config: async (config, configEnv) => { await preloadVite(); - const vite = getVite(); // This is a compatibility layer for Vite 5. Default conditions were // automatically added to any custom conditions in Vite 5, but Vite 6 // removed this behavior. Instead, the default conditions are overridden @@ -68,9 +67,11 @@ export const cloudflareDevProxyVitePlugin = ( // conditions arrays exported from Vite. In Vite 5, these default // conditions arrays do not exist. // https://vite.dev/guide/migration.html#default-value-for-resolve-conditions - const serverConditions: string[] = [ - ...(vite.defaultServerConditions ?? []), - ]; + // + // In addition to that, those are external conditions (do not confuse them with server conditions) + // and there is no helpful export with the default external conditions (see https://github.com/vitejs/vite/pull/20279 for more details). + // So, for now, we are hardcording the default here. + const externalConditions: string[] = ["node"]; let configResult = await loadConfig({ rootDirectory: config.root ?? process.cwd(), @@ -86,7 +87,7 @@ export const cloudflareDevProxyVitePlugin = ( return { ssr: { resolve: { - externalConditions: [...workerdConditions, ...serverConditions], + externalConditions: [...workerdConditions, ...externalConditions], }, }, }; diff --git a/packages/react-router-dev/vite/plugin.ts b/packages/react-router-dev/vite/plugin.ts index 20a8f8cff7..10ac5d9076 100644 --- a/packages/react-router-dev/vite/plugin.ts +++ b/packages/react-router-dev/vite/plugin.ts @@ -3451,8 +3451,7 @@ export async function getEnvironmentOptionsResolvers( `file:///${path.join(packageRoot, "module-sync-enabled/index.mjs")}` ); let vite = getVite(); - let viteServerConditions: string[] = [ - ...(vite.defaultServerConditions ?? []), + let baseServerLikeConditions: string[] = [ ...(moduleSyncEnabled ? ["module-sync"] : []), ]; @@ -3512,8 +3511,8 @@ export async function getEnvironmentOptionsResolvers( }): EnvironmentOptions { let conditions = viteCommand === "build" - ? viteServerConditions - : ["development", ...viteServerConditions]; + ? baseServerLikeConditions + : ["development", ...baseServerLikeConditions]; return mergeEnvironmentOptions(getBaseOptions({ viteUserConfig }), { resolve: { @@ -3522,8 +3521,8 @@ export async function getEnvironmentOptionsResolvers( ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? undefined : ssrExternals, - conditions, - externalConditions: conditions, + conditions: [...conditions, ...(vite.defaultServerConditions || [])], + externalConditions: [...conditions, "node"], }, build: { // We move SSR-only assets to client assets. Note that the From 89f1fa37cc9b0f6d2fe5d8a57c4ed6b9d0047d14 Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Mon, 7 Jul 2025 10:44:57 +1000 Subject: [PATCH 2/5] update changeset --- .changeset/rare-tables-smile.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/rare-tables-smile.md b/.changeset/rare-tables-smile.md index 3956fd24ec..d848cd7e9b 100644 --- a/.changeset/rare-tables-smile.md +++ b/.changeset/rare-tables-smile.md @@ -2,4 +2,4 @@ "@react-router/dev": patch --- -Fixed an issue with Vite's default server conditions being misapplied to `externalConditions`. This incorrectly enabled `module` condition for externals and broke builds with certain packages, like Emotion. +In `cloudflareDevProxy`, fix incorrectly configured `externalConditions` which had enabled `module` condition for externals and broke builds with certain packages, like Emotion. From 4a6e53a426a8bb7a02986968a37e30baab8a69b1 Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Mon, 7 Jul 2025 10:45:07 +1000 Subject: [PATCH 3/5] update comment --- packages/react-router-dev/vite/cloudflare-dev-proxy.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/react-router-dev/vite/cloudflare-dev-proxy.ts b/packages/react-router-dev/vite/cloudflare-dev-proxy.ts index 1f89d1edcb..88139bf606 100644 --- a/packages/react-router-dev/vite/cloudflare-dev-proxy.ts +++ b/packages/react-router-dev/vite/cloudflare-dev-proxy.ts @@ -68,9 +68,10 @@ export const cloudflareDevProxyVitePlugin = ( // conditions arrays do not exist. // https://vite.dev/guide/migration.html#default-value-for-resolve-conditions // - // In addition to that, those are external conditions (do not confuse them with server conditions) - // and there is no helpful export with the default external conditions (see https://github.com/vitejs/vite/pull/20279 for more details). - // So, for now, we are hardcording the default here. + // In addition to that, these are external conditions (do not confuse them + // with server conditions) and there is no helpful export with the default + // external conditions (see https://github.com/vitejs/vite/pull/20279 for + // more details). So, for now, we are hardcording the default here. const externalConditions: string[] = ["node"]; let configResult = await loadConfig({ From 06ea3a540b87a0ee088c12d0684bfebba18908ca Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Mon, 7 Jul 2025 10:56:00 +1000 Subject: [PATCH 4/5] update changeset --- .changeset/rare-tables-smile.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/rare-tables-smile.md b/.changeset/rare-tables-smile.md index d848cd7e9b..922e102c35 100644 --- a/.changeset/rare-tables-smile.md +++ b/.changeset/rare-tables-smile.md @@ -2,4 +2,4 @@ "@react-router/dev": patch --- -In `cloudflareDevProxy`, fix incorrectly configured `externalConditions` which had enabled `module` condition for externals and broke builds with certain packages, like Emotion. +Fix incorrectly configured `externalConditions` which had enabled `module` condition for externals and broke builds with certain packages, like Emotion. From d005142386cd92912e4d0d8ba8af7afac11512a2 Mon Sep 17 00:00:00 2001 From: Mark Dalgleish Date: Mon, 7 Jul 2025 11:11:58 +1000 Subject: [PATCH 5/5] refactor conditions --- packages/react-router-dev/vite/plugin.ts | 40 ++++++++++++++++++------ 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/packages/react-router-dev/vite/plugin.ts b/packages/react-router-dev/vite/plugin.ts index 10ac5d9076..676b945af1 100644 --- a/packages/react-router-dev/vite/plugin.ts +++ b/packages/react-router-dev/vite/plugin.ts @@ -3451,9 +3451,6 @@ export async function getEnvironmentOptionsResolvers( `file:///${path.join(packageRoot, "module-sync-enabled/index.mjs")}` ); let vite = getVite(); - let baseServerLikeConditions: string[] = [ - ...(moduleSyncEnabled ? ["module-sync"] : []), - ]; function getBaseOptions({ viteUserConfig, @@ -3509,10 +3506,35 @@ export async function getEnvironmentOptionsResolvers( }: { viteUserConfig: Vite.UserConfig; }): EnvironmentOptions { - let conditions = - viteCommand === "build" - ? baseServerLikeConditions - : ["development", ...baseServerLikeConditions]; + // We're using the module-sync condition, but Vite + // doesn't support it by default. + // See https://github.com/vitest-dev/vitest/issues/7692 + let maybeModuleSyncConditions: string[] = [ + ...(moduleSyncEnabled ? ["module-sync"] : []), + ]; + + let maybeDevelopmentConditions = + viteCommand === "build" ? [] : ["development"]; + + // This is a compatibility layer for Vite 5. Default conditions were + // automatically added to any custom conditions in Vite 5, but Vite 6 + // removed this behavior. Instead, the default conditions are overridden + // by any custom conditions. If we wish to retain the default + // conditions, we need to manually merge them using the provided default + // conditions arrays exported from Vite. In Vite 5, these default + // conditions arrays do not exist. + // https://vite.dev/guide/migration.html#default-value-for-resolve-conditions + let maybeDefaultServerConditions = vite.defaultServerConditions || []; + + // There is no helpful export with the default external conditions (see + // https://github.com/vitejs/vite/pull/20279 for more details). So, for now, + // we are hardcording the default here. + let defaultExternalConditions = ["node"]; + + let baseConditions = [ + ...maybeDevelopmentConditions, + ...maybeModuleSyncConditions, + ]; return mergeEnvironmentOptions(getBaseOptions({ viteUserConfig }), { resolve: { @@ -3521,8 +3543,8 @@ export async function getEnvironmentOptionsResolvers( ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? undefined : ssrExternals, - conditions: [...conditions, ...(vite.defaultServerConditions || [])], - externalConditions: [...conditions, "node"], + conditions: [...baseConditions, ...maybeDefaultServerConditions], + externalConditions: [...baseConditions, ...defaultExternalConditions], }, build: { // We move SSR-only assets to client assets. Note that the