@react-router/dev 8.3.1 → 8.5.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 +44 -0
- package/dist/{build-Ou3B3epu.js → build-ZbZgdE7Y.js} +2 -2
- package/dist/cli/index.js +29 -15
- package/dist/{config-t89niiFv.d.ts → config-DP95WFpo.d.ts} +41 -10
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/{dev-DFccbHpq.js → dev-DGFm0uWr.js} +2 -2
- package/dist/{routes-C-NBxWG3.js → routes-Cyup1Gnm.js} +1 -1
- package/dist/routes.js +2 -2
- package/dist/{typegen-DxFMuBQP.js → typegen-CiHN93zF.js} +15 -3
- package/dist/vite.js +138 -61
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# `@react-router/dev`
|
|
2
2
|
|
|
3
|
+
## v8.5.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fix critical CSS collection in dev registering server-only route imports as client dependencies, which triggered dependency re-optimization and full page reloads ([#15595](https://github.com/remix-run/react-router/pull/15595))
|
|
8
|
+
- Fix intermittent `Prerender: Request failed for ... connect ECONNREFUSED` errors during prerendering ([#15325](https://github.com/remix-run/react-router/pull/15325))
|
|
9
|
+
- Send requests to the address the Vite preview server bound to
|
|
10
|
+
- Avoid re-resolving `localhost` for each request, which could select a different address family (`127.0.0.1` vs `::1`)
|
|
11
|
+
|
|
12
|
+
### Unstable Changes
|
|
13
|
+
|
|
14
|
+
⚠️ _[Unstable features](https://reactrouter.com/community/api-development-strategy#unstable-flags) are not recommended for production use_
|
|
15
|
+
|
|
16
|
+
- Add `ssr: "unstable_api-only"` to retain a runtime server for loaders, actions, and route discovery while disabling production document rendering ([#15601](https://github.com/remix-run/react-router/pull/15601))
|
|
17
|
+
- Generate a root-only SPA shell when prerendering is disabled
|
|
18
|
+
- Support prerendered pages and data files alongside runtime loaders and actions, with a SPA fallback for non-prerendered paths
|
|
19
|
+
- Default API-only builds to lazy route discovery
|
|
20
|
+
- Reject API-only configuration in RSC Framework Mode
|
|
21
|
+
- Preserve server-only route exports in additional Vite server environments in both API-only and SSR modes
|
|
22
|
+
- Serve prerendered pages and the SPA fallback in Vite preview while retaining live data requests and route discovery
|
|
23
|
+
- Add the `future.unstable_customRouteDiscovery` flag to opt into application-controlled route discovery in conventional Framework Mode ([#15602](https://github.com/remix-run/react-router/pull/15602))
|
|
24
|
+
- Fix source maps for route modules in unstable RSC Framework Mode ([#15479](https://github.com/remix-run/react-router/pull/15479))
|
|
25
|
+
- Add `unstable_apiServerOrigin` to configure the origin for API-only loader, action, and route discovery requests ([#15601](https://github.com/remix-run/react-router/pull/15601))
|
|
26
|
+
- Updated dependencies:
|
|
27
|
+
- [`react-router@8.5.0`](https://github.com/remix-run/react-router/releases/tag/react-router@8.5.0)
|
|
28
|
+
- [`@react-router/node@8.5.0`](https://github.com/remix-run/react-router/releases/tag/@react-router/node@8.5.0)
|
|
29
|
+
- [`@react-router/serve@8.5.0`](https://github.com/remix-run/react-router/releases/tag/@react-router/serve@8.5.0)
|
|
30
|
+
|
|
31
|
+
## v8.4.0
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- 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))
|
|
36
|
+
- No React Router configuration is required
|
|
37
|
+
- The URL host continues to come from `Host`, not `X-Forwarded-Host`
|
|
38
|
+
- Configure reverse proxies to overwrite client-supplied `X-Forwarded-Proto` headers
|
|
39
|
+
- Do not expose dev or preview servers publicly
|
|
40
|
+
- Pass development conditions as CLI flags when relaunching the dev process ([#15435](https://github.com/remix-run/react-router/pull/15435))
|
|
41
|
+
- 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))
|
|
42
|
+
- Updated dependencies:
|
|
43
|
+
- [`react-router@8.4.0`](https://github.com/remix-run/react-router/releases/tag/react-router@8.4.0)
|
|
44
|
+
- [`@react-router/node@8.4.0`](https://github.com/remix-run/react-router/releases/tag/@react-router/node@8.4.0)
|
|
45
|
+
- [`@react-router/serve@8.4.0`](https://github.com/remix-run/react-router/releases/tag/@react-router/serve@8.4.0)
|
|
46
|
+
|
|
3
47
|
## v8.3.1
|
|
4
48
|
|
|
5
49
|
### Patch Changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/dev v8.
|
|
2
|
+
* @react-router/dev v8.5.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-
|
|
11
|
+
import { _ as getVite, v as preloadVite } from "./typegen-CiHN93zF.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
|
+
* @react-router/dev v8.5.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-
|
|
12
|
+
import { _ as getVite, l as hasNodeDependency, n as watch, t as run$1, u as loadConfig, v as preloadVite } from "../typegen-CiHN93zF.js";
|
|
13
13
|
import { createRequire } from "node:module";
|
|
14
14
|
import { parseArgs } from "node:util";
|
|
15
15
|
import semver from "semver";
|
|
@@ -107,20 +107,34 @@ async function hasReactRouterRscPlugin({ root, viteBuildOptions: { config, logLe
|
|
|
107
107
|
//#endregion
|
|
108
108
|
//#region restart-with-conditions.ts
|
|
109
109
|
/**
|
|
110
|
-
*
|
|
111
|
-
*
|
|
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.
|
|
112
115
|
*/
|
|
113
|
-
function
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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],
|
|
119
122
|
env: {
|
|
120
|
-
...
|
|
121
|
-
NODE_OPTIONS: mergedOptions,
|
|
123
|
+
...env,
|
|
122
124
|
REACT_ROUTER_DEV_RESTARTED: "true"
|
|
123
|
-
}
|
|
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,
|
|
124
138
|
stdio: "inherit"
|
|
125
139
|
});
|
|
126
140
|
let signalHandlers = ["SIGINT", "SIGTERM"].map((sig) => {
|
|
@@ -158,7 +172,7 @@ async function routes(rootDirectory, flags = {}) {
|
|
|
158
172
|
}
|
|
159
173
|
async function build(root, options = {}) {
|
|
160
174
|
root = resolveRootDirectory(root, options);
|
|
161
|
-
let { build } = await import("../build-
|
|
175
|
+
let { build } = await import("../build-ZbZgdE7Y.js");
|
|
162
176
|
if (options.profile) await start();
|
|
163
177
|
try {
|
|
164
178
|
await build(root, options);
|
|
@@ -168,7 +182,7 @@ async function build(root, options = {}) {
|
|
|
168
182
|
}
|
|
169
183
|
async function dev(root, options = {}) {
|
|
170
184
|
if (developmentConditionEnabled) {
|
|
171
|
-
let { dev } = await import("../dev-
|
|
185
|
+
let { dev } = await import("../dev-DGFm0uWr.js");
|
|
172
186
|
if (options.profile) await start();
|
|
173
187
|
exitHook(() => stop(console.info));
|
|
174
188
|
root = resolveRootDirectory(root, options);
|
|
@@ -38,6 +38,7 @@ type ServerBundlesBuildManifest = BaseBuildManifest & {
|
|
|
38
38
|
};
|
|
39
39
|
type ServerModuleFormat = "esm" | "cjs";
|
|
40
40
|
interface FutureConfig {
|
|
41
|
+
unstable_customRouteDiscovery: boolean;
|
|
41
42
|
unstable_enableNodeReadableStream: boolean;
|
|
42
43
|
unstable_optimizeDeps: boolean;
|
|
43
44
|
}
|
|
@@ -140,12 +141,30 @@ type ReactRouterConfig = {
|
|
|
140
141
|
*/
|
|
141
142
|
serverBundles?: ServerBundlesFunction;
|
|
142
143
|
/**
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* `
|
|
146
|
-
*
|
|
144
|
+
* Control runtime server-side document rendering. Defaults to `true`.
|
|
145
|
+
*
|
|
146
|
+
* Set `false` to generate a static client build without a runtime server.
|
|
147
|
+
* Without prerendering, this generates a root-only SPA shell. With
|
|
148
|
+
* prerendering, it generates HTML and data files for selected paths plus
|
|
149
|
+
* a SPA fallback for non-prerendered paths.
|
|
150
|
+
*
|
|
151
|
+
* Set `"unstable_api-only"` to retain a runtime server for loaders, actions,
|
|
152
|
+
* and route discovery while disabling production document rendering.
|
|
153
|
+
* Documents follow the same prerendering and SPA fallback behavior as
|
|
154
|
+
* `ssr:false`, with runtime loaders and actions available for all routes.
|
|
155
|
+
* API-only mode is unstable and is not supported in RSC Framework Mode.
|
|
156
|
+
*/
|
|
157
|
+
ssr?: boolean | "unstable_api-only";
|
|
158
|
+
/**
|
|
159
|
+
* The origin to use for server requests when `ssr` is `"unstable_api-only"`.
|
|
160
|
+
* This is ignored when `ssr` is `true` or `false`. Defaults to the same
|
|
161
|
+
* origin that serves the client build. Applies to loader, action, and route
|
|
162
|
+
* discovery requests.
|
|
163
|
+
*
|
|
164
|
+
* **Note:** The server origin will need to be configured appropriately for
|
|
165
|
+
* Cross-Origin Request Sharing (CORS).
|
|
147
166
|
*/
|
|
148
|
-
|
|
167
|
+
unstable_apiServerOrigin?: string;
|
|
149
168
|
/**
|
|
150
169
|
* Enable subresource integrity hashes on asset script tags. Defaults to
|
|
151
170
|
* `false`.
|
|
@@ -256,12 +275,24 @@ type ResolvedReactRouterConfig = Readonly<{
|
|
|
256
275
|
*/
|
|
257
276
|
serverModuleFormat: ServerModuleFormat;
|
|
258
277
|
/**
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
* `
|
|
262
|
-
*
|
|
278
|
+
* Control runtime server-side document rendering. Defaults to `true`.
|
|
279
|
+
*
|
|
280
|
+
* Set `false` to generate a static client build without a runtime server.
|
|
281
|
+
* Without prerendering, this generates a root-only SPA shell. With
|
|
282
|
+
* prerendering, it generates HTML and data files for selected paths plus
|
|
283
|
+
* a SPA fallback for non-prerendered paths.
|
|
284
|
+
*
|
|
285
|
+
* Set `"unstable_api-only"` to retain a runtime server for loaders, actions,
|
|
286
|
+
* and route discovery while disabling production document rendering.
|
|
287
|
+
* Documents follow the same prerendering and SPA fallback behavior as
|
|
288
|
+
* `ssr:false`, with runtime loaders and actions available for all routes.
|
|
289
|
+
* API-only mode is unstable and is not supported in RSC Framework Mode.
|
|
290
|
+
*/
|
|
291
|
+
ssr: boolean | "unstable_api-only";
|
|
292
|
+
/**
|
|
293
|
+
* The origin to use for server requests in API-only mode.
|
|
263
294
|
*/
|
|
264
|
-
|
|
295
|
+
unstable_apiServerOrigin?: string;
|
|
265
296
|
/**
|
|
266
297
|
* Whether to generate subresource integrity hashes for asset script tags.
|
|
267
298
|
*/
|
package/dist/config.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
|
|
2
|
-
import { i as ServerBundlesFunction, n as Preset, r as ReactRouterConfig, t as BuildManifest } from "./config-
|
|
2
|
+
import { i as ServerBundlesFunction, n as Preset, r as ReactRouterConfig, t as BuildManifest } from "./config-DP95WFpo.js";
|
|
3
3
|
export type { BuildManifest, ReactRouterConfig as Config, Preset, ServerBundlesFunction };
|
package/dist/config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/dev v8.
|
|
2
|
+
* @react-router/dev v8.5.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-
|
|
11
|
+
import { _ as getVite, v as preloadVite } from "./typegen-CiHN93zF.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
|
package/dist/routes.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/dev v8.
|
|
2
|
+
* @react-router/dev v8.5.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-
|
|
11
|
+
import { a as prefix, i as layout, n as getAppDirectory, o as relative, r as index, s as route } from "./routes-Cyup1Gnm.js";
|
|
12
12
|
export { getAppDirectory, index, layout, prefix, relative, route };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/dev v8.
|
|
2
|
+
* @react-router/dev v8.5.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-
|
|
11
|
+
import { c as setAppDirectory, l as validateRouteConfig, t as configRoutesToRouteManifest, u as invariant } from "./routes-Cyup1Gnm.js";
|
|
12
12
|
import { createRequire } from "node:module";
|
|
13
13
|
import colors from "picocolors";
|
|
14
14
|
import fs from "node:fs";
|
|
@@ -228,10 +228,18 @@ async function resolveConfig({ root, viteRunnerContext, reactRouterConfigFile, s
|
|
|
228
228
|
ssr: true
|
|
229
229
|
};
|
|
230
230
|
let userAndPresetConfigs = mergeReactRouterConfig(...presets, reactRouterUserConfig);
|
|
231
|
-
let { appDirectory: userAppDirectory, basename, buildDirectory: userBuildDirectory, buildEnd, prerender, routeDiscovery: userRouteDiscovery, serverBuildFile, serverBundles, serverModuleFormat, ssr } = {
|
|
231
|
+
let { appDirectory: userAppDirectory, basename, buildDirectory: userBuildDirectory, buildEnd, prerender, routeDiscovery: userRouteDiscovery, serverBuildFile, serverBundles, serverModuleFormat, ssr, unstable_apiServerOrigin } = {
|
|
232
232
|
...defaults,
|
|
233
233
|
...userAndPresetConfigs
|
|
234
234
|
};
|
|
235
|
+
if (ssr === "unstable_api-only" && unstable_apiServerOrigin != null) try {
|
|
236
|
+
let url = new URL(unstable_apiServerOrigin);
|
|
237
|
+
if (url.pathname !== "/" || url.search || url.hash) return err("The `unstable_apiServerOrigin` config must be an origin without a path, query, or hash.");
|
|
238
|
+
unstable_apiServerOrigin = url.origin;
|
|
239
|
+
} catch {
|
|
240
|
+
return err("The `unstable_apiServerOrigin` config must be a valid absolute URL.");
|
|
241
|
+
}
|
|
242
|
+
else unstable_apiServerOrigin = void 0;
|
|
235
243
|
if (!ssr && serverBundles) serverBundles = void 0;
|
|
236
244
|
if (prerender) {
|
|
237
245
|
let isValidPrerenderPathsConfig = (p) => typeof p === "boolean" || typeof p === "function" || Array.isArray(p);
|
|
@@ -295,6 +303,7 @@ async function resolveConfig({ root, viteRunnerContext, reactRouterConfigFile, s
|
|
|
295
303
|
if ("unstable_subResourceIntegrity" in futureConfig) return err("The `future.unstable_subResourceIntegrity` flag has been stabilized and moved to a top-level `config.subResourceIntegrity` field");
|
|
296
304
|
}
|
|
297
305
|
let future = {
|
|
306
|
+
unstable_customRouteDiscovery: userAndPresetConfigs.future?.unstable_customRouteDiscovery ?? false,
|
|
298
307
|
unstable_enableNodeReadableStream: userAndPresetConfigs.future?.unstable_enableNodeReadableStream ?? false,
|
|
299
308
|
unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false
|
|
300
309
|
};
|
|
@@ -314,6 +323,7 @@ async function resolveConfig({ root, viteRunnerContext, reactRouterConfigFile, s
|
|
|
314
323
|
serverBundles,
|
|
315
324
|
serverModuleFormat,
|
|
316
325
|
ssr,
|
|
326
|
+
unstable_apiServerOrigin,
|
|
317
327
|
splitRouteModules,
|
|
318
328
|
subResourceIntegrity,
|
|
319
329
|
allowedActionOrigins,
|
|
@@ -624,6 +634,8 @@ function generateServerBuild(ctx) {
|
|
|
624
634
|
export const routeDiscovery: ServerBuild["routeDiscovery"];
|
|
625
635
|
export const routes: ServerBuild["routes"];
|
|
626
636
|
export const ssr: ServerBuild["ssr"];
|
|
637
|
+
export const unstable_apiOnly: ServerBuild["unstable_apiOnly"];
|
|
638
|
+
export const unstable_apiServerOrigin: ServerBuild["unstable_apiServerOrigin"];
|
|
627
639
|
export const allowedActionOrigins: ServerBuild["allowedActionOrigins"];
|
|
628
640
|
export const unstable_getCriticalCss: ServerBuild["unstable_getCriticalCss"];
|
|
629
641
|
}
|
package/dist/vite.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/dev v8.
|
|
2
|
+
* @react-router/dev v8.5.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-
|
|
12
|
-
import { u as invariant } from "./routes-
|
|
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-CiHN93zF.js";
|
|
12
|
+
import { u as invariant } from "./routes-Cyup1Gnm.js";
|
|
13
13
|
import { createRequire } from "node:module";
|
|
14
14
|
import colors from "picocolors";
|
|
15
15
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
@@ -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
|
|
@@ -108,7 +114,8 @@ const findDeps = async (vite, node, deps) => {
|
|
|
108
114
|
}
|
|
109
115
|
}
|
|
110
116
|
async function addFromUrl(url) {
|
|
111
|
-
let
|
|
117
|
+
let ssrNode = await vite.environments.ssr.moduleGraph.getModuleByUrl(url);
|
|
118
|
+
let node = ssrNode?.id ? vite.moduleGraph.getModuleById(ssrNode.id) : void 0;
|
|
112
119
|
if (node) await addFromNode(node);
|
|
113
120
|
}
|
|
114
121
|
if (node.ssrTransformResult) {
|
|
@@ -614,9 +621,9 @@ const routeChunkExportNames = [
|
|
|
614
621
|
];
|
|
615
622
|
const mainChunkName = "main";
|
|
616
623
|
const routeChunkNames = ["main", ...routeChunkExportNames];
|
|
617
|
-
function getRouteChunkCode(code, chunkName, cache, cacheKey) {
|
|
618
|
-
if (chunkName === mainChunkName) return omitChunkedExports(code, routeChunkExportNames,
|
|
619
|
-
return getChunkedExport(code, chunkName,
|
|
624
|
+
function getRouteChunkCode(code, chunkName, cache, cacheKey, generateOptions = {}) {
|
|
625
|
+
if (chunkName === mainChunkName) return omitChunkedExports(code, routeChunkExportNames, generateOptions, cache, cacheKey);
|
|
626
|
+
return getChunkedExport(code, chunkName, generateOptions, cache, cacheKey);
|
|
620
627
|
}
|
|
621
628
|
const routeChunkQueryStringPrefix = "?route-chunk=";
|
|
622
629
|
const routeChunkQueryStrings = {
|
|
@@ -910,7 +917,7 @@ async function nodeHttpFetch(request, { signal }) {
|
|
|
910
917
|
return new Promise((resolve, reject) => {
|
|
911
918
|
const req = http.request({
|
|
912
919
|
protocol: url.protocol,
|
|
913
|
-
hostname: url.hostname,
|
|
920
|
+
hostname: url.hostname.replace(/^\[|\]$/g, ""),
|
|
914
921
|
port: url.port || void 0,
|
|
915
922
|
path: url.pathname + url.search,
|
|
916
923
|
method: request.method,
|
|
@@ -960,9 +967,15 @@ async function startPreviewServer(viteConfig) {
|
|
|
960
967
|
}
|
|
961
968
|
}
|
|
962
969
|
function getResolvedUrl(previewServer) {
|
|
963
|
-
const
|
|
964
|
-
|
|
965
|
-
|
|
970
|
+
const printableUrl = previewServer.resolvedUrls?.local[0];
|
|
971
|
+
const address = previewServer.httpServer?.address();
|
|
972
|
+
if (address && typeof address === "object" && address.address !== "::" && address.address !== "0.0.0.0") {
|
|
973
|
+
const protocol = printableUrl ? new URL(printableUrl).protocol : "http:";
|
|
974
|
+
const hostname = address.family === "IPv6" ? `[${address.address}]` : address.address;
|
|
975
|
+
return new URL(`${protocol}//${hostname}:${address.port}/`);
|
|
976
|
+
}
|
|
977
|
+
if (!printableUrl) throw new Error("Prerender: No resolved URL is available from the Vite preview server");
|
|
978
|
+
return new URL(printableUrl);
|
|
966
979
|
}
|
|
967
980
|
//#endregion
|
|
968
981
|
//#region vite/plugin.ts
|
|
@@ -1231,14 +1244,16 @@ const reactRouterVitePlugin = () => {
|
|
|
1231
1244
|
import * as entryServer from ${JSON.stringify(resolveFileUrl(ctx, ctx.entryServerFilePath, { publicPath: ctx.publicPath }))};
|
|
1232
1245
|
${Object.keys(routes).map((key, index) => {
|
|
1233
1246
|
let route = routes[key];
|
|
1234
|
-
if (isSpaMode && key !== "root") return `const route${index} = { default: () => null };`;
|
|
1247
|
+
if (isSpaMode && !isApiOnlyMode(ctx.reactRouterConfig) && key !== "root") return `const route${index} = { default: () => null };`;
|
|
1235
1248
|
else return `import * as route${index} from ${JSON.stringify(resolveFileUrl(ctx, resolveRelativeRouteFilePath(route, ctx.reactRouterConfig), { publicPath: ctx.publicPath }))};`;
|
|
1236
1249
|
}).join("\n")}
|
|
1237
1250
|
export { default as assets } from ${JSON.stringify(virtual$1.serverManifest.id)};
|
|
1238
1251
|
export const assetsBuildDirectory = ${JSON.stringify(path$2.relative(ctx.rootDirectory, getClientBuildDirectory$1(ctx.reactRouterConfig)))};
|
|
1239
1252
|
export const basename = ${JSON.stringify(ctx.reactRouterConfig.basename)};
|
|
1240
1253
|
export const future = ${JSON.stringify(ctx.reactRouterConfig.future)};
|
|
1241
|
-
export const ssr = ${ctx.reactRouterConfig.ssr};
|
|
1254
|
+
export const ssr = ${Boolean(ctx.reactRouterConfig.ssr)};
|
|
1255
|
+
export const unstable_apiOnly = ${isApiOnlyMode(ctx.reactRouterConfig)};
|
|
1256
|
+
export const unstable_apiServerOrigin = ${isApiOnlyMode(ctx.reactRouterConfig) ? JSON.stringify(ctx.reactRouterConfig.unstable_apiServerOrigin) : "undefined"};
|
|
1242
1257
|
export const isSpaMode = ${isSpaMode};
|
|
1243
1258
|
export const prerender = ${JSON.stringify(prerenderPaths)};
|
|
1244
1259
|
export const routeDiscovery = ${JSON.stringify(ctx.reactRouterConfig.routeDiscovery)};
|
|
@@ -1484,7 +1499,7 @@ const reactRouterVitePlugin = () => {
|
|
|
1484
1499
|
invariant(serverEnvironment);
|
|
1485
1500
|
return {
|
|
1486
1501
|
__reactRouterPluginContext: ctx,
|
|
1487
|
-
appType: viteCommand === "serve" && _viteConfigEnv.mode === "production" && ctx.reactRouterConfig.ssr ===
|
|
1502
|
+
appType: viteCommand === "serve" && _viteConfigEnv.mode === "production" && (!ctx.reactRouterConfig.ssr || ctx.reactRouterConfig.ssr === "unstable_api-only") ? isApiOnlyMode(ctx.reactRouterConfig) ? "mpa" : "spa" : "custom",
|
|
1488
1503
|
ssr: {
|
|
1489
1504
|
external: serverEnvironment.resolve?.external,
|
|
1490
1505
|
resolve: serverEnvironment.resolve
|
|
@@ -1717,6 +1732,21 @@ const reactRouterVitePlugin = () => {
|
|
|
1717
1732
|
previewServer.middlewares.use(async (req, res, next) => {
|
|
1718
1733
|
if (!ctx.reactRouterConfig.ssr && (!process.env.hasOwnProperty("IS_RR_BUILD_REQUEST") ? true : process.env.IS_RR_BUILD_REQUEST !== "yes")) return next();
|
|
1719
1734
|
try {
|
|
1735
|
+
if (isApiOnlyMode(ctx.reactRouterConfig) && process.env.IS_RR_BUILD_REQUEST !== "yes") {
|
|
1736
|
+
let { basename, routeDiscovery } = ctx.reactRouterConfig;
|
|
1737
|
+
let manifestPath = routeDiscovery?.mode === "lazy" ? path$2.posix.join(basename, routeDiscovery.manifestPath ?? "/__manifest") : void 0;
|
|
1738
|
+
let pathname = new URL(req.originalUrl ?? req.url ?? "/", "http://localhost").pathname;
|
|
1739
|
+
if (!pathname.endsWith(".data") && pathname !== manifestPath) {
|
|
1740
|
+
let clientBuildDirectory = getClientBuildDirectory$1(ctx.reactRouterConfig);
|
|
1741
|
+
let previewPathname = decodeURIComponent(new URL(req.url ?? "/", "http://localhost").pathname);
|
|
1742
|
+
if (previewPathname.endsWith(".html") && existsSync(path$2.join(clientBuildDirectory, previewPathname))) return next();
|
|
1743
|
+
let fallbackFile = path$2.join(clientBuildDirectory, "__spa-fallback.html");
|
|
1744
|
+
if (!existsSync(fallbackFile)) fallbackFile = path$2.join(clientBuildDirectory, "index.html");
|
|
1745
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
1746
|
+
res.end(await readFile(fallbackFile));
|
|
1747
|
+
return;
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1720
1750
|
let handler = await getHandler();
|
|
1721
1751
|
let request = await fromNodeRequest(req, res);
|
|
1722
1752
|
await sendResponse(res, await handler(request, await reactRouterDevLoadContext(request)));
|
|
@@ -1817,11 +1847,14 @@ const reactRouterVitePlugin = () => {
|
|
|
1817
1847
|
let routeFileName = path$2.basename(routeModuleId);
|
|
1818
1848
|
let sourceExports = await getRouteModuleExports(viteChildCompiler, ctx, routeModuleId);
|
|
1819
1849
|
let { chunkedExports = [] } = options?.ssr ? {} : await detectRouteChunksIfEnabled(cache, ctx, id, code);
|
|
1820
|
-
return
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1850
|
+
return {
|
|
1851
|
+
code: `export { ${sourceExports.filter((exportName) => {
|
|
1852
|
+
let isRouteEntryExport = options?.ssr && SERVER_ONLY_ROUTE_EXPORTS.includes(exportName) || CLIENT_ROUTE_EXPORTS$1.includes(exportName);
|
|
1853
|
+
let isChunkedExport = chunkedExports.includes(exportName);
|
|
1854
|
+
return isRouteEntryExport && !isChunkedExport;
|
|
1855
|
+
}).join(", ")} } from "./${routeFileName}";`,
|
|
1856
|
+
map: { mappings: "" }
|
|
1857
|
+
};
|
|
1825
1858
|
}
|
|
1826
1859
|
},
|
|
1827
1860
|
{
|
|
@@ -1946,7 +1979,8 @@ const reactRouterVitePlugin = () => {
|
|
|
1946
1979
|
if (isRouteChunkModuleId(id)) id = id.split("?")[0];
|
|
1947
1980
|
let route = getRoute(ctx.reactRouterConfig, id);
|
|
1948
1981
|
if (!route) return;
|
|
1949
|
-
|
|
1982
|
+
let isServerEnvironment = isReactRouterServerEnvironment(ctx, this.environment.name);
|
|
1983
|
+
if (!options?.ssr && isSpaModeEnabled(ctx.reactRouterConfig) && !isApiOnlyMode(ctx.reactRouterConfig)) {
|
|
1950
1984
|
let exportNames = getExportNames(code);
|
|
1951
1985
|
let serverOnlyExports = exportNames.filter((exp) => {
|
|
1952
1986
|
if (route.id === "root" && exp === "loader") return false;
|
|
@@ -1967,6 +2001,7 @@ const reactRouterVitePlugin = () => {
|
|
|
1967
2001
|
let [filepath] = id.split("?");
|
|
1968
2002
|
let ast = parse$1(code, { sourceType: "module" });
|
|
1969
2003
|
if (!options?.ssr) removeExports(ast, SERVER_ONLY_ROUTE_EXPORTS);
|
|
2004
|
+
else if (isApiOnlyMode(ctx.reactRouterConfig) && isServerEnvironment && !isPrerenderingEnabled(ctx.reactRouterConfig) && viteCommand === "build" && route.id !== "root") removeExports(ast, CLIENT_ROUTE_EXPORTS$1);
|
|
1970
2005
|
decorateComponentExportsWithProps(ast);
|
|
1971
2006
|
return generate(ast, {
|
|
1972
2007
|
sourceMaps: true,
|
|
@@ -2108,7 +2143,7 @@ const reactRouterVitePlugin = () => {
|
|
|
2108
2143
|
else requests.push(createRouteRequest(prerenderPath, reactRouterConfig));
|
|
2109
2144
|
}
|
|
2110
2145
|
}
|
|
2111
|
-
if (!ctx.reactRouterConfig.ssr) requests.push(createSpaModeRequest(ctx.reactRouterConfig));
|
|
2146
|
+
if (!ctx.reactRouterConfig.ssr || ctx.reactRouterConfig.ssr === "unstable_api-only") requests.push(createSpaModeRequest(ctx.reactRouterConfig));
|
|
2112
2147
|
return requests;
|
|
2113
2148
|
},
|
|
2114
2149
|
async postProcess(request, response, metadata) {
|
|
@@ -2175,7 +2210,7 @@ const reactRouterVitePlugin = () => {
|
|
|
2175
2210
|
async finalize(buildDirectory) {
|
|
2176
2211
|
invariant(viteConfig);
|
|
2177
2212
|
let { ssr } = ctx.reactRouterConfig;
|
|
2178
|
-
if (!ssr) {
|
|
2213
|
+
if (!ssr || ssr === "unstable_api-only") {
|
|
2179
2214
|
let spaFallback = path$2.join(buildDirectory, "__spa-fallback.html");
|
|
2180
2215
|
let index = path$2.join(buildDirectory, "index.html");
|
|
2181
2216
|
let finalSpaPath;
|
|
@@ -2310,7 +2345,10 @@ function isPrerenderingEnabled(reactRouterConfig) {
|
|
|
2310
2345
|
return reactRouterConfig.prerender != null && reactRouterConfig.prerender !== false;
|
|
2311
2346
|
}
|
|
2312
2347
|
function isSpaModeEnabled(reactRouterConfig) {
|
|
2313
|
-
return reactRouterConfig.ssr ===
|
|
2348
|
+
return (!reactRouterConfig.ssr || reactRouterConfig.ssr === "unstable_api-only") && !isPrerenderingEnabled(reactRouterConfig);
|
|
2349
|
+
}
|
|
2350
|
+
function isApiOnlyMode(reactRouterConfig) {
|
|
2351
|
+
return reactRouterConfig.ssr === "unstable_api-only";
|
|
2314
2352
|
}
|
|
2315
2353
|
function getStaticPrerenderPaths(routes) {
|
|
2316
2354
|
let paths = ["/"];
|
|
@@ -2476,7 +2514,10 @@ async function detectRouteChunksIfEnabled(cache, ctx, id, input) {
|
|
|
2476
2514
|
}
|
|
2477
2515
|
async function getRouteChunkIfEnabled(cache, ctx, id, chunkName, input) {
|
|
2478
2516
|
if (!ctx.reactRouterConfig.splitRouteModules) return null;
|
|
2479
|
-
return getRouteChunkCode(await resolveRouteFileCode(ctx, input), chunkName, cache, normalizeRelativeFilePath(id, ctx.reactRouterConfig) + (typeof input === "string" ? "" : "?read")
|
|
2517
|
+
return getRouteChunkCode(await resolveRouteFileCode(ctx, input), chunkName, cache, normalizeRelativeFilePath(id, ctx.reactRouterConfig) + (typeof input === "string" ? "" : "?read"), {
|
|
2518
|
+
sourceMaps: true,
|
|
2519
|
+
sourceFileName: path$2.basename(id.split("?")[0])
|
|
2520
|
+
});
|
|
2480
2521
|
}
|
|
2481
2522
|
function validateRouteChunks$1({ ctx, id, valid }) {
|
|
2482
2523
|
if (isRootRouteModuleId(ctx, id)) return;
|
|
@@ -2665,7 +2706,7 @@ function createDataRequest(prerenderPath, reactRouterConfig, onlyRoutes, isResou
|
|
|
2665
2706
|
let url = new URL(`http://localhost${normalizedPath}`);
|
|
2666
2707
|
if (onlyRoutes?.length) url.searchParams.set("_routes", onlyRoutes.join(","));
|
|
2667
2708
|
return {
|
|
2668
|
-
request: new Request(url),
|
|
2709
|
+
request: new Request(url, { headers: { "X-React-Router-Prerender": "yes" } }),
|
|
2669
2710
|
metadata: {
|
|
2670
2711
|
type: "data",
|
|
2671
2712
|
path: prerenderPath,
|
|
@@ -2675,7 +2716,7 @@ function createDataRequest(prerenderPath, reactRouterConfig, onlyRoutes, isResou
|
|
|
2675
2716
|
}
|
|
2676
2717
|
function createRouteRequest(prerenderPath, reactRouterConfig, data) {
|
|
2677
2718
|
let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(/\/\/+/g, "/");
|
|
2678
|
-
let headers = new Headers();
|
|
2719
|
+
let headers = new Headers({ "X-React-Router-Prerender": "yes" });
|
|
2679
2720
|
if (data) {
|
|
2680
2721
|
let encodedData = encodeURI(data);
|
|
2681
2722
|
if (encodedData.length < 8 * 1024) headers.set("X-React-Router-Prerender-Data", encodedData);
|
|
@@ -2690,8 +2731,13 @@ function createRouteRequest(prerenderPath, reactRouterConfig, data) {
|
|
|
2690
2731
|
}
|
|
2691
2732
|
function createResourceRouteRequest(prerenderPath, reactRouterConfig, requestInit) {
|
|
2692
2733
|
let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(/\/\/+/g, "/").replace(/\/$/g, "");
|
|
2734
|
+
let headers = new Headers(requestInit?.headers);
|
|
2735
|
+
headers.set("X-React-Router-Prerender", "yes");
|
|
2693
2736
|
return {
|
|
2694
|
-
request: new Request(`http://localhost${normalizedPath}`,
|
|
2737
|
+
request: new Request(`http://localhost${normalizedPath}`, {
|
|
2738
|
+
...requestInit,
|
|
2739
|
+
headers
|
|
2740
|
+
}),
|
|
2695
2741
|
metadata: {
|
|
2696
2742
|
type: "resource",
|
|
2697
2743
|
path: prerenderPath
|
|
@@ -2851,6 +2897,38 @@ const ENSURE_CLIENT_ROUTE_MODULE_CHUNK_FOR_HMR = `
|
|
|
2851
2897
|
import * as ___EnsureClientRouteModuleForHMR_REACT___ from "react";
|
|
2852
2898
|
export function EnsureClientRouteModuleForHMR___() { return ___EnsureClientRouteModuleForHMR_REACT___.createElement(___EnsureClientRouteModuleForHMR_REACT___.Fragment, null) }
|
|
2853
2899
|
`;
|
|
2900
|
+
function createEmptySourceMap() {
|
|
2901
|
+
return {
|
|
2902
|
+
version: 3,
|
|
2903
|
+
names: [],
|
|
2904
|
+
sources: [],
|
|
2905
|
+
mappings: ""
|
|
2906
|
+
};
|
|
2907
|
+
}
|
|
2908
|
+
function generateRouteModule(code, map, filename) {
|
|
2909
|
+
const ast = parse$1(code, { sourceType: "module" });
|
|
2910
|
+
const generatorOptions = {
|
|
2911
|
+
sourceMaps: true,
|
|
2912
|
+
sourceFileName: filename,
|
|
2913
|
+
inputSourceMap: map
|
|
2914
|
+
};
|
|
2915
|
+
return {
|
|
2916
|
+
ast,
|
|
2917
|
+
generate: () => generate(ast, generatorOptions)
|
|
2918
|
+
};
|
|
2919
|
+
}
|
|
2920
|
+
function prependUnmappedCode(prefix, generated) {
|
|
2921
|
+
if (generated.map) generated.map.mappings = ";".repeat(prefix.match(/\n/g)?.length ?? 0) + generated.map.mappings;
|
|
2922
|
+
return {
|
|
2923
|
+
code: prefix + generated.code,
|
|
2924
|
+
map: generated.map
|
|
2925
|
+
};
|
|
2926
|
+
}
|
|
2927
|
+
function appendUnmappedCode(generated, code) {
|
|
2928
|
+
if (!generated.code.endsWith("\n") && !code.startsWith("\n")) code = "\n" + code;
|
|
2929
|
+
if (generated.map) generated.map.mappings += ";A".repeat(code.match(/\n/g)?.length ?? 0);
|
|
2930
|
+
generated.code += code;
|
|
2931
|
+
}
|
|
2854
2932
|
function virtualRouteModulesPlugin({ enforceSplitRouteModules, environments: { client = ["client", "ssr"], server = ["rsc"] } = {}, getRouteIdForFile, isRootRouteModule, transformToJs, shouldTransform }) {
|
|
2855
2933
|
let clientEnvironments = new Set(client);
|
|
2856
2934
|
let serverEnvironments = new Set(server);
|
|
@@ -2886,7 +2964,10 @@ function virtualRouteModulesPlugin({ enforceSplitRouteModules, environments: { c
|
|
|
2886
2964
|
}
|
|
2887
2965
|
});
|
|
2888
2966
|
}
|
|
2889
|
-
return {
|
|
2967
|
+
return {
|
|
2968
|
+
code: "\"use client\";\n" + result,
|
|
2969
|
+
map: createEmptySourceMap()
|
|
2970
|
+
};
|
|
2890
2971
|
}
|
|
2891
2972
|
async function createServerRouteEntry(id, code, isRootRouteModule, routeId) {
|
|
2892
2973
|
let result = "";
|
|
@@ -2926,16 +3007,19 @@ ${result}`;
|
|
|
2926
3007
|
}
|
|
2927
3008
|
});
|
|
2928
3009
|
}
|
|
2929
|
-
return {
|
|
3010
|
+
return {
|
|
3011
|
+
code: result,
|
|
3012
|
+
map: createEmptySourceMap()
|
|
3013
|
+
};
|
|
2930
3014
|
}
|
|
2931
|
-
function createServerRouteModule(code) {
|
|
2932
|
-
const ast =
|
|
3015
|
+
function createServerRouteModule(code, map, filename) {
|
|
3016
|
+
const { ast, generate } = generateRouteModule(code, map, filename);
|
|
2933
3017
|
removeExports(ast, CLIENT_ROUTE_EXPORTS);
|
|
2934
|
-
return generate(
|
|
3018
|
+
return generate();
|
|
2935
3019
|
}
|
|
2936
|
-
async function createClientRouteModuleChunk(id, code, chunk, routeId, isRootRouteModule, isDevMode) {
|
|
3020
|
+
async function createClientRouteModuleChunk(id, code, chunk, routeId, isRootRouteModule, isDevMode, map, filename) {
|
|
2937
3021
|
let routeChunks = detectRouteChunks(cache, id, code, isRootRouteModule);
|
|
2938
|
-
const ast =
|
|
3022
|
+
const { ast, generate } = generateRouteModule(code, map, filename);
|
|
2939
3023
|
const { staticExports } = await parseRouteExports(code);
|
|
2940
3024
|
if (chunk === "shared") removeExports(ast, [...SERVER_ROUTE_EXPORTS, ...routeChunks.chunkedExports]);
|
|
2941
3025
|
else {
|
|
@@ -2943,33 +3027,26 @@ ${result}`;
|
|
|
2943
3027
|
toRemove.delete(chunk);
|
|
2944
3028
|
removeExports(ast, Array.from(toRemove));
|
|
2945
3029
|
}
|
|
2946
|
-
let result = "\"use client\";\n"
|
|
3030
|
+
let result = prependUnmappedCode("\"use client\";\n", generate());
|
|
2947
3031
|
if (chunk === "shared") {
|
|
2948
|
-
if (isRootRouteModule && !staticExports.includes("ErrorBoundary") && !staticExports.includes("ServerErrorBoundary"))
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
result += `}\n`;
|
|
2955
|
-
}
|
|
2956
|
-
result += ENSURE_CLIENT_ROUTE_MODULE_CHUNK_FOR_HMR;
|
|
3032
|
+
if (isRootRouteModule && !staticExports.includes("ErrorBoundary") && !staticExports.includes("ServerErrorBoundary")) appendUnmappedCode(result, `
|
|
3033
|
+
import { createElement as __rr_createElement } from "react";
|
|
3034
|
+
import { UNSAFE_RSCDefaultRootErrorBoundary } from "react-router";
|
|
3035
|
+
export function ErrorBoundary() {
|
|
3036
|
+
return __rr_createElement(UNSAFE_RSCDefaultRootErrorBoundary, { hasRootLayout: ${staticExports.includes("Layout") || staticExports.includes("ServerLayout")} });\n}\n`);
|
|
3037
|
+
appendUnmappedCode(result, ENSURE_CLIENT_ROUTE_MODULE_CHUNK_FOR_HMR);
|
|
2957
3038
|
}
|
|
2958
3039
|
let hasAction = staticExports.includes("action");
|
|
2959
3040
|
let hasLoader = staticExports.includes("loader");
|
|
2960
3041
|
let hasComponent = staticExports.includes("default") || staticExports.includes("ServerComponent");
|
|
2961
3042
|
let hasErrorBoundary = staticExports.includes("ErrorBoundary") || staticExports.includes("ServerErrorBoundary");
|
|
2962
|
-
if (isDevMode) {
|
|
2963
|
-
result += `export function ReactRouterHMRMeta___() {return null;};\n`;
|
|
2964
|
-
result += `Object.assign(ReactRouterHMRMeta___, {
|
|
3043
|
+
if (isDevMode) appendUnmappedCode(result, `export function ReactRouterHMRMeta___() {return null;};\nObject.assign(ReactRouterHMRMeta___, {
|
|
2965
3044
|
hasAction: ${JSON.stringify(hasAction)},
|
|
2966
3045
|
hasComponent: ${JSON.stringify(hasComponent)},
|
|
2967
3046
|
hasErrorBoundary: ${JSON.stringify(hasErrorBoundary)},
|
|
2968
3047
|
hasLoader: ${JSON.stringify(hasLoader)},
|
|
2969
3048
|
hasClientLoader: ${JSON.stringify(staticExports.includes("clientLoader"))},
|
|
2970
|
-
});\n
|
|
2971
|
-
result += `\nif (import.meta.hot) {\n`;
|
|
2972
|
-
result += ` import.meta.hot.accept((mod) => {
|
|
3049
|
+
});\n\nif (import.meta.hot) {\n import.meta.hot.accept((mod) => {
|
|
2973
3050
|
if (typeof __reactRouterDataRouter === "object") {
|
|
2974
3051
|
__reactRouterDataRouter._updateRoutesForHMR(new Map([[${JSON.stringify(routeId)}, {
|
|
2975
3052
|
routeModule: mod,
|
|
@@ -2983,10 +3060,8 @@ ${result}`;
|
|
|
2983
3060
|
}
|
|
2984
3061
|
}
|
|
2985
3062
|
});
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
}
|
|
2989
|
-
return { code: result };
|
|
3063
|
+
}\n`);
|
|
3064
|
+
return result;
|
|
2990
3065
|
}
|
|
2991
3066
|
return {
|
|
2992
3067
|
name: "react-router-rsc-virtual-route-modules",
|
|
@@ -2998,12 +3073,13 @@ ${result}`;
|
|
|
2998
3073
|
let isClientEnvironment = clientEnvironments.has(this.environment.name);
|
|
2999
3074
|
let isServerEnvironment = serverEnvironments.has(this.environment.name);
|
|
3000
3075
|
if (!isClientEnvironment && !isServerEnvironment) return;
|
|
3001
|
-
let
|
|
3076
|
+
let transformed = await transformToJs(_code, filename);
|
|
3077
|
+
let code = transformed.code;
|
|
3002
3078
|
let searchParams = rest.length > 0 ? new URLSearchParams(rest.join("?")) : null;
|
|
3003
3079
|
let clientRouteModuleType = searchParams?.get("client-route-module");
|
|
3004
3080
|
let isServerRouteModule = searchParams?.has("server-route-module");
|
|
3005
|
-
if (clientRouteModuleType) return await createClientRouteModuleChunk(id, code, clientRouteModuleType, routeId, isRootRouteModule(filename), this.environment.mode === "dev");
|
|
3006
|
-
if (isServerRouteModule) return createServerRouteModule(code);
|
|
3081
|
+
if (clientRouteModuleType) return await createClientRouteModuleChunk(id, code, clientRouteModuleType, routeId, isRootRouteModule(filename), this.environment.mode === "dev", transformed.map, filename);
|
|
3082
|
+
if (isServerRouteModule) return createServerRouteModule(code, transformed.map, filename);
|
|
3007
3083
|
if (isClientEnvironment) return await createClientRouteEntry(id, code, isRootRouteModule(filename), routeId);
|
|
3008
3084
|
return await createServerRouteEntry(id, code, isRootRouteModule(filename), routeId);
|
|
3009
3085
|
}
|
|
@@ -3169,7 +3245,7 @@ function reactRouterRSCVitePlugin() {
|
|
|
3169
3245
|
await preloadVite();
|
|
3170
3246
|
let vite = getVite();
|
|
3171
3247
|
let lang = getTransformLanguage(filename);
|
|
3172
|
-
return
|
|
3248
|
+
return "transformWithOxc" in vite && typeof vite.transformWithOxc === "function" ? await vite.transformWithOxc(code, filename, {
|
|
3173
3249
|
lang,
|
|
3174
3250
|
jsx: {
|
|
3175
3251
|
runtime: "automatic",
|
|
@@ -3182,7 +3258,7 @@ function reactRouterRSCVitePlugin() {
|
|
|
3182
3258
|
format: "esm",
|
|
3183
3259
|
jsx: "automatic",
|
|
3184
3260
|
jsxDev: viteCommand !== "build"
|
|
3185
|
-
})
|
|
3261
|
+
});
|
|
3186
3262
|
}
|
|
3187
3263
|
async function getClientVersion(source) {
|
|
3188
3264
|
const digest = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(source));
|
|
@@ -3211,6 +3287,7 @@ function reactRouterRSCVitePlugin() {
|
|
|
3211
3287
|
if (userConfig.buildEnd) errors.push("buildEnd");
|
|
3212
3288
|
if (userConfig.presets?.length) errors.push("presets");
|
|
3213
3289
|
if (userConfig.serverBundles) errors.push("serverBundles");
|
|
3290
|
+
if (userConfig.ssr === "unstable_api-only") errors.push("ssr: \"unstable_api-only\"");
|
|
3214
3291
|
if (errors.length) return `RSC Framework Mode does not currently support the following React Router config:\n${errors.map((x) => ` - ${x}`).join("\n")}\n`;
|
|
3215
3292
|
}
|
|
3216
3293
|
});
|
|
@@ -3642,7 +3719,7 @@ function createRSCOptimizeDepsRouteModulesPlugin({ routeFiles, transformToJs })
|
|
|
3642
3719
|
let normalizedFilename = getVite().normalizePath(filename);
|
|
3643
3720
|
if (!routeFiles.has(normalizedFilename)) return;
|
|
3644
3721
|
return {
|
|
3645
|
-
code: createClientRouteModuleForOptimizeDepsScan(await transformToJs(code, filename)).code,
|
|
3722
|
+
code: createClientRouteModuleForOptimizeDepsScan((await transformToJs(code, filename)).code).code,
|
|
3646
3723
|
map: null,
|
|
3647
3724
|
moduleType: "js"
|
|
3648
3725
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-router/dev",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "8.
|
|
4
|
+
"version": "8.5.0",
|
|
5
5
|
"description": "Dev tools and CLI for React Router",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"react",
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
"semver": "^7.8.1",
|
|
108
108
|
"tinyglobby": "^0.2.16",
|
|
109
109
|
"valibot": "^1.4.1",
|
|
110
|
-
"@react-router/node": "8.
|
|
110
|
+
"@react-router/node": "8.5.0"
|
|
111
111
|
},
|
|
112
112
|
"devDependencies": {
|
|
113
113
|
"@babel/plugin-syntax-jsx": "^7.29.7",
|
|
@@ -132,8 +132,8 @@
|
|
|
132
132
|
"vite": "^7.0.0",
|
|
133
133
|
"wireit": "0.14.12",
|
|
134
134
|
"wrangler": "^4.95.0",
|
|
135
|
-
"
|
|
136
|
-
"react-router": "
|
|
135
|
+
"react-router": "^8.5.0",
|
|
136
|
+
"@react-router/serve": "8.5.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/serve": "^8.
|
|
145
|
-
"react-router": "^8.
|
|
144
|
+
"@react-router/serve": "^8.5.0",
|
|
145
|
+
"react-router": "^8.5.0"
|
|
146
146
|
},
|
|
147
147
|
"peerDependenciesMeta": {
|
|
148
148
|
"@vitejs/plugin-rsc": {
|