@react-router/dev 0.0.0-experimental-66d5af831 → 0.0.0-experimental-8677247c0
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 +86 -0
- package/dist/cli/index.js +27 -5
- package/dist/config.d.ts +0 -1
- package/dist/config.js +1 -1
- package/dist/routes.js +1 -1
- package/dist/vite/cloudflare.js +1 -2
- package/dist/vite.js +104 -36
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,91 @@
|
|
|
1
1
|
# `@react-router/dev`
|
|
2
2
|
|
|
3
|
+
## 7.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Generate a "SPA fallback" HTML file for scenarios where applications are prerendering the `/` route with `ssr:false` ([#12948](https://github.com/remix-run/react-router/pull/12948))
|
|
8
|
+
|
|
9
|
+
- If you specify `ssr:false` without a `prerender` config, this is considered "SPA Mode" and the generated `index.html` file will only render down to the root route and will be able to hydrate for any valid application path
|
|
10
|
+
- If you specify `ssr:false` with a `prerender` config but _do not_ include the `/` path (i.e., `prerender: ['/blog/post']`), then we still generate a "SPA Mode" `index.html` file that can hydrate for any path in the application
|
|
11
|
+
- However, previously if you specified `ssr:false` and included the `/` path in your `prerender` config, we would prerender the `/` route into `index.html` as a non-SPA page
|
|
12
|
+
- The generated HTML would include the root index route which prevented hydration for any other paths
|
|
13
|
+
- With this change, we now generate a "SPA Mode" file in `__spa-fallback.html` that will allow you to hydrate for any non-prerendered paths
|
|
14
|
+
- You can serve this file from your static file server for any paths that would otherwise 404 if you only want to pre-render _some_ routes in your `ssr:false` app and serve the others as a SPA
|
|
15
|
+
- `npx sirv-cli build/client --single __spa-fallback.html`
|
|
16
|
+
|
|
17
|
+
- Allow a `loader` in the root route in SPA mode because it can be called/server-rendered at build time ([#12948](https://github.com/remix-run/react-router/pull/12948))
|
|
18
|
+
|
|
19
|
+
- `Route.HydrateFallbackProps` now also receives `loaderData`
|
|
20
|
+
- This will be defined so long as the `HydrateFallback` is rendering while _children_ routes are loading
|
|
21
|
+
- This will be `undefined` if the `HydrateFallback` is rendering because the route has it's own hydrating `clientLoader`
|
|
22
|
+
- In SPA mode, this will allow you to render loader root data into the SPA `index.html`
|
|
23
|
+
|
|
24
|
+
- New type-safe `href` utility that guarantees links point to actual paths in your app ([#13012](https://github.com/remix-run/react-router/pull/13012))
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { href } from "react-router";
|
|
28
|
+
|
|
29
|
+
export default function Component() {
|
|
30
|
+
const link = href("/blog/:slug", { slug: "my-first-post" });
|
|
31
|
+
return (
|
|
32
|
+
<main>
|
|
33
|
+
<Link to={href("/products/:id", { id: "asdf" })} />
|
|
34
|
+
<NavLink to={href("/:lang?/about", { lang: "en" })} />
|
|
35
|
+
</main>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
- Handle custom `envDir` in Vite config ([#12969](https://github.com/remix-run/react-router/pull/12969))
|
|
43
|
+
|
|
44
|
+
- Fix typegen for repeated params ([#13012](https://github.com/remix-run/react-router/pull/13012))
|
|
45
|
+
|
|
46
|
+
In React Router, path parameters are keyed by their name.
|
|
47
|
+
So for a path pattern like `/a/:id/b/:id?/c/:id`, the last `:id` will set the value for `id` in `useParams` and the `params` prop.
|
|
48
|
+
For example, `/a/1/b/2/c/3` will result in the value `{ id: 3 }` at runtime.
|
|
49
|
+
|
|
50
|
+
Previously, generated types for params incorrectly modeled repeated params with an array.
|
|
51
|
+
So `/a/1/b/2/c/3` generated a type like `{ id: [1,2,3] }`.
|
|
52
|
+
|
|
53
|
+
To be consistent with runtime behavior, the generated types now correctly model the "last one wins" semantics of path parameters.
|
|
54
|
+
So `/a/1/b/2/c/3` now generates a type like `{ id: 3 }`.
|
|
55
|
+
|
|
56
|
+
- Fix CLI parsing to allow argumentless `npx react-router` usage ([#12925](https://github.com/remix-run/react-router/pull/12925))
|
|
57
|
+
|
|
58
|
+
- Fix `ArgError: unknown or unexpected option: --version` when running `react-router --version` ([#13012](https://github.com/remix-run/react-router/pull/13012))
|
|
59
|
+
|
|
60
|
+
- Skip action-only resource routes when using `prerender:true` ([#13004](https://github.com/remix-run/react-router/pull/13004))
|
|
61
|
+
|
|
62
|
+
- Enhance invalid export detection when using `ssr:false` ([#12948](https://github.com/remix-run/react-router/pull/12948))
|
|
63
|
+
|
|
64
|
+
- `headers`/`action` are prohibited in all routes with `ssr:false` because there will be no runtime server on which to run them
|
|
65
|
+
- `loader` functions are more nuanced and depend on whether a given route is prerendered
|
|
66
|
+
- When using `ssr:false` without a `prerender` config, only the `root` route can have a `loader`
|
|
67
|
+
- This is "SPA mode" which generates a single `index.html` file with the root route `HydrateFallback` so it is capable of hydrating for any path in your application - therefore we can only call a root route `loader` at build time
|
|
68
|
+
- When using `ssr:false` with a `prerender` config, you can export a `loader` from routes matched by one of the `prerender` paths because those routes will be server rendered at build time
|
|
69
|
+
- Exporting a `loader` from a route that is never matched by a `prerender` path will throw a build time error because there will be no runtime server to ever run the loader
|
|
70
|
+
|
|
71
|
+
- Limit prerendered resource route `.data` files to only the target route ([#13004](https://github.com/remix-run/react-router/pull/13004))
|
|
72
|
+
|
|
73
|
+
- Add unstable support for splitting route modules in framework mode via `future.unstable_splitRouteModules` ([#11871](https://github.com/remix-run/react-router/pull/11871))
|
|
74
|
+
|
|
75
|
+
- Fix prerendering of binary files ([#13039](https://github.com/remix-run/react-router/pull/13039))
|
|
76
|
+
|
|
77
|
+
- Add `future.unstable_viteEnvironmentApi` flag to enable experimental Vite Environment API support ([#12936](https://github.com/remix-run/react-router/pull/12936))
|
|
78
|
+
|
|
79
|
+
- Disable Lazy Route Discovery for all `ssr:false` apps and not just "SPA Mode" because there is no runtime server to serve the search-param-configured `__manifest` requests ([#12894](https://github.com/remix-run/react-router/pull/12894))
|
|
80
|
+
|
|
81
|
+
- We previously only disabled this for "SPA Mode" which is `ssr:false` and no `prerender` config but we realized it should apply to all `ssr:false` apps, including those prerendering multiple pages
|
|
82
|
+
- In those `prerender` scenarios we would prerender the `/__manifest` file assuming the static file server would serve it but that makes some unneccesary assumptions about the static file server behaviors
|
|
83
|
+
|
|
84
|
+
- Updated dependencies:
|
|
85
|
+
- `react-router@7.2.0`
|
|
86
|
+
- `@react-router/node@7.2.0`
|
|
87
|
+
- `@react-router/serve@7.2.0`
|
|
88
|
+
|
|
3
89
|
## 7.1.5
|
|
4
90
|
|
|
5
91
|
### Patch Changes
|
package/dist/cli/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* @react-router/dev v0.0.0-experimental-
|
|
3
|
+
* @react-router/dev v0.0.0-experimental-8677247c0
|
|
4
4
|
*
|
|
5
5
|
* Copyright (c) Remix Software Inc.
|
|
6
6
|
*
|
|
@@ -389,7 +389,6 @@ async function resolveConfig({
|
|
|
389
389
|
);
|
|
390
390
|
}
|
|
391
391
|
let future = {
|
|
392
|
-
turboV3: reactRouterUserConfig.future?.turboV3 ?? false,
|
|
393
392
|
unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false,
|
|
394
393
|
unstable_splitRouteModules: reactRouterUserConfig.future?.unstable_splitRouteModules ?? false,
|
|
395
394
|
unstable_viteEnvironmentApi: reactRouterUserConfig.future?.unstable_viteEnvironmentApi ?? false
|
|
@@ -945,7 +944,6 @@ var init_styles = __esm({
|
|
|
945
944
|
path6 = __toESM(require("path"));
|
|
946
945
|
import_react_router = require("react-router");
|
|
947
946
|
init_resolve_file_url();
|
|
948
|
-
init_vite();
|
|
949
947
|
cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
|
|
950
948
|
cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
|
|
951
949
|
}
|
|
@@ -1364,9 +1362,26 @@ async function getEnvironmentOptionsResolvers(ctx, buildManifest, viteCommand) {
|
|
|
1364
1362
|
rollupOptions: {
|
|
1365
1363
|
input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id
|
|
1366
1364
|
}
|
|
1367
|
-
}
|
|
1365
|
+
},
|
|
1366
|
+
optimizeDeps: ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteUserConfig.environments?.ssr?.optimizeDeps?.noDiscovery === false ? {
|
|
1367
|
+
entries: [
|
|
1368
|
+
vite2.normalizePath(ctx.entryServerFilePath),
|
|
1369
|
+
...Object.values(ctx.reactRouterConfig.routes).map(
|
|
1370
|
+
(route) => resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
|
|
1371
|
+
)
|
|
1372
|
+
],
|
|
1373
|
+
include: [
|
|
1374
|
+
"react",
|
|
1375
|
+
"react/jsx-dev-runtime",
|
|
1376
|
+
"react-dom/server",
|
|
1377
|
+
"react-router"
|
|
1378
|
+
]
|
|
1379
|
+
} : void 0
|
|
1368
1380
|
});
|
|
1369
1381
|
}
|
|
1382
|
+
if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteCommand === "serve") {
|
|
1383
|
+
environmentOptionsResolvers[CSS_DEV_HELPER_ENVIRONMENT_NAME] = () => ({});
|
|
1384
|
+
}
|
|
1370
1385
|
return environmentOptionsResolvers;
|
|
1371
1386
|
}
|
|
1372
1387
|
function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
|
|
@@ -1381,7 +1396,7 @@ function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
|
|
|
1381
1396
|
function isNonNullable(x) {
|
|
1382
1397
|
return x != null;
|
|
1383
1398
|
}
|
|
1384
|
-
var import_node_crypto, path7, url, fse, babel2, import_react_router2, import_es_module_lexer, import_pick3, import_jsesc, import_picocolors4, import_kebabCase, BUILD_CLIENT_ROUTE_QUERY_STRING, SSR_BUNDLE_PREFIX, virtualHmrRuntime, virtualInjectHmrRuntime, virtual, getServerBuildDirectory, getClientBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER;
|
|
1399
|
+
var import_node_crypto, path7, url, fse, babel2, import_react_router2, import_es_module_lexer, import_pick3, import_jsesc, import_picocolors4, import_kebabCase, BUILD_CLIENT_ROUTE_QUERY_STRING, SSR_BUNDLE_PREFIX, CSS_DEV_HELPER_ENVIRONMENT_NAME, virtualHmrRuntime, virtualInjectHmrRuntime, resolveRelativeRouteFilePath, virtual, getServerBuildDirectory, getClientBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER;
|
|
1385
1400
|
var init_plugin = __esm({
|
|
1386
1401
|
"vite/plugin.ts"() {
|
|
1387
1402
|
"use strict";
|
|
@@ -1411,8 +1426,15 @@ var init_plugin = __esm({
|
|
|
1411
1426
|
init_with_props();
|
|
1412
1427
|
BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-route";
|
|
1413
1428
|
SSR_BUNDLE_PREFIX = "ssrBundle_";
|
|
1429
|
+
CSS_DEV_HELPER_ENVIRONMENT_NAME = "__react_router_css_dev_helper__";
|
|
1414
1430
|
virtualHmrRuntime = create("hmr-runtime");
|
|
1415
1431
|
virtualInjectHmrRuntime = create("inject-hmr-runtime");
|
|
1432
|
+
resolveRelativeRouteFilePath = (route, reactRouterConfig) => {
|
|
1433
|
+
let vite2 = getVite();
|
|
1434
|
+
let file = route.file;
|
|
1435
|
+
let fullPath = path7.resolve(reactRouterConfig.appDirectory, file);
|
|
1436
|
+
return vite2.normalizePath(fullPath);
|
|
1437
|
+
};
|
|
1416
1438
|
virtual = {
|
|
1417
1439
|
serverBuild: create("server-build"),
|
|
1418
1440
|
serverManifest: create("server-manifest"),
|
package/dist/config.d.ts
CHANGED
|
@@ -37,7 +37,6 @@ type ServerBundlesBuildManifest = BaseBuildManifest & {
|
|
|
37
37
|
};
|
|
38
38
|
type ServerModuleFormat = "esm" | "cjs";
|
|
39
39
|
interface FutureConfig {
|
|
40
|
-
turboV3: boolean;
|
|
41
40
|
unstable_optimizeDeps: boolean;
|
|
42
41
|
/**
|
|
43
42
|
* Automatically split route modules into multiple chunks when possible.
|
package/dist/config.js
CHANGED
package/dist/routes.js
CHANGED
package/dist/vite/cloudflare.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/dev v0.0.0-experimental-
|
|
2
|
+
* @react-router/dev v0.0.0-experimental-8677247c0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -477,7 +477,6 @@ async function resolveConfig({
|
|
|
477
477
|
);
|
|
478
478
|
}
|
|
479
479
|
let future = {
|
|
480
|
-
turboV3: reactRouterUserConfig.future?.turboV3 ?? false,
|
|
481
480
|
unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false,
|
|
482
481
|
unstable_splitRouteModules: reactRouterUserConfig.future?.unstable_splitRouteModules ?? false,
|
|
483
482
|
unstable_viteEnvironmentApi: reactRouterUserConfig.future?.unstable_viteEnvironmentApi ?? false
|
package/dist/vite.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/dev v0.0.0-experimental-
|
|
2
|
+
* @react-router/dev v0.0.0-experimental-8677247c0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -453,7 +453,6 @@ async function resolveConfig({
|
|
|
453
453
|
);
|
|
454
454
|
}
|
|
455
455
|
let future = {
|
|
456
|
-
turboV3: reactRouterUserConfig.future?.turboV3 ?? false,
|
|
457
456
|
unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false,
|
|
458
457
|
unstable_splitRouteModules: reactRouterUserConfig.future?.unstable_splitRouteModules ?? false,
|
|
459
458
|
unstable_viteEnvironmentApi: reactRouterUserConfig.future?.unstable_viteEnvironmentApi ?? false
|
|
@@ -964,15 +963,12 @@ var isCssUrlWithoutSideEffects = (url2) => {
|
|
|
964
963
|
}
|
|
965
964
|
return false;
|
|
966
965
|
};
|
|
967
|
-
var injectQuery = (url2, query) => url2.includes("?") ? url2.replace("?", `?${query}&`) : `${url2}?${query}`;
|
|
968
966
|
var getStylesForFiles = async ({
|
|
969
967
|
viteDevServer,
|
|
970
968
|
rootDirectory,
|
|
971
|
-
|
|
969
|
+
loadCssContents,
|
|
972
970
|
files
|
|
973
971
|
}) => {
|
|
974
|
-
let vite2 = getVite();
|
|
975
|
-
let viteMajor = parseInt(vite2.version.split(".")[0], 10);
|
|
976
972
|
let styles = {};
|
|
977
973
|
let deps = /* @__PURE__ */ new Set();
|
|
978
974
|
try {
|
|
@@ -1001,21 +997,9 @@ var getStylesForFiles = async ({
|
|
|
1001
997
|
for (let dep of deps) {
|
|
1002
998
|
if (dep.file && isCssFile(dep.file) && !isCssUrlWithoutSideEffects(dep.url)) {
|
|
1003
999
|
try {
|
|
1004
|
-
|
|
1005
|
-
// We need the ?inline query in Vite v6 when loading CSS in SSR
|
|
1006
|
-
// since it does not expose the default export for CSS in a
|
|
1007
|
-
// server environment. This is to align with non-SSR
|
|
1008
|
-
// environments. For backwards compatibility with v5 we keep
|
|
1009
|
-
// using the URL without ?inline query because the HMR code was
|
|
1010
|
-
// relying on the implicit SSR-client module graph relationship.
|
|
1011
|
-
viteMajor >= 6 ? injectQuery(dep.url, "inline") : dep.url
|
|
1012
|
-
)).default;
|
|
1013
|
-
if (css === void 0) {
|
|
1014
|
-
throw new Error();
|
|
1015
|
-
}
|
|
1016
|
-
styles[dep.url] = css;
|
|
1000
|
+
styles[dep.url] = await loadCssContents(viteDevServer, dep);
|
|
1017
1001
|
} catch {
|
|
1018
|
-
console.warn(`
|
|
1002
|
+
console.warn(`Failed to load CSS for ${dep.file}`);
|
|
1019
1003
|
}
|
|
1020
1004
|
}
|
|
1021
1005
|
}
|
|
@@ -1074,7 +1058,7 @@ var getStylesForUrl = async ({
|
|
|
1074
1058
|
rootDirectory,
|
|
1075
1059
|
reactRouterConfig,
|
|
1076
1060
|
entryClientFilePath,
|
|
1077
|
-
|
|
1061
|
+
loadCssContents,
|
|
1078
1062
|
build,
|
|
1079
1063
|
url: url2
|
|
1080
1064
|
}) => {
|
|
@@ -1089,7 +1073,7 @@ var getStylesForUrl = async ({
|
|
|
1089
1073
|
let styles = await getStylesForFiles({
|
|
1090
1074
|
viteDevServer,
|
|
1091
1075
|
rootDirectory,
|
|
1092
|
-
|
|
1076
|
+
loadCssContents,
|
|
1093
1077
|
files: [
|
|
1094
1078
|
// Always include the client entry file when crawling the module graph for CSS
|
|
1095
1079
|
path5.relative(rootDirectory, entryClientFilePath),
|
|
@@ -1968,6 +1952,7 @@ var CLIENT_ROUTE_EXPORTS = [
|
|
|
1968
1952
|
];
|
|
1969
1953
|
var BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-route";
|
|
1970
1954
|
var SSR_BUNDLE_PREFIX = "ssrBundle_";
|
|
1955
|
+
var CSS_DEV_HELPER_ENVIRONMENT_NAME = "__react_router_css_dev_helper__";
|
|
1971
1956
|
function isSeverBundleEnvironmentName(name) {
|
|
1972
1957
|
return name.startsWith(SSR_BUNDLE_PREFIX);
|
|
1973
1958
|
}
|
|
@@ -2159,6 +2144,7 @@ var getServerBuildDirectory = (ctx, { serverBundleId } = {}) => path6.join(
|
|
|
2159
2144
|
...serverBundleId ? [serverBundleId] : []
|
|
2160
2145
|
);
|
|
2161
2146
|
var getClientBuildDirectory = (reactRouterConfig) => path6.join(reactRouterConfig.buildDirectory, "client");
|
|
2147
|
+
var injectQuery = (url2, query) => url2.includes("?") ? url2.replace("?", `?${query}&`) : `${url2}?${query}`;
|
|
2162
2148
|
var defaultEntriesDir = path6.resolve(
|
|
2163
2149
|
path6.dirname(require.resolve("@react-router/dev/package.json")),
|
|
2164
2150
|
"dist",
|
|
@@ -2415,6 +2401,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2415
2401
|
reactRouterServerManifest
|
|
2416
2402
|
};
|
|
2417
2403
|
};
|
|
2404
|
+
let currentReactRouterManifestForDev = null;
|
|
2418
2405
|
let getReactRouterManifestForDev = async () => {
|
|
2419
2406
|
let routes = {};
|
|
2420
2407
|
let routeManifestExports = await getRouteManifestModuleExports(
|
|
@@ -2471,7 +2458,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2471
2458
|
imports: []
|
|
2472
2459
|
};
|
|
2473
2460
|
}
|
|
2474
|
-
|
|
2461
|
+
let reactRouterManifestForDev = {
|
|
2475
2462
|
version: String(Math.random()),
|
|
2476
2463
|
url: combineURLs(ctx.publicPath, virtual.browserManifest.url),
|
|
2477
2464
|
hmr: {
|
|
@@ -2486,6 +2473,42 @@ var reactRouterVitePlugin = () => {
|
|
|
2486
2473
|
},
|
|
2487
2474
|
routes
|
|
2488
2475
|
};
|
|
2476
|
+
currentReactRouterManifestForDev = reactRouterManifestForDev;
|
|
2477
|
+
return reactRouterManifestForDev;
|
|
2478
|
+
};
|
|
2479
|
+
const loadCssContents = async (viteDevServer, dep) => {
|
|
2480
|
+
invariant(
|
|
2481
|
+
viteCommand === "serve",
|
|
2482
|
+
"loadCssContents is only available in dev mode"
|
|
2483
|
+
);
|
|
2484
|
+
if (dep.file && isCssModulesFile(dep.file)) {
|
|
2485
|
+
return cssModulesManifest[dep.file];
|
|
2486
|
+
}
|
|
2487
|
+
const vite2 = getVite();
|
|
2488
|
+
const viteMajor = parseInt(vite2.version.split(".")[0], 10);
|
|
2489
|
+
const url2 = viteMajor >= 6 ? (
|
|
2490
|
+
// We need the ?inline query in Vite v6 when loading CSS in SSR
|
|
2491
|
+
// since it does not expose the default export for CSS in a
|
|
2492
|
+
// server environment. This is to align with non-SSR
|
|
2493
|
+
// environments. For backwards compatibility with v5 we keep
|
|
2494
|
+
// using the URL without ?inline query because the HMR code was
|
|
2495
|
+
// relying on the implicit SSR-client module graph relationship.
|
|
2496
|
+
injectQuery(dep.url, "inline")
|
|
2497
|
+
) : dep.url;
|
|
2498
|
+
let cssMod;
|
|
2499
|
+
if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi) {
|
|
2500
|
+
const cssDevHelperEnvironment = viteDevServer.environments[CSS_DEV_HELPER_ENVIRONMENT_NAME];
|
|
2501
|
+
invariant(cssDevHelperEnvironment, "Missing CSS dev helper environment");
|
|
2502
|
+
invariant(vite2.isRunnableDevEnvironment(cssDevHelperEnvironment));
|
|
2503
|
+
cssMod = await cssDevHelperEnvironment.runner.import(url2);
|
|
2504
|
+
} else {
|
|
2505
|
+
cssMod = await viteDevServer.ssrLoadModule(url2);
|
|
2506
|
+
}
|
|
2507
|
+
invariant(
|
|
2508
|
+
typeof cssMod === "object" && cssMod !== null && "default" in cssMod && typeof cssMod.default === "string",
|
|
2509
|
+
`Failed to load CSS for ${dep.file ?? dep.url}`
|
|
2510
|
+
);
|
|
2511
|
+
return cssMod.default;
|
|
2489
2512
|
};
|
|
2490
2513
|
return [
|
|
2491
2514
|
{
|
|
@@ -2664,6 +2687,8 @@ var reactRouterVitePlugin = () => {
|
|
|
2664
2687
|
}
|
|
2665
2688
|
viteChildCompiler = await vite2.createServer({
|
|
2666
2689
|
...viteUserConfig,
|
|
2690
|
+
// Ensure child compiler cannot overwrite the default cache directory
|
|
2691
|
+
cacheDir: "node_modules/.vite-child-compiler",
|
|
2667
2692
|
mode: viteConfig.mode,
|
|
2668
2693
|
server: {
|
|
2669
2694
|
watch: viteConfig.command === "build" ? null : void 0,
|
|
@@ -2675,7 +2700,23 @@ var reactRouterVitePlugin = () => {
|
|
|
2675
2700
|
plugins: [
|
|
2676
2701
|
...(childCompilerConfigFile.config.plugins ?? []).flat().filter(
|
|
2677
2702
|
(plugin2) => typeof plugin2 === "object" && plugin2 !== null && "name" in plugin2 && plugin2.name !== "react-router" && plugin2.name !== "react-router:route-exports" && plugin2.name !== "react-router:hmr-updates"
|
|
2678
|
-
)
|
|
2703
|
+
),
|
|
2704
|
+
{
|
|
2705
|
+
name: "react-router:override-optimize-deps",
|
|
2706
|
+
config(userConfig) {
|
|
2707
|
+
if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && userConfig.environments) {
|
|
2708
|
+
for (const environmentName of Object.keys(
|
|
2709
|
+
userConfig.environments
|
|
2710
|
+
)) {
|
|
2711
|
+
userConfig.environments[environmentName].optimizeDeps = {
|
|
2712
|
+
noDiscovery: true
|
|
2713
|
+
};
|
|
2714
|
+
}
|
|
2715
|
+
} else {
|
|
2716
|
+
userConfig.optimizeDeps = { noDiscovery: true };
|
|
2717
|
+
}
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2679
2720
|
]
|
|
2680
2721
|
});
|
|
2681
2722
|
await viteChildCompiler.pluginContainer.buildStart({});
|
|
@@ -2712,7 +2753,7 @@ var reactRouterVitePlugin = () => {
|
|
|
2712
2753
|
entryClientFilePath: ctx.entryClientFilePath,
|
|
2713
2754
|
reactRouterConfig: ctx.reactRouterConfig,
|
|
2714
2755
|
viteDevServer,
|
|
2715
|
-
|
|
2756
|
+
loadCssContents,
|
|
2716
2757
|
build,
|
|
2717
2758
|
url: url2
|
|
2718
2759
|
});
|
|
@@ -3232,8 +3273,7 @@ var reactRouterVitePlugin = () => {
|
|
|
3232
3273
|
let route = getRoute(ctx.reactRouterConfig, file);
|
|
3233
3274
|
let hmrEventData = { route: null };
|
|
3234
3275
|
if (route) {
|
|
3235
|
-
let
|
|
3236
|
-
let oldRouteMetadata = serverManifest.routes[route.id];
|
|
3276
|
+
let oldRouteMetadata = currentReactRouterManifestForDev?.routes[route.id];
|
|
3237
3277
|
let newRouteMetadata = await getRouteMetadata(
|
|
3238
3278
|
cache,
|
|
3239
3279
|
ctx,
|
|
@@ -3633,17 +3673,17 @@ async function prerenderResourceRoute(handler, prerenderPath, clientBuildDirecto
|
|
|
3633
3673
|
let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(/\/\/+/g, "/").replace(/\/$/g, "");
|
|
3634
3674
|
let request = new Request(`http://localhost${normalizedPath}`, requestInit);
|
|
3635
3675
|
let response = await handler(request);
|
|
3636
|
-
let
|
|
3676
|
+
let content = Buffer.from(await response.arrayBuffer());
|
|
3637
3677
|
if (response.status !== 200) {
|
|
3638
3678
|
throw new Error(
|
|
3639
3679
|
`Prerender (resource): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${normalizedPath}\` path.
|
|
3640
|
-
${
|
|
3680
|
+
${content.toString("utf8")}`
|
|
3641
3681
|
);
|
|
3642
3682
|
}
|
|
3643
3683
|
let outdir = path6.relative(process.cwd(), clientBuildDirectory);
|
|
3644
3684
|
let outfile = path6.join(outdir, ...normalizedPath.split("/"));
|
|
3645
3685
|
await fse.ensureDir(path6.dirname(outfile));
|
|
3646
|
-
await fse.outputFile(outfile,
|
|
3686
|
+
await fse.outputFile(outfile, content);
|
|
3647
3687
|
viteConfig.logger.info(
|
|
3648
3688
|
`Prerender (resource): ${prerenderPath} -> ${import_picocolors3.default.bold(outfile)}`
|
|
3649
3689
|
);
|
|
@@ -3742,13 +3782,24 @@ async function validateSsrFalsePrerenderExports(viteConfig, ctx, manifest, viteC
|
|
|
3742
3782
|
if (exports2.includes("action")) invalidApis.push("action");
|
|
3743
3783
|
if (invalidApis.length > 0) {
|
|
3744
3784
|
errors.push(
|
|
3745
|
-
`Prerender: ${invalidApis.length} invalid route export(s) in \`${route.id}\` when
|
|
3785
|
+
`Prerender: ${invalidApis.length} invalid route export(s) in \`${route.id}\` when pre-rendering with \`ssr:false\`: ${invalidApis.map((a) => `\`${a}\``).join(", ")}. See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information.`
|
|
3746
3786
|
);
|
|
3747
3787
|
}
|
|
3748
|
-
if (
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3788
|
+
if (!prerenderedRoutes.has(routeId)) {
|
|
3789
|
+
if (exports2.includes("loader")) {
|
|
3790
|
+
errors.push(
|
|
3791
|
+
`Prerender: 1 invalid route export in \`${route.id}\` when pre-rendering with \`ssr:false\`: \`loader\`. See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information.`
|
|
3792
|
+
);
|
|
3793
|
+
}
|
|
3794
|
+
let parentRoute = route.parentId ? manifest.routes[route.parentId] : null;
|
|
3795
|
+
while (parentRoute && parentRoute.id !== "root") {
|
|
3796
|
+
if (parentRoute.hasLoader && !parentRoute.hasClientLoader) {
|
|
3797
|
+
errors.push(
|
|
3798
|
+
`Prerender: 1 invalid route export in \`${parentRoute.id}\` when pre-rendering with \`ssr:false\`: \`loader\`. See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information.`
|
|
3799
|
+
);
|
|
3800
|
+
}
|
|
3801
|
+
parentRoute = parentRoute.parentId && parentRoute.parentId !== "root" ? manifest.routes[parentRoute.parentId] : null;
|
|
3802
|
+
}
|
|
3752
3803
|
}
|
|
3753
3804
|
}
|
|
3754
3805
|
if (errors.length > 0) {
|
|
@@ -4102,9 +4153,26 @@ async function getEnvironmentOptionsResolvers(ctx, buildManifest, viteCommand) {
|
|
|
4102
4153
|
rollupOptions: {
|
|
4103
4154
|
input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id
|
|
4104
4155
|
}
|
|
4105
|
-
}
|
|
4156
|
+
},
|
|
4157
|
+
optimizeDeps: ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteUserConfig.environments?.ssr?.optimizeDeps?.noDiscovery === false ? {
|
|
4158
|
+
entries: [
|
|
4159
|
+
vite2.normalizePath(ctx.entryServerFilePath),
|
|
4160
|
+
...Object.values(ctx.reactRouterConfig.routes).map(
|
|
4161
|
+
(route) => resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
|
|
4162
|
+
)
|
|
4163
|
+
],
|
|
4164
|
+
include: [
|
|
4165
|
+
"react",
|
|
4166
|
+
"react/jsx-dev-runtime",
|
|
4167
|
+
"react-dom/server",
|
|
4168
|
+
"react-router"
|
|
4169
|
+
]
|
|
4170
|
+
} : void 0
|
|
4106
4171
|
});
|
|
4107
4172
|
}
|
|
4173
|
+
if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteCommand === "serve") {
|
|
4174
|
+
environmentOptionsResolvers[CSS_DEV_HELPER_ENVIRONMENT_NAME] = () => ({});
|
|
4175
|
+
}
|
|
4108
4176
|
return environmentOptionsResolvers;
|
|
4109
4177
|
}
|
|
4110
4178
|
function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-router/dev",
|
|
3
|
-
"version": "0.0.0-experimental-
|
|
3
|
+
"version": "0.0.0-experimental-8677247c0",
|
|
4
4
|
"description": "Dev tools and CLI for React Router",
|
|
5
5
|
"homepage": "https://reactrouter.com",
|
|
6
6
|
"bugs": {
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"set-cookie-parser": "^2.6.0",
|
|
89
89
|
"valibot": "^0.41.0",
|
|
90
90
|
"vite-node": "3.0.0-beta.2",
|
|
91
|
-
"@react-router/node": "0.0.0-experimental-
|
|
91
|
+
"@react-router/node": "0.0.0-experimental-8677247c0"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
94
|
"@types/babel__core": "^7.20.5",
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
"@types/prettier": "^2.7.3",
|
|
107
107
|
"@types/set-cookie-parser": "^2.4.1",
|
|
108
108
|
"dotenv": "^16.0.0",
|
|
109
|
-
"esbuild-register": "^3.
|
|
109
|
+
"esbuild-register": "^3.6.0",
|
|
110
110
|
"execa": "5.1.1",
|
|
111
111
|
"express": "^4.19.2",
|
|
112
112
|
"fast-glob": "3.2.11",
|
|
@@ -117,15 +117,15 @@
|
|
|
117
117
|
"vite": "^6.0.0",
|
|
118
118
|
"wireit": "0.14.9",
|
|
119
119
|
"wrangler": "^3.28.2",
|
|
120
|
-
"react-router": "
|
|
121
|
-
"
|
|
120
|
+
"@react-router/serve": "0.0.0-experimental-8677247c0",
|
|
121
|
+
"react-router": "^0.0.0-experimental-8677247c0"
|
|
122
122
|
},
|
|
123
123
|
"peerDependencies": {
|
|
124
124
|
"typescript": "^5.1.0",
|
|
125
125
|
"vite": "^5.1.0 || ^6.0.0",
|
|
126
126
|
"wrangler": "^3.28.2",
|
|
127
|
-
"@react-router/serve": "^0.0.0-experimental-
|
|
128
|
-
"react-router": "^0.0.0-experimental-
|
|
127
|
+
"@react-router/serve": "^0.0.0-experimental-8677247c0",
|
|
128
|
+
"react-router": "^0.0.0-experimental-8677247c0"
|
|
129
129
|
},
|
|
130
130
|
"peerDependenciesMeta": {
|
|
131
131
|
"@react-router/serve": {
|