diff --git a/.changeset/lucky-fireants-sip.md b/.changeset/lucky-fireants-sip.md new file mode 100644 index 0000000000..2a855bb4d3 --- /dev/null +++ b/.changeset/lucky-fireants-sip.md @@ -0,0 +1,5 @@ +--- +"@react-router/dev": patch +--- + +Use `vite` instead of `vite-node` to load configuraiton file diff --git a/contributors.yml b/contributors.yml index 0042fd098f..362a84ebda 100644 --- a/contributors.yml +++ b/contributors.yml @@ -453,6 +453,7 @@ - vikingviolinist - vishwast03 - vitekzach +- vixalien - vladinator1000 - vonagam - WalkAlone0325 diff --git a/packages/react-router-dev/config/config.ts b/packages/react-router-dev/config/config.ts index 7caf7ed27d..58a21eea14 100644 --- a/packages/react-router-dev/config/config.ts +++ b/packages/react-router-dev/config/config.ts @@ -1,6 +1,6 @@ import fs from "node:fs"; import { execSync } from "node:child_process"; -import * as ViteNode from "../vite/vite-node"; +import * as ViteRunner from "../vite/vite-runner"; import type * as Vite from "vite"; import Path from "pathe"; import chokidar, { @@ -422,13 +422,13 @@ function err(error: string): Result { async function resolveConfig({ root, - viteNodeContext, + viteRunnerContext, reactRouterConfigFile, skipRoutes, validateConfig, }: { root: string; - viteNodeContext: ViteNode.Context; + viteRunnerContext: ViteRunner.Context; reactRouterConfigFile?: string; skipRoutes?: boolean; validateConfig?: ValidateConfigFunction; @@ -441,7 +441,7 @@ async function resolveConfig({ return err(`${reactRouterConfigFile} no longer exists`); } - let configModule = await viteNodeContext.runner.executeFile( + let configModule = await viteRunnerContext.env.runner.import( reactRouterConfigFile, ); @@ -623,7 +623,7 @@ async function resolveConfig({ setAppDirectory(appDirectory); let routeConfigExport = ( - await viteNodeContext.runner.executeFile( + await viteRunnerContext.env.runner.import( Path.join(appDirectory, routeConfigFile), ) ).default; @@ -761,7 +761,7 @@ export async function createConfigLoader({ root = Path.normalize(root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd()); let vite = await import("vite"); - let viteNodeContext = await ViteNode.createContext({ + let viteRunnerContext = await ViteRunner.createContext({ root, mode, // Filter out any info level logs from vite-node @@ -783,7 +783,7 @@ export async function createConfigLoader({ let getConfig = () => resolveConfig({ root, - viteNodeContext, + viteRunnerContext, reactRouterConfigFile, skipRoutes, validateConfig, @@ -854,7 +854,7 @@ export async function createConfigLoader({ let moduleGraphChanged = configFileAddedOrRemoved || Boolean( - viteNodeContext.devServer?.moduleGraph.getModuleById(filepath), + viteRunnerContext.server?.moduleGraph.getModuleById(filepath), ); // Bail out if no relevant changes detected @@ -862,8 +862,8 @@ export async function createConfigLoader({ return; } - viteNodeContext.devServer?.moduleGraph.invalidateAll(); - viteNodeContext.runner?.moduleCache.clear(); + viteRunnerContext.server?.moduleGraph.invalidateAll(); + viteRunnerContext.env?.runner.clearCache(); let result = await getConfig(); @@ -881,7 +881,7 @@ export async function createConfigLoader({ configFileAddedOrRemoved || (reactRouterConfigFile !== undefined && isEntryFileDependency( - viteNodeContext.devServer.moduleGraph, + viteRunnerContext.server.moduleGraph, reactRouterConfigFile, filepath, )); @@ -894,7 +894,7 @@ export async function createConfigLoader({ let routeConfigCodeChanged = routeConfigFile !== undefined && isEntryFileDependency( - viteNodeContext.devServer.moduleGraph, + viteRunnerContext.server.moduleGraph, routeConfigFile, filepath, ); @@ -932,7 +932,7 @@ export async function createConfigLoader({ }, close: async () => { changeHandlers = []; - await viteNodeContext.devServer.close(); + await viteRunnerContext.server.close(); await fsWatcher?.close(); }, }; diff --git a/packages/react-router-dev/package.json b/packages/react-router-dev/package.json index cbd36e9bd5..dad0b55fc1 100644 --- a/packages/react-router-dev/package.json +++ b/packages/react-router-dev/package.json @@ -95,8 +95,7 @@ "react-refresh": "^0.14.0", "semver": "^7.3.7", "tinyglobby": "^0.2.14", - "valibot": "^1.2.0", - "vite-node": "^3.2.2" + "valibot": "^1.2.0" }, "devDependencies": { "@react-router/serve": "workspace:*", diff --git a/packages/react-router-dev/vite/vite-node.ts b/packages/react-router-dev/vite/vite-node.ts deleted file mode 100644 index 86a6e7b78c..0000000000 --- a/packages/react-router-dev/vite/vite-node.ts +++ /dev/null @@ -1,84 +0,0 @@ -// We can only import types from vite-node at the top level since we're in a CJS -// context but want to use vite-node's ESM build since Vite 7+ is ESM only -import type { ViteNodeServer as ViteNodeServerType } from "vite-node/server"; -import type { ViteNodeRunner as ViteNodeRunnerType } from "vite-node/client"; -import type * as Vite from "vite"; - -import { preloadVite, getVite } from "./vite"; -import { ssrExternals } from "./ssr-externals"; - -export type Context = { - devServer: Vite.ViteDevServer; - server: ViteNodeServerType; - runner: ViteNodeRunnerType; -}; - -export async function createContext({ - root, - mode, - customLogger, -}: { - root: Vite.UserConfig["root"]; - mode: Vite.ConfigEnv["mode"]; - customLogger: Vite.UserConfig["customLogger"]; -}): Promise { - await preloadVite(); - const vite = getVite(); - - // Ensure we're using the ESM build of vite-node since Vite 7+ is ESM only - const [{ ViteNodeServer }, { ViteNodeRunner }, { installSourcemapsSupport }] = - await Promise.all([ - import("vite-node/server"), - import("vite-node/client"), - import("vite-node/source-map"), - ]); - - const devServer = await vite.createServer({ - root, - mode, - customLogger, - server: { - preTransformRequests: false, - hmr: false, - watch: null, - }, - ssr: { - external: ssrExternals, - }, - optimizeDeps: { - noDiscovery: true, - }, - css: { - // This empty PostCSS config object prevents the PostCSS config file from - // being loaded. We don't need it in a React Router config context, and - // there's also an issue in Vite 5 when using a .ts PostCSS config file in - // an ESM project: https://github.com/vitejs/vite/issues/15869. Consumers - // can work around this in their own Vite config file, but they can't - // configure this internal usage of vite-node. - postcss: {}, - }, - configFile: false, - envFile: false, - plugins: [], - }); - await devServer.pluginContainer.buildStart({}); - - const server = new ViteNodeServer(devServer); - - installSourcemapsSupport({ - getSourceMap: (source) => server.getSourceMap(source), - }); - - const runner = new ViteNodeRunner({ - root: devServer.config.root, - base: devServer.config.base, - fetchModule(id) { - return server.fetchModule(id); - }, - resolveId(id, importer) { - return server.resolveId(id, importer); - }, - }); - - return { devServer, server, runner }; -} diff --git a/packages/react-router-dev/vite/vite-runner.ts b/packages/react-router-dev/vite/vite-runner.ts new file mode 100644 index 0000000000..b7038337ef --- /dev/null +++ b/packages/react-router-dev/vite/vite-runner.ts @@ -0,0 +1,63 @@ +import type * as Vite from "vite"; + +import { preloadVite, getVite } from "./vite"; +import { ssrExternals } from "./ssr-externals"; + +export type Context = { + server: Vite.ViteDevServer; + env: Vite.RunnableDevEnvironment; +}; + +export async function createContext({ + root, + mode, + customLogger, +}: { + root: Vite.UserConfig["root"]; + mode: Vite.ConfigEnv["mode"]; + customLogger: Vite.UserConfig["customLogger"]; +}): Promise { + await preloadVite(); + const vite = getVite(); + + const server = await vite.createServer({ + root, + mode, + customLogger, + server: { + preTransformRequests: false, + hmr: false, + watch: null, + }, + ssr: { + external: ssrExternals, + }, + optimizeDeps: { + noDiscovery: true, + }, + css: { + // This empty PostCSS config object prevents the PostCSS config file from + // being loaded. We don't need it in a React Router config context, and + // there's also an issue in Vite 5 when using a .ts PostCSS config file in + // an ESM project: https://github.com/vitejs/vite/issues/15869. Consumers + // can work around this in their own Vite config file, but they can't + // configure this internal usage of vite. + postcss: {}, + }, + configFile: false, + envFile: false, + plugins: [], + appType: "custom", + environments: { + nodeRunnerEnv: {}, + }, + }); + await server.pluginContainer.buildStart({}); + + const env = server.environments.nodeRunnerEnv; + if (!env || !vite.isRunnableDevEnvironment(env)) { + throw new Error("Vite environment is not runnable."); + } + + return { server, env }; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bc26854688..bde83557cf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,15 +9,6 @@ catalogs: '@vitejs/plugin-rsc': specifier: ~0.5.7 version: 0.5.7 - react: - specifier: ^19.2.3 - version: 19.2.3 - react-dom: - specifier: ^19.2.3 - version: 19.2.3 - react-server-dom-webpack: - specifier: ^19.2.3 - version: 19.2.3 tsup: specifier: ^8.3.0 version: 8.5.0 @@ -27,16 +18,6 @@ catalogs: wireit: specifier: 0.14.9 version: 0.14.9 - react-canary: - react: - specifier: ^19.2.2 - version: 19.2.3 - react-dom: - specifier: ^19.2.2 - version: 19.2.3 - react-server-dom-webpack: - specifier: ^19.2.2 - version: 19.2.3 overrides: '@types/react': ^18.0.27 @@ -1076,7 +1057,7 @@ importers: version: 0.14.2 react-server-dom-webpack: specifier: 'catalog:' - version: 19.2.3(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react@19.3.0-canary-d763f313-20251210)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.4)) + version: 19.2.3(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react@19.3.0-canary-d763f313-20251210)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.0)) semver: specifier: ^7.3.7 version: 7.7.2 @@ -1086,9 +1067,6 @@ importers: valibot: specifier: ^1.2.0 version: 1.2.0(typescript@5.4.5) - vite-node: - specifier: ^3.2.2 - version: 3.2.4(@types/node@20.11.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.44.1)(tsx@4.19.3)(yaml@2.8.0) devDependencies: '@react-router/serve': specifier: workspace:* @@ -1128,10 +1106,10 @@ importers: version: 7.7.0 '@vitejs/plugin-rsc': specifier: 'catalog:' - version: 0.5.7(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react-server-dom-webpack@19.2.3(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react@19.3.0-canary-d763f313-20251210)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.4)))(react@19.3.0-canary-d763f313-20251210)(vite@6.4.1(@types/node@20.11.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.44.1)(tsx@4.19.3)(yaml@2.8.0)) + version: 0.5.7(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react-server-dom-webpack@19.2.3(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react@19.3.0-canary-d763f313-20251210)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.0)))(react@19.3.0-canary-d763f313-20251210)(vite@6.4.1(@types/node@20.11.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.44.1)(tsx@4.19.3)(yaml@2.8.0)) esbuild-register: specifier: ^3.6.0 - version: 3.6.0(esbuild@0.25.4) + version: 3.6.0(esbuild@0.25.0) execa: specifier: 5.1.1 version: 5.1.1 @@ -12138,7 +12116,7 @@ snapshots: optionalDependencies: react-server-dom-webpack: 19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.103.0) - '@vitejs/plugin-rsc@0.5.7(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react-server-dom-webpack@19.2.3(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react@19.3.0-canary-d763f313-20251210)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.4)))(react@19.3.0-canary-d763f313-20251210)(vite@6.4.1(@types/node@20.11.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.44.1)(tsx@4.19.3)(yaml@2.8.0))': + '@vitejs/plugin-rsc@0.5.7(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react-server-dom-webpack@19.2.3(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react@19.3.0-canary-d763f313-20251210)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.0)))(react@19.3.0-canary-d763f313-20251210)(vite@6.4.1(@types/node@20.11.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.44.1)(tsx@4.19.3)(yaml@2.8.0))': dependencies: '@remix-run/node-fetch-server': 0.12.0 es-module-lexer: 2.0.0 @@ -12152,7 +12130,7 @@ snapshots: vite: 6.4.1(@types/node@20.11.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.44.1)(tsx@4.19.3)(yaml@2.8.0) vitefu: 1.1.1(vite@6.4.1(@types/node@20.11.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.44.1)(tsx@4.19.3)(yaml@2.8.0)) optionalDependencies: - react-server-dom-webpack: 19.2.3(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react@19.3.0-canary-d763f313-20251210)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.4)) + react-server-dom-webpack: 19.2.3(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react@19.3.0-canary-d763f313-20251210)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.0)) '@web3-storage/multipart-parser@1.0.0': {} @@ -13350,13 +13328,6 @@ snapshots: transitivePeerDependencies: - supports-color - esbuild-register@3.6.0(esbuild@0.25.4): - dependencies: - debug: 4.4.1 - esbuild: 0.25.4 - transitivePeerDependencies: - - supports-color - esbuild@0.19.12: optionalDependencies: '@esbuild/aix-ppc64': 0.19.12 @@ -14931,7 +14902,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.14.0 + '@types/node': 20.11.30 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -16522,13 +16493,13 @@ snapshots: webpack: 5.103.0 webpack-sources: 3.3.3 - react-server-dom-webpack@19.2.3(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react@19.3.0-canary-d763f313-20251210)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.4)): + react-server-dom-webpack@19.2.3(react-dom@19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210))(react@19.3.0-canary-d763f313-20251210)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.0)): dependencies: acorn-loose: 8.5.2 neo-async: 2.6.2 react: 19.3.0-canary-d763f313-20251210 react-dom: 19.3.0-canary-d763f313-20251210(react@19.3.0-canary-d763f313-20251210) - webpack: 5.103.0(@swc/core@1.11.24)(esbuild@0.25.4) + webpack: 5.103.0(@swc/core@1.11.24)(esbuild@0.25.0) webpack-sources: 3.3.3 react-test-renderer@19.1.0(react@19.2.3): @@ -17339,17 +17310,17 @@ snapshots: term-size@2.2.1: {} - terser-webpack-plugin@5.3.15(@swc/core@1.11.24)(esbuild@0.25.4)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.4)): + terser-webpack-plugin@5.3.15(@swc/core@1.11.24)(esbuild@0.25.0)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.0)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 4.3.3 serialize-javascript: 6.0.2 terser: 5.44.1 - webpack: 5.103.0(@swc/core@1.11.24)(esbuild@0.25.4) + webpack: 5.103.0(@swc/core@1.11.24)(esbuild@0.25.0) optionalDependencies: '@swc/core': 1.11.24 - esbuild: 0.25.4 + esbuild: 0.25.0 terser-webpack-plugin@5.3.15(webpack@5.103.0): dependencies: @@ -17495,7 +17466,7 @@ snapshots: tsx@4.19.3: dependencies: - esbuild: 0.25.0 + esbuild: 0.25.4 get-tsconfig: 4.10.0 optionalDependencies: fsevents: 2.3.3 @@ -17859,27 +17830,6 @@ snapshots: transitivePeerDependencies: - supports-color - vite-node@3.2.4(@types/node@20.11.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.44.1)(tsx@4.19.3)(yaml@2.8.0): - dependencies: - cac: 6.7.14 - debug: 4.4.1 - es-module-lexer: 1.7.0 - pathe: 2.0.3 - vite: 6.4.1(@types/node@20.11.30)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.44.1)(tsx@4.19.3)(yaml@2.8.0) - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - vite-node@3.2.4(@types/node@22.14.0)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.44.1)(tsx@4.19.3)(yaml@2.8.0): dependencies: cac: 6.7.14 @@ -18112,7 +18062,7 @@ snapshots: - esbuild - uglify-js - webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.4): + webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.0): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -18136,7 +18086,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.15(@swc/core@1.11.24)(esbuild@0.25.4)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.4)) + terser-webpack-plugin: 5.3.15(@swc/core@1.11.24)(esbuild@0.25.0)(webpack@5.103.0(@swc/core@1.11.24)(esbuild@0.25.0)) watchpack: 2.4.4 webpack-sources: 3.3.3 transitivePeerDependencies: