Skip to content
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
7 changes: 7 additions & 0 deletions .changeset/vite-node-dependency-rr8-vite8.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"react-router-devtools": patch
---

Fix `Cannot find package 'vite-node'` (#261) and support React Router 8 / Vite 8.

`vite-node` is imported at runtime by the Vite plugin but was only declared as a `devDependency`, so consumers relied on it being a phantom dependency of `@react-router/dev@7`. React Router 8 dropped `vite-node` from its dependencies, which broke resolution for any project on RR8. `vite-node` is now a real `dependency` (`^5.0.0 || ^6.0.0`, covering both Vite 7 and Vite 8), and the `vite` peer range was tidied to `>=5.0.0` so it explicitly admits Vite 8 alongside React Router's existing `>=7.0.0` peer range (which already admits v8).
8 changes: 4 additions & 4 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
"i18next-http-backend": "3.0.2",
"isbot": "^5.1.27",
"pretty-cache-header": "1.0.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-i18next": "15.4.0",
"react-router": "^7.9.3",
"react-router-hono-server": "2.10.0",
Expand All @@ -70,8 +70,8 @@
"@testing-library/react": "16.3.0",
"@types/node": "24.10.0",
"@types/prompt": "1.1.9",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"@types/semver": "7.7.0",
"@types/slug": "5.0.9",
"@vitest/browser": "3.0.5",
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"local-release": "changeset version && changeset publish",
"version": "changeset version",
"test:unused": "knip",
"test:deps": "sherif -i react-router-devtools -i tailwindcss",
"test:deps": "sherif -i react-router-devtools -i tailwindcss -p react-router-v8-vite",
"watch": "pnpm run build:all && nx watch --all -- pnpm run build:all"
},
"license": "MIT",
Expand All @@ -67,7 +67,9 @@
"pnpm": {
"onlyBuiltDependencies": ["esbuild", "msw"],
"overrides": {
"react-router-devtools": "workspace:*"
"react-router-devtools": "workspace:*",
"react": "19.2.7",
"react-dom": "19.2.7"
}
},
"private": true
Expand Down
6 changes: 3 additions & 3 deletions packages/react-router-devtools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
"react": ">=17",
"react-dom": ">=17",
"react-router": ">=7.0.0",
"vite": ">=5.0.0 || >=6.0.0"
"vite": ">=5.0.0"
},
"devDependencies": {
"@react-router/dev": "7.9.5",
Expand All @@ -121,7 +121,6 @@
"tsx": "4.20.6",
"typescript": "^5.9.3",
"vite": "^7.2.2",
"vite-node": "^5.0.0",
"vitest": "3.0.5"
},
"dependencies": {
Expand All @@ -141,7 +140,8 @@
"goober": "^2.1.18",
"react-d3-tree": "^3.6.6",
"react-hotkeys-hook": "^5.2.1",
"react-tooltip": "^5.30.0"
"react-tooltip": "^5.30.0",
"vite-node": "^5.0.0 || ^6.0.0"
},
"optionalDependencies": {
"@biomejs/cli-darwin-arm64": "^2.3.5",
Expand Down
1,910 changes: 1,522 additions & 388 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions test-apps/custom-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"express": "^5.1.0",
"isbot": "^5.1.27",
"morgan": "^1.10.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-router": "^7.9.3"
},
"devDependencies": {
Expand All @@ -28,8 +28,8 @@
"@types/express-serve-static-core": "^5.0.6",
"@types/morgan": "^1.9.9",
"@types/node": "24.10.0",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"cross-env": "^7.0.3",
"postcss-import": "16.1.0",
"react-router-devtools": "*",
Expand Down
7 changes: 7 additions & 0 deletions test-apps/react-router-v8-vite/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules

/.cache
/build
/public/build
/.react-router
.env
25 changes: 25 additions & 0 deletions test-apps/react-router-v8-vite/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# react-router-v8-vite

A minimal **React Router v8 + Vite 8** framework-mode app used to verify that
[`react-router-devtools`](../../packages/react-router-devtools) works on the latest major versions.

It exists alongside [`react-router-vite`](../react-router-vite) (React Router 7 / Vite 7) so the repo
exercises both supported majors.

This example imports the devtools plugin by its **published package name**
(`react-router-devtools`) rather than a relative `dist/` path, so it exercises the real consumer
dependency-resolution path — including the `vite-node` runtime dependency that
[issue #261](https://github.com/code-forge-io/react-router-devtools/issues/261) was about.

## Run

```sh
pnpm --filter react-router-v8-vite dev
```

## Build

```sh
pnpm --filter react-router-v8-vite build
pnpm --filter react-router-v8-vite start
```
45 changes: 45 additions & 0 deletions test-apps/react-router-v8-vite/app/root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Links, Meta, type MetaFunction, Outlet, Scripts, ScrollRestoration } from "react-router"
import type { Route } from "./+types/root"

// Server middleware — exercises react-router-devtools' middleware augmentation.
const loggingMiddleware: Route.MiddlewareFunction = async ({ request }, next) => {
console.log("Server middleware - request:", request.url)
return next()
}

export const middleware: Route.MiddlewareFunction[] = [loggingMiddleware]

// Client middleware
const clientLoggingMiddleware: Route.ClientMiddlewareFunction = async ({ request }, next) => {
console.log("Client middleware - request:", request.url)
return next()
}

export const clientMiddleware: Route.ClientMiddlewareFunction[] = [clientLoggingMiddleware]

export const meta: MetaFunction = () => [
{ title: "React Router v8 + Vite 8 DevTools" },
{ name: "description", content: "React Router DevTools running on React Router v8 and Vite 8" },
]

export function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body style={{ margin: 0 }}>
{children}
<ScrollRestoration />
<Scripts />
</body>
</html>
)
}

export default function App() {
return <Outlet />
}
3 changes: 3 additions & 0 deletions test-apps/react-router-v8-vite/app/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { index, type RouteConfig } from "@react-router/dev/routes"

export default [index("routes/home.tsx")] satisfies RouteConfig
64 changes: 64 additions & 0 deletions test-apps/react-router-v8-vite/app/routes/home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useFetcher, useLoaderData, useSubmit } from "react-router"
import type { Route } from "./+types/home"

export const loader = async () => {
// A deferred promise + a BigInt exercise the devtools data/serialization viewer.
const slowPromise = new Promise((resolve) => setTimeout(() => resolve("resolved later"), 300))
return { message: "Hello from React Router v8 + Vite 8!", slowPromise, bigInt: BigInt(8) }
}

export const action = async ({ request }: Route.ActionArgs) => {
await new Promise((resolve) => setTimeout(resolve, 150))
return { method: request.method, ok: true }
}

const buttonStyle = {
padding: "0.625rem 1.25rem",
fontSize: "0.875rem",
fontWeight: 600,
color: "#ffffff",
background: "linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)",
border: "1px solid rgba(59, 130, 246, 0.3)",
borderRadius: "0.5rem",
cursor: "pointer",
}

export default function Home() {
const { message } = useLoaderData<typeof loader>()
const fetcher = useFetcher()
const submit = useSubmit()

return (
<main
style={{
fontFamily: "system-ui, -apple-system, sans-serif",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
minHeight: "100vh",
gap: "2rem",
background: "linear-gradient(135deg, #1e293b 0%, #0f172a 100%)",
color: "white",
padding: "2rem",
}}
>
<div style={{ textAlign: "center" }}>
<h1 style={{ fontSize: "clamp(2rem, 6vw, 4rem)", margin: 0 }}>
React Router DevTools
<br />
<span style={{ color: "#60a5fa" }}>on RR v8 + Vite 8</span>
</h1>
<p style={{ opacity: 0.9, marginTop: "1rem" }}>{message}</p>
</div>
<div style={{ display: "flex", gap: "0.75rem", flexWrap: "wrap", justifyContent: "center" }}>
<button type="button" style={buttonStyle} onClick={() => fetcher.submit(null, { method: "get" })}>
Fetcher loader
</button>
<button type="button" style={buttonStyle} onClick={() => submit(null, { method: "post" })}>
Submit action
</button>
</div>
</main>
)
}
2 changes: 2 additions & 0 deletions test-apps/react-router-v8-vite/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// <reference types="@react-router/node" />
/// <reference types="vite/client" />
31 changes: 31 additions & 0 deletions test-apps/react-router-v8-vite/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "react-router-v8-vite",
"private": true,
"sideEffects": false,
"type": "module",
"scripts": {
"build": "react-router build",
"dev": "react-router dev",
"start": "react-router-serve ./build/server/index.js",
"typecheck": "react-router typegen && tsc"
},
"dependencies": {
"@react-router/node": "^8.0.1",
"@react-router/serve": "^8.0.1",
"isbot": "^5.1.27",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-router": "^8.0.1"
},
"devDependencies": {
"@react-router/dev": "^8.0.1",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"react-router-devtools": "workspace:*",
"typescript": "^5.9.3",
"vite": "^8.0.16"
},
"engines": {
"node": ">=20.19.0"
}
}
7 changes: 7 additions & 0 deletions test-apps/react-router-v8-vite/react-router.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { Config } from "@react-router/dev/config"

// React Router v8: route middleware is stable and enabled by default,
// so no future flags are required here.
export default {
ssr: true,
} satisfies Config
23 changes: 23 additions & 0 deletions test-apps/react-router-v8-vite/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"include": ["env.d.ts", "**/*.ts", "**/*.tsx", ".react-router/types/**/*"],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2022"],
"isolatedModules": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"module": "ESNext",
"moduleResolution": "Bundler",
"resolveJsonModule": true,
"target": "ES2022",
"strict": true,
"skipLibCheck": true,
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"~/*": ["./app/*"]
},
"rootDirs": [".", "./.react-router/types"],
"noEmit": true
}
}
24 changes: 24 additions & 0 deletions test-apps/react-router-v8-vite/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { reactRouter } from "@react-router/dev/vite"
import { defineRdtConfig, reactRouterDevTools } from "react-router-devtools"
import { defineConfig } from "vite"

// Import the devtools plugin by its published package name (not a relative dist path)
// so this example exercises the real consumer resolution path — including the
// `vite-node` dependency that issue #261 was about.
const config = defineRdtConfig({
includeInProd: {
client: true,
server: true,
},
server: {
serverTimingThreshold: 250,
},
})

export default defineConfig({
plugins: [reactRouterDevTools(config), reactRouter()],
server: {
open: true,
port: 3001,
},
})
8 changes: 4 additions & 4 deletions test-apps/react-router-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
"@react-router/node": "7.9.5",
"@react-router/serve": "7.9.5",
"isbot": "^5.1.27",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-router": "^7.9.3"
},
"devDependencies": {
"@react-router/fs-routes": "7.9.3",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"eslint": "^9.19.0",
"react-router-devtools": "^6.2.1",
"typescript": "^5.9.3",
Expand Down
Loading