@react-router/dev 8.3.0 → 8.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # `@react-router/dev`
2
2
 
3
+ ## v8.4.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix action submissions behind an HTTPS reverse proxy in `react-router dev` and `vite preview` by using `X-Forwarded-Proto` when constructing `request.url` ([#15466](https://github.com/remix-run/react-router/pull/15466))
8
+ - No React Router configuration is required
9
+ - The URL host continues to come from `Host`, not `X-Forwarded-Host`
10
+ - Configure reverse proxies to overwrite client-supplied `X-Forwarded-Proto` headers
11
+ - Do not expose dev or preview servers publicly
12
+ - Pass development conditions as CLI flags when relaunching the dev process ([#15435](https://github.com/remix-run/react-router/pull/15435))
13
+ - Fix stack trace locations for split route modules when source maps are enabled in the `reactRouter` Vite plugin ([#15440](https://github.com/remix-run/react-router/pull/15440))
14
+ - Updated dependencies:
15
+ - [`react-router@8.4.0`](https://github.com/remix-run/react-router/releases/tag/react-router@8.4.0)
16
+ - [`@react-router/node@8.4.0`](https://github.com/remix-run/react-router/releases/tag/@react-router/node@8.4.0)
17
+ - [`@react-router/serve@8.4.0`](https://github.com/remix-run/react-router/releases/tag/@react-router/serve@8.4.0)
18
+
19
+ ## v8.3.1
20
+
21
+ ### Patch Changes
22
+
23
+ - Bump `@remix-run/node-fetch-server` dependency ([#15447](https://github.com/remix-run/react-router/pull/15447))
24
+ - Generate JavaScript entry files at package build time so `react-router reveal --no-typescript` does not require Prettier at runtime ([#15373](https://github.com/remix-run/react-router/pull/15373))
25
+ - Deprecate the `--no-typescript` flag ahead of its removal in React Router v9
26
+ - Updated dependencies:
27
+ - [`react-router@8.3.1`](https://github.com/remix-run/react-router/releases/tag/react-router@8.3.1)
28
+ - [`@react-router/node@8.3.1`](https://github.com/remix-run/react-router/releases/tag/@react-router/node@8.3.1)
29
+ - [`@react-router/serve@8.3.1`](https://github.com/remix-run/react-router/releases/tag/@react-router/serve@8.3.1)
30
+
3
31
  ## v8.3.0
4
32
 
5
33
  ### Minor Changes
@@ -12,7 +40,7 @@
12
40
 
13
41
  ### Unstable Changes
14
42
 
15
- ⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
43
+ ⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
16
44
 
17
45
  - Add `unstable_rsc/client-version` client build version virtual module ([#15318](https://github.com/remix-run/react-router/pull/15318))
18
46
 
@@ -35,6 +63,7 @@
35
63
  signal: request.signal,
36
64
  });
37
65
  ```
66
+
38
67
  - Updated dependencies:
39
68
  - [`react-router@8.3.0`](https://github.com/remix-run/react-router/releases/tag/react-router@8.3.0)
40
69
  - [`@react-router/node@8.3.0`](https://github.com/remix-run/react-router/releases/tag/@react-router/node@8.3.0)
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v8.3.0
2
+ * @react-router/dev v8.4.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import { _ as getVite, v as preloadVite } from "./typegen-C6qQ4fuP.js";
11
+ import { _ as getVite, v as preloadVite } from "./typegen-WywajSVn.js";
12
12
  //#region vite/build.ts
13
13
  async function build(root, viteBuildOptions) {
14
14
  await preloadVite();
package/dist/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * @react-router/dev v8.3.0
3
+ * @react-router/dev v8.4.0
4
4
  *
5
5
  * Copyright (c) Remix Software Inc.
6
6
  *
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * @license MIT
11
11
  */
12
- import { _ as getVite, l as hasNodeDependency, n as watch, t as run$1, u as loadConfig, v as preloadVite } from "../typegen-C6qQ4fuP.js";
12
+ import { _ as getVite, l as hasNodeDependency, n as watch, t as run$1, u as loadConfig, v as preloadVite } from "../typegen-WywajSVn.js";
13
13
  import { createRequire } from "node:module";
14
14
  import { parseArgs } from "node:util";
15
15
  import semver from "semver";
@@ -23,10 +23,6 @@ import { readPackageJSON } from "pkg-types";
23
23
  import "react-router";
24
24
  import developmentConditionEnabled from "#development-condition-enabled";
25
25
  import { spawn } from "node:child_process";
26
- import * as babel from "@babel/core";
27
- import babelPluginSyntaxJSX from "@babel/plugin-syntax-jsx";
28
- import babelPresetTypeScript from "@babel/preset-typescript";
29
- import prettier from "prettier";
30
26
  import process$1 from "node:process";
31
27
  import packageJson from "@react-router/dev/package.json" with { type: "json" };
32
28
  //#region config/format.ts
@@ -72,24 +68,6 @@ function formatRoutesAsJsx(routeManifest) {
72
68
  return output;
73
69
  }
74
70
  //#endregion
75
- //#region cli/useJavascript.ts
76
- async function transpile(tsx, options = {}) {
77
- let mjs = babel.transformSync(tsx, {
78
- compact: false,
79
- cwd: options.cwd,
80
- filename: options.filename,
81
- plugins: [babelPluginSyntaxJSX],
82
- presets: [[babelPresetTypeScript, { jsx: "preserve" }]],
83
- retainLines: true
84
- });
85
- if (!mjs || !mjs.code) throw new Error("Could not parse TypeScript");
86
- /**
87
- * Babel's `compact` and `retainLines` options are both bad at formatting code.
88
- * Use Prettier for nicer formatting.
89
- */
90
- return await prettier.format(mjs.code, { parser: "babel" });
91
- }
92
- //#endregion
93
71
  //#region vite/profiler.ts
94
72
  const getSession = () => global.__reactRouter_profile_session;
95
73
  const start = async (callback) => {
@@ -129,20 +107,34 @@ async function hasReactRouterRscPlugin({ root, viteBuildOptions: { config, logLe
129
107
  //#endregion
130
108
  //#region restart-with-conditions.ts
131
109
  /**
132
- * Restarts the current Node process, appending new flags to the
133
- * existing NODE_OPTIONS. SIGINT/SIGTERM are always forwarded to the child.
110
+ * Build the child process invocation used to relaunch the CLI with extra flags.
111
+ *
112
+ * Extra flags are placed on argv immediately after the runtime binary. Putting
113
+ * them in NODE_OPTIONS is not portable: Bun silently ignores `--conditions`
114
+ * there, so the child would restart again and hit the already-restarted guard.
134
115
  */
135
- function restartWithMergedOptions(nodeOptions) {
136
- if (process$1.env.REACT_ROUTER_DEV_RESTARTED === "true") throw new Error("restartWithMergedOptions() was called, but the process has already been restarted. This is likely a bug in @react-router/dev.");
137
- const mergedOptions = [process$1.env.NODE_OPTIONS, nodeOptions].filter(Boolean).join(" ").trim();
138
- console.log(`[restart] Relaunching with NODE_OPTIONS: ${mergedOptions}`);
139
- const [cmd, ...args] = process$1.argv;
140
- const child = spawn(cmd, args, {
116
+ function resolveRestartSpawn(argv, extraOptions, env) {
117
+ const extraArgs = extraOptions.split(/\s+/).filter(Boolean);
118
+ const [command, ...args] = argv;
119
+ return {
120
+ command,
121
+ args: [...extraArgs, ...args],
141
122
  env: {
142
- ...process$1.env,
143
- NODE_OPTIONS: mergedOptions,
123
+ ...env,
144
124
  REACT_ROUTER_DEV_RESTARTED: "true"
145
- },
125
+ }
126
+ };
127
+ }
128
+ /**
129
+ * Restarts the current process with extra CLI flags after argv[0].
130
+ * SIGINT/SIGTERM are always forwarded to the child.
131
+ */
132
+ function restartWithMergedOptions(nodeOptions) {
133
+ if (process$1.env.REACT_ROUTER_DEV_RESTARTED === "true") throw new Error("restartWithMergedOptions() was called, but the process has already been restarted. This is likely a bug in @react-router/dev.");
134
+ const { command, args, env } = resolveRestartSpawn(process$1.argv, nodeOptions, process$1.env);
135
+ console.log(`[restart] Relaunching with ${nodeOptions}`);
136
+ const child = spawn(command, args, {
137
+ env,
146
138
  stdio: "inherit"
147
139
  });
148
140
  let signalHandlers = ["SIGINT", "SIGTERM"].map((sig) => {
@@ -180,7 +172,7 @@ async function routes(rootDirectory, flags = {}) {
180
172
  }
181
173
  async function build(root, options = {}) {
182
174
  root = resolveRootDirectory(root, options);
183
- let { build } = await import("../build-B8O1OXuF.js");
175
+ let { build } = await import("../build-CsJF5XUO.js");
184
176
  if (options.profile) await start();
185
177
  try {
186
178
  await build(root, options);
@@ -190,7 +182,7 @@ async function build(root, options = {}) {
190
182
  }
191
183
  async function dev(root, options = {}) {
192
184
  if (developmentConditionEnabled) {
193
- let { dev } = await import("../dev-CznbsRZe.js");
185
+ let { dev } = await import("../dev-_GaivbeG.js");
194
186
  if (options.profile) await start();
195
187
  exitHook(() => stop(console.info));
196
188
  root = resolveRootDirectory(root, options);
@@ -273,20 +265,13 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
273
265
  await copyFile(defaultEntry, outputFile);
274
266
  } else {
275
267
  let pkgJson = await readPackageJSON(rootDirectory);
276
- let defaultEntryClient = path$1.resolve(defaultsDirectory, "entry.client.tsx");
277
- let defaultEntryServer = path$1.resolve(defaultsDirectory, hasNodeDependency(pkgJson.dependencies) && !configResult.value.future.unstable_enableNodeReadableStream ? `entry.server.node.tsx` : `entry.server.web.tsx`);
278
- let isServerEntry = entry === "entry.server";
279
- let contents = isServerEntry ? await createServerEntry(rootDirectory, appDirectory, defaultEntryServer) : await createClientEntry(rootDirectory, appDirectory, defaultEntryClient);
280
- let useTypeScript = flags.typescript ?? true;
281
- let outputEntry = `${entry}.${useTypeScript ? "tsx" : "jsx"}`;
268
+ let outputExtension = flags.typescript ?? true ? "tsx" : "jsx";
269
+ let defaultEntryClient = path$1.resolve(defaultsDirectory, `entry.client.${outputExtension}`);
270
+ let defaultEntryServer = path$1.resolve(defaultsDirectory, hasNodeDependency(pkgJson.dependencies) && !configResult.value.future.unstable_enableNodeReadableStream ? `entry.server.node.${outputExtension}` : `entry.server.web.${outputExtension}`);
271
+ let contents = entry === "entry.server" ? await createServerEntry(rootDirectory, appDirectory, defaultEntryServer) : await createClientEntry(rootDirectory, appDirectory, defaultEntryClient);
272
+ let outputEntry = `${entry}.${outputExtension}`;
282
273
  outputFile = path$1.resolve(appDirectory, outputEntry);
283
- if (!useTypeScript) {
284
- let javascript = await transpile(contents, {
285
- cwd: rootDirectory,
286
- filename: isServerEntry ? defaultEntryServer : defaultEntryClient
287
- });
288
- await writeFile(outputFile, javascript, "utf-8");
289
- } else await writeFile(outputFile, contents, "utf-8");
274
+ await writeFile(outputFile, contents, "utf-8");
290
275
  }
291
276
  console.log(colors.blue(`Entry file ${entry} created at ${path$1.relative(rootDirectory, outputFile)}.`));
292
277
  }
@@ -379,7 +364,7 @@ ${colors.blueBright("react-router")}
379
364
  --json Print the routes as JSON
380
365
  \`reveal\` Options:
381
366
  --config, -c Use specified Vite config file (string)
382
- --no-typescript Generate plain JavaScript files
367
+ --no-typescript Generate plain JavaScript files (deprecated; will be removed in v9)
383
368
  \`typegen\` Options:
384
369
  --watch Automatically regenerate types whenever route config (\`routes.ts\`) or route modules change
385
370
 
@@ -516,7 +501,10 @@ async function run(argv = process.argv.slice(2), { isMain = false } = {}) {
516
501
  return;
517
502
  }
518
503
  flags.interactive = flags.interactive ?? isMain;
519
- if (values["no-typescript"]) flags.typescript = false;
504
+ if (values["no-typescript"]) {
505
+ console.warn(colors.yellow("The --no-typescript flag is deprecated and will be removed in React Router v9."));
506
+ flags.typescript = false;
507
+ }
520
508
  switch (input[0]) {
521
509
  case "routes":
522
510
  await routes(input[1], flags);
@@ -0,0 +1,12 @@
1
+ import { startTransition, StrictMode } from "react";
2
+ import { hydrateRoot } from "react-dom/client";
3
+ import { HydratedRouter } from "react-router/dom";
4
+
5
+ startTransition(() => {
6
+ hydrateRoot(
7
+ document,
8
+ <StrictMode>
9
+ <HydratedRouter />
10
+ </StrictMode>,
11
+ );
12
+ });
@@ -0,0 +1,82 @@
1
+ import { PassThrough } from "node:stream";
2
+
3
+ import { createReadableStreamFromReadable } from "@react-router/node";
4
+ import { ServerRouter } from "react-router";
5
+ import { isbot } from "isbot";
6
+
7
+ import { renderToPipeableStream } from "react-dom/server";
8
+
9
+ export const streamTimeout = 5_000;
10
+
11
+ export default function handleRequest(
12
+ request,
13
+ responseStatusCode,
14
+ responseHeaders,
15
+ routerContext,
16
+ loadContext,
17
+ ) {
18
+ // https://httpwg.org/specs/rfc9110.html#HEAD
19
+ if (request.method.toUpperCase() === "HEAD") {
20
+ return new Response(null, {
21
+ status: responseStatusCode,
22
+ headers: responseHeaders,
23
+ });
24
+ }
25
+
26
+ return new Promise((resolve, reject) => {
27
+ let shellRendered = false;
28
+ let userAgent = request.headers.get("user-agent");
29
+
30
+ // Ensure requests from bots and SPA Mode renders wait for all content to load before responding
31
+ // https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation
32
+ let readyOption =
33
+ (userAgent && isbot(userAgent)) || routerContext.isSpaMode
34
+ ? "onAllReady"
35
+ : "onShellReady";
36
+
37
+ // Abort the rendering stream after the `streamTimeout` so it has time to
38
+ // flush down the rejected boundaries
39
+ let timeoutId = setTimeout(() => abort(), streamTimeout + 1000);
40
+
41
+ const { pipe, abort } = renderToPipeableStream(
42
+ <ServerRouter context={routerContext} url={request.url} />,
43
+ {
44
+ [readyOption]() {
45
+ shellRendered = true;
46
+ const body = new PassThrough({
47
+ final(callback) {
48
+ // Clear the timeout to prevent retaining the closure and memory leak
49
+ clearTimeout(timeoutId);
50
+ timeoutId = undefined;
51
+ callback();
52
+ },
53
+ });
54
+ const stream = createReadableStreamFromReadable(body);
55
+
56
+ responseHeaders.set("Content-Type", "text/html");
57
+
58
+ pipe(body);
59
+
60
+ resolve(
61
+ new Response(stream, {
62
+ headers: responseHeaders,
63
+ status: responseStatusCode,
64
+ }),
65
+ );
66
+ },
67
+ onShellError(error) {
68
+ reject(error);
69
+ },
70
+ onError(error) {
71
+ responseStatusCode = 500;
72
+ // Log streaming rendering errors from inside the shell. Don't log
73
+ // errors encountered during initial shell rendering since they'll
74
+ // reject and get logged in handleDocumentRequest.
75
+ if (shellRendered) {
76
+ console.error(error);
77
+ }
78
+ },
79
+ },
80
+ );
81
+ });
82
+ }
@@ -0,0 +1,53 @@
1
+ import { ServerRouter } from "react-router";
2
+ import { isbot } from "isbot";
3
+ import { renderToReadableStream } from "react-dom/server";
4
+
5
+ export const streamTimeout = 5_000;
6
+
7
+ export default async function handleRequest(
8
+ request,
9
+ responseStatusCode,
10
+ responseHeaders,
11
+ routerContext,
12
+ _loadContext,
13
+ ) {
14
+ // https://httpwg.org/specs/rfc9110.html#HEAD
15
+ if (request.method.toUpperCase() === "HEAD") {
16
+ return new Response(null, {
17
+ status: responseStatusCode,
18
+ headers: responseHeaders,
19
+ });
20
+ }
21
+
22
+ let shellRendered = false;
23
+ let userAgent = request.headers.get("user-agent");
24
+
25
+ const body = await renderToReadableStream(
26
+ <ServerRouter context={routerContext} url={request.url} />,
27
+ {
28
+ signal: AbortSignal.timeout(streamTimeout + 1000),
29
+ onError(error) {
30
+ responseStatusCode = 500;
31
+ // Log streaming rendering errors from inside the shell. Don't log
32
+ // errors encountered during initial shell rendering since they'll
33
+ // reject and get logged in handleDocumentRequest.
34
+ if (shellRendered) {
35
+ console.error(error);
36
+ }
37
+ },
38
+ },
39
+ );
40
+ shellRendered = true;
41
+
42
+ // Ensure requests from bots and SPA Mode renders wait for all content to load before responding
43
+ // https://react.dev/reference/react-dom/server/renderToPipeableStream#waiting-for-all-content-to-load-for-crawlers-and-static-generation
44
+ if ((userAgent && isbot(userAgent)) || routerContext.isSpaMode) {
45
+ await body.allReady;
46
+ }
47
+
48
+ responseHeaders.set("Content-Type", "text/html");
49
+ return new Response(body, {
50
+ headers: responseHeaders,
51
+ status: responseStatusCode,
52
+ });
53
+ }
package/dist/config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v8.3.0
2
+ * @react-router/dev v8.4.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v8.3.0
2
+ * @react-router/dev v8.4.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import { _ as getVite, v as preloadVite } from "./typegen-C6qQ4fuP.js";
11
+ import { _ as getVite, v as preloadVite } from "./typegen-WywajSVn.js";
12
12
  import { n as start, r as stop, t as getSession } from "./cli/index.js";
13
13
  import colors from "picocolors";
14
14
  //#region vite/dev.ts
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v8.3.0
2
+ * @react-router/dev v8.4.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
package/dist/routes.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v8.3.0
2
+ * @react-router/dev v8.4.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,5 +8,5 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import { a as prefix, i as layout, n as getAppDirectory, o as relative, r as index, s as route } from "./routes-BwOSW5AT.js";
11
+ import { a as prefix, i as layout, n as getAppDirectory, o as relative, r as index, s as route } from "./routes-BFdkiVnp.js";
12
12
  export { getAppDirectory, index, layout, prefix, relative, route };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v8.3.0
2
+ * @react-router/dev v8.4.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import { c as setAppDirectory, l as validateRouteConfig, t as configRoutesToRouteManifest, u as invariant } from "./routes-BwOSW5AT.js";
11
+ import { c as setAppDirectory, l as validateRouteConfig, t as configRoutesToRouteManifest, u as invariant } from "./routes-BFdkiVnp.js";
12
12
  import { createRequire } from "node:module";
13
13
  import colors from "picocolors";
14
14
  import fs from "node:fs";
package/dist/vite.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v8.3.0
2
+ * @react-router/dev v8.4.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,8 +8,8 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import { _ as getVite, a as t, c as createConfigLoader, d as resolveEntryFiles, f as resolveRSCEntryFiles, g as getUserBuildRollupOptions, h as defineOptimizeDepsCompilerOptions, i as parse$1, l as hasNodeDependency, m as defineCompilerOptions, n as watch, o as traverse, p as ssrExternals, r as generate, s as configRouteToBranchRoute, v as preloadVite } from "./typegen-C6qQ4fuP.js";
12
- import { u as invariant } from "./routes-BwOSW5AT.js";
11
+ import { _ as getVite, a as t, c as createConfigLoader, d as resolveEntryFiles, f as resolveRSCEntryFiles, g as getUserBuildRollupOptions, h as defineOptimizeDepsCompilerOptions, i as parse$1, l as hasNodeDependency, m as defineCompilerOptions, n as watch, o as traverse, p as ssrExternals, r as generate, s as configRouteToBranchRoute, v as preloadVite } from "./typegen-WywajSVn.js";
12
+ import { u as invariant } from "./routes-BFdkiVnp.js";
13
13
  import { createRequire } from "node:module";
14
14
  import colors from "picocolors";
15
15
  import { existsSync, readFileSync, readdirSync } from "node:fs";
@@ -21,9 +21,9 @@ import { createRequestHandler, matchRoutes, unstable_setDevServerHooks } from "r
21
21
  import * as Path from "pathe";
22
22
  import path$1, { join } from "pathe";
23
23
  import pick from "lodash/pick.js";
24
- import * as babel from "@babel/core";
25
24
  import { createHash } from "node:crypto";
26
25
  import * as url from "node:url";
26
+ import * as babel from "@babel/core";
27
27
  import { createRequest, sendResponse } from "@remix-run/node-fetch-server";
28
28
  import { init, parse } from "es-module-lexer";
29
29
  import jsesc from "jsesc";
@@ -37,7 +37,13 @@ import { readFile as readFile$1 } from "fs/promises";
37
37
  async function fromNodeRequest(nodeReq, nodeRes) {
38
38
  invariant(nodeReq.originalUrl, "Expected `nodeReq.originalUrl` to be defined");
39
39
  nodeReq.url = nodeReq.originalUrl;
40
- return createRequest(nodeReq, nodeRes);
40
+ return createRequest(nodeReq, nodeRes, { protocol: getForwardedProtocol(nodeReq) });
41
+ }
42
+ function getForwardedProtocol(nodeReq) {
43
+ let forwardedProto = nodeReq.headers["x-forwarded-proto"];
44
+ let proto = (Array.isArray(forwardedProto) ? forwardedProto[0] : forwardedProto)?.split(",")[0].trim().toLowerCase();
45
+ if (proto?.endsWith(":")) proto = proto.slice(0, -1);
46
+ return proto === "http" || proto === "https" ? `${proto}:` : void 0;
41
47
  }
42
48
  //#endregion
43
49
  //#region vite/resolve-file-url.ts
@@ -614,9 +620,9 @@ const routeChunkExportNames = [
614
620
  ];
615
621
  const mainChunkName = "main";
616
622
  const routeChunkNames = ["main", ...routeChunkExportNames];
617
- function getRouteChunkCode(code, chunkName, cache, cacheKey) {
618
- if (chunkName === mainChunkName) return omitChunkedExports(code, routeChunkExportNames, {}, cache, cacheKey);
619
- return getChunkedExport(code, chunkName, {}, cache, cacheKey);
623
+ function getRouteChunkCode(code, chunkName, cache, cacheKey, generateOptions = {}) {
624
+ if (chunkName === mainChunkName) return omitChunkedExports(code, routeChunkExportNames, generateOptions, cache, cacheKey);
625
+ return getChunkedExport(code, chunkName, generateOptions, cache, cacheKey);
620
626
  }
621
627
  const routeChunkQueryStringPrefix = "?route-chunk=";
622
628
  const routeChunkQueryStrings = {
@@ -1817,11 +1823,14 @@ const reactRouterVitePlugin = () => {
1817
1823
  let routeFileName = path$2.basename(routeModuleId);
1818
1824
  let sourceExports = await getRouteModuleExports(viteChildCompiler, ctx, routeModuleId);
1819
1825
  let { chunkedExports = [] } = options?.ssr ? {} : await detectRouteChunksIfEnabled(cache, ctx, id, code);
1820
- return `export { ${sourceExports.filter((exportName) => {
1821
- let isRouteEntryExport = options?.ssr && SERVER_ONLY_ROUTE_EXPORTS.includes(exportName) || CLIENT_ROUTE_EXPORTS$1.includes(exportName);
1822
- let isChunkedExport = chunkedExports.includes(exportName);
1823
- return isRouteEntryExport && !isChunkedExport;
1824
- }).join(", ")} } from "./${routeFileName}";`;
1826
+ return {
1827
+ code: `export { ${sourceExports.filter((exportName) => {
1828
+ let isRouteEntryExport = options?.ssr && SERVER_ONLY_ROUTE_EXPORTS.includes(exportName) || CLIENT_ROUTE_EXPORTS$1.includes(exportName);
1829
+ let isChunkedExport = chunkedExports.includes(exportName);
1830
+ return isRouteEntryExport && !isChunkedExport;
1831
+ }).join(", ")} } from "./${routeFileName}";`,
1832
+ map: { mappings: "" }
1833
+ };
1825
1834
  }
1826
1835
  },
1827
1836
  {
@@ -2476,7 +2485,10 @@ async function detectRouteChunksIfEnabled(cache, ctx, id, input) {
2476
2485
  }
2477
2486
  async function getRouteChunkIfEnabled(cache, ctx, id, chunkName, input) {
2478
2487
  if (!ctx.reactRouterConfig.splitRouteModules) return null;
2479
- return getRouteChunkCode(await resolveRouteFileCode(ctx, input), chunkName, cache, normalizeRelativeFilePath(id, ctx.reactRouterConfig) + (typeof input === "string" ? "" : "?read"));
2488
+ return getRouteChunkCode(await resolveRouteFileCode(ctx, input), chunkName, cache, normalizeRelativeFilePath(id, ctx.reactRouterConfig) + (typeof input === "string" ? "" : "?read"), {
2489
+ sourceMaps: true,
2490
+ sourceFileName: path$2.basename(id.split("?")[0])
2491
+ });
2480
2492
  }
2481
2493
  function validateRouteChunks$1({ ctx, id, valid }) {
2482
2494
  if (isRootRouteModuleId(ctx, id)) return;
@@ -2724,7 +2736,7 @@ const nodeRequire = createRequire(import.meta.url);
2724
2736
  function hasDependency({ name, rootDirectory }) {
2725
2737
  try {
2726
2738
  return Boolean(nodeRequire.resolve(name, { paths: [rootDirectory] }));
2727
- } catch (e) {
2739
+ } catch {
2728
2740
  return false;
2729
2741
  }
2730
2742
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@react-router/dev",
3
3
  "type": "module",
4
- "version": "8.3.0",
4
+ "version": "8.4.0",
5
5
  "description": "Dev tools and CLI for React Router",
6
6
  "keywords": [
7
7
  "react",
@@ -88,11 +88,9 @@
88
88
  "@babel/core": "^7.29.7",
89
89
  "@babel/generator": "^7.29.7",
90
90
  "@babel/parser": "^7.29.7",
91
- "@babel/plugin-syntax-jsx": "^7.29.7",
92
- "@babel/preset-typescript": "^7.29.7",
93
91
  "@babel/traverse": "^7.29.7",
94
92
  "@babel/types": "^7.29.7",
95
- "@remix-run/node-fetch-server": "^0.13.3",
93
+ "@remix-run/node-fetch-server": "^0.14.1",
96
94
  "babel-dead-code-elimination": "^1.0.12",
97
95
  "chokidar": "^5.0.0",
98
96
  "dedent": "^1.7.2",
@@ -105,14 +103,15 @@
105
103
  "pathe": "^2.0.3",
106
104
  "picocolors": "^1.1.1",
107
105
  "pkg-types": "^2.3.1",
108
- "prettier": "^3.8.3",
109
106
  "react-refresh": "^0.18.0",
110
107
  "semver": "^7.8.1",
111
108
  "tinyglobby": "^0.2.16",
112
109
  "valibot": "^1.4.1",
113
- "@react-router/node": "8.3.0"
110
+ "@react-router/node": "8.4.0"
114
111
  },
115
112
  "devDependencies": {
113
+ "@babel/plugin-syntax-jsx": "^7.29.7",
114
+ "@babel/preset-typescript": "^7.29.7",
116
115
  "@types/babel__core": "^7.20.5",
117
116
  "@types/babel__generator": "^7.27.0",
118
117
  "@types/babel__traverse": "^7.28.0",
@@ -127,13 +126,14 @@
127
126
  "esbuild-register": "^3.6.0",
128
127
  "execa": "9.6.1",
129
128
  "fast-glob": "3.3.3",
129
+ "prettier": "^3.8.3",
130
130
  "tsdown": "^0.22.0",
131
131
  "typescript": "^6.0.3",
132
132
  "vite": "^7.0.0",
133
133
  "wireit": "0.14.12",
134
134
  "wrangler": "^4.95.0",
135
- "react-router": "^8.3.0",
136
- "@react-router/serve": "8.3.0"
135
+ "react-router": "^8.4.0",
136
+ "@react-router/serve": "8.4.0"
137
137
  },
138
138
  "peerDependencies": {
139
139
  "@vitejs/plugin-rsc": "~0.5.26",
@@ -141,8 +141,8 @@
141
141
  "typescript": "^5.1.0 || ^6.0.0 || ^7.0.0",
142
142
  "vite": "^7.0.0 || ^8.0.0",
143
143
  "wrangler": "^4.0.0",
144
- "react-router": "^8.3.0",
145
- "@react-router/serve": "^8.3.0"
144
+ "@react-router/serve": "^8.4.0",
145
+ "react-router": "^8.4.0"
146
146
  },
147
147
  "peerDependenciesMeta": {
148
148
  "@vitejs/plugin-rsc": {