Skip to content

Remove Vite server hooks in child compiler plugins #13184

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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/eleven-oranges-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@react-router/dev": patch
---

Fix conflicts with other Vite plugins that use the `configureServer` and/or `configurePreviewServer` hooks
31 changes: 27 additions & 4 deletions packages/react-router-dev/vite/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1349,6 +1349,10 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
}
}

const childCompilerPlugins = await asyncFlatten(
childCompilerConfigFile.config.plugins ?? []
);

viteChildCompiler = await vite.createServer({
...viteUserConfig,
// Ensure child compiler cannot overwrite the default cache directory
Expand All @@ -1362,8 +1366,7 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
configFile: false,
envFile: false,
plugins: [
...(childCompilerConfigFile.config.plugins ?? [])
.flat()
childCompilerPlugins
// Exclude this plugin from the child compiler to prevent an
// infinite loop (plugin creates a child compiler with the same
// plugin that creates another child compiler, repeat ad
Expand All @@ -1372,14 +1375,20 @@ export const reactRouterVitePlugin: ReactRouterVitePlugin = () => {
// production build because the child compiler is a Vite dev
// server and will generate incorrect manifests.
.filter(
(plugin) =>
(plugin): plugin is Vite.Plugin =>
typeof plugin === "object" &&
plugin !== null &&
"name" in plugin &&
plugin.name !== "react-router" &&
plugin.name !== "react-router:route-exports" &&
plugin.name !== "react-router:hmr-updates"
),
)
// Remove server hooks to avoid conflicts with main dev server
.map((plugin) => ({
...plugin,
configureServer: undefined,
configurePreviewServer: undefined,
})),
{
name: "react-router:override-optimize-deps",
config(userConfig) {
Expand Down Expand Up @@ -3497,3 +3506,17 @@ async function getEnvironmentsOptions(
function isNonNullable<T>(x: T): x is NonNullable<T> {
return x != null;
}

// Type and function copied from Vite
type AsyncFlatten<T extends unknown[]> = T extends (infer U)[]
? Exclude<Awaited<U>, U[]>[]
: never;

async function asyncFlatten<T extends unknown[]>(
arr: T
): Promise<AsyncFlatten<T>> {
do {
arr = (await Promise.all(arr)).flat(Infinity) as any;
} while (arr.some((v: any) => v?.then));
return arr as unknown[] as AsyncFlatten<T>;
}
Loading