@c0va23/react-router-dev 7.9.5 → 7.10.1

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,65 @@
1
1
  # `@react-router/dev`
2
2
 
3
+ ## 7.10.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Import ESM package `pkg-types` with a dynamic `import()` to fix issues on Node 20.18 ([#14624](https://github.com/remix-run/react-router/pull/14624))
8
+ - Update `valibot` dependency to `^1.2.0` to address [GHSA-vqpr-j7v3-hqw9](https://github.com/advisories/GHSA-vqpr-j7v3-hqw9) ([#14608](https://github.com/remix-run/react-router/pull/14608))
9
+ - Updated dependencies:
10
+ - `react-router@7.10.1`
11
+ - `@react-router/node@7.10.1`
12
+ - `@react-router/serve@7.10.1`
13
+
14
+ ## 7.10.0
15
+
16
+ ### Minor Changes
17
+
18
+ - Stabilize `future.v8_splitRouteModules`, replacing `future.unstable_splitRouteModules` ([#14595](https://github.com/remix-run/react-router/pull/14595))
19
+ - ⚠️ This is a breaking change if you have begun using `future.unstable_splitRouteModules`. Please update your `react-router.config.ts`.
20
+
21
+ - Stabilize `future.v8_viteEnvironmentApi`, replacing `future.unstable_viteEnvironmentApi` ([#14595](https://github.com/remix-run/react-router/pull/14595))
22
+ - ⚠️ This is a breaking change if you have begun using `future.unstable_viteEnvironmentApi`. Please update your `react-router.config.ts`.
23
+
24
+ ### Patch Changes
25
+
26
+ - Load environment variables before evaluating `routes.ts` ([#14446](https://github.com/remix-run/react-router/pull/14446))
27
+
28
+ For example, you can now compute your routes based on [`VITE_`-prefixed environment variables](https://vite.dev/guide/env-and-mode#env-variables):
29
+
30
+ ```txt
31
+ # .env
32
+ VITE_ENV_ROUTE=my-route
33
+ ```
34
+
35
+ ```ts
36
+ // app/routes.ts
37
+ import { type RouteConfig, route } from "@react-router/dev/routes";
38
+
39
+ const routes: RouteConfig = [];
40
+ if (import.meta.env.VITE_ENV_ROUTE === "my-route") {
41
+ routes.push(route("my-route", "routes/my-route.tsx"));
42
+ }
43
+
44
+ export default routes;
45
+ ```
46
+
47
+ - Updated dependencies:
48
+ - `react-router@7.10.0`
49
+ - `@react-router/node@7.10.0`
50
+ - `@react-router/serve@7.10.0`
51
+
52
+ ## 7.9.6
53
+
54
+ ### Patch Changes
55
+
56
+ - Use a dynamic `import()` to load ESM-only `p-map` dependency to avoid issues on Node 20.18 and below ([#14492](https://github.com/remix-run/react-router/pull/14492))
57
+ - Short circuit `HEAD` document requests before calling `renderToPipeableStream` in the default `entry.server.tsx` to more closely align with the [spec](https://httpwg.org/specs/rfc9110.html#HEAD) ([#14488](https://github.com/remix-run/react-router/pull/14488))
58
+ - Updated dependencies:
59
+ - `react-router@7.9.6`
60
+ - `@react-router/node@7.9.6`
61
+ - `@react-router/serve@7.9.6`
62
+
3
63
  ## 7.9.5
4
64
 
5
65
  ### Patch Changes
@@ -169,6 +229,7 @@
169
229
  - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215))
170
230
 
171
231
  We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use:
232
+
172
233
  - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider)
173
234
  - [`createContext`](https://reactrouter.com/api/utils/createContext)
174
235
  - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option
@@ -911,6 +972,7 @@
911
972
  ```
912
973
 
913
974
  This initial implementation targets type inference for:
975
+
914
976
  - `Params` : Path parameters from your routing config in `routes.ts` including file-based routing
915
977
  - `LoaderData` : Loader data from `loader` and/or `clientLoader` within your route module
916
978
  - `ActionData` : Action data from `action` and/or `clientAction` within your route module
@@ -925,6 +987,7 @@
925
987
  ```
926
988
 
927
989
  Check out our docs for more:
990
+
928
991
  - [_Explanations > Type Safety_](https://reactrouter.com/dev/guides/explanation/type-safety)
929
992
  - [_How-To > Setting up type safety_](https://reactrouter.com/dev/guides/how-to/setting-up-type-safety)
930
993
 
@@ -1124,6 +1187,7 @@
1124
1187
  - Vite: Provide `Unstable_ServerBundlesFunction` and `Unstable_VitePluginConfig` types ([#8654](https://github.com/remix-run/remix/pull/8654))
1125
1188
 
1126
1189
  - Vite: add `--sourcemapClient` and `--sourcemapServer` flags to `remix vite:build` ([#8613](https://github.com/remix-run/remix/pull/8613))
1190
+
1127
1191
  - `--sourcemapClient`
1128
1192
 
1129
1193
  - `--sourcemapClient=inline`
@@ -1460,6 +1524,7 @@
1460
1524
  - Add support for `clientLoader`/`clientAction`/`HydrateFallback` route exports ([RFC](https://github.com/remix-run/remix/discussions/7634)) ([#8173](https://github.com/remix-run/remix/pull/8173))
1461
1525
 
1462
1526
  Remix now supports loaders/actions that run on the client (in addition to, or instead of the loader/action that runs on the server). While we still recommend server loaders/actions for the majority of your data needs in a Remix app - these provide some levers you can pull for more advanced use-cases such as:
1527
+
1463
1528
  - Leveraging a data source local to the browser (i.e., `localStorage`)
1464
1529
  - Managing a client-side cache of server data (like `IndexedDB`)
1465
1530
  - Bypassing the Remix server in a BFF setup and hitting your API directly from the browser
@@ -1863,6 +1928,7 @@
1863
1928
  - Output esbuild metafiles for bundle analysis ([#6772](https://github.com/remix-run/remix/pull/6772))
1864
1929
 
1865
1930
  Written to server build directory (`build/` by default):
1931
+
1866
1932
  - `metafile.css.json`
1867
1933
  - `metafile.js.json` (browser JS)
1868
1934
  - `metafile.server.json` (server JS)
@@ -1960,6 +2026,7 @@
1960
2026
  - built-in tls support ([#6483](https://github.com/remix-run/remix/pull/6483))
1961
2027
 
1962
2028
  New options:
2029
+
1963
2030
  - `--tls-key` / `tlsKey`: TLS key
1964
2031
  - `--tls-cert` / `tlsCert`: TLS Certificate
1965
2032
 
@@ -2230,6 +2297,7 @@
2230
2297
  ```
2231
2298
 
2232
2299
  The dev server will:
2300
+
2233
2301
  - force `NODE_ENV=development` and warn you if it was previously set to something else
2234
2302
  - rebuild your app whenever your Remix app code changes
2235
2303
  - restart your app server whenever rebuilds succeed
package/dist/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * @react-router/dev v7.9.5
3
+ * @react-router/dev v7.10.1
4
4
  *
5
5
  * Copyright (c) Remix Software Inc.
6
6
  *
@@ -492,12 +492,23 @@ async function resolveConfig({
492
492
  );
493
493
  }
494
494
  }
495
+ let futureConfig = userAndPresetConfigs.future;
496
+ if (futureConfig?.unstable_splitRouteModules !== void 0) {
497
+ return err(
498
+ 'The "future.unstable_splitRouteModules" flag has been stabilized as "future.v8_splitRouteModules"'
499
+ );
500
+ }
501
+ if (futureConfig?.unstable_viteEnvironmentApi !== void 0) {
502
+ return err(
503
+ 'The "future.unstable_viteEnvironmentApi" flag has been stabilized as "future.v8_viteEnvironmentApi"'
504
+ );
505
+ }
495
506
  let future = {
496
- v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false,
497
507
  unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
498
- unstable_splitRouteModules: userAndPresetConfigs.future?.unstable_splitRouteModules ?? false,
499
508
  unstable_subResourceIntegrity: userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
500
- unstable_viteEnvironmentApi: userAndPresetConfigs.future?.unstable_viteEnvironmentApi ?? false
509
+ v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false,
510
+ v8_splitRouteModules: userAndPresetConfigs.future?.v8_splitRouteModules ?? false,
511
+ v8_viteEnvironmentApi: userAndPresetConfigs.future?.v8_viteEnvironmentApi ?? false
501
512
  };
502
513
  let reactRouterConfig = deepFreeze({
503
514
  appDirectory,
@@ -718,13 +729,12 @@ function isEntryFileDependency(moduleGraph, entryFilepath, filepath, visited = /
718
729
  }
719
730
  return false;
720
731
  }
721
- var import_node_fs, import_node_child_process, import_package_json, import_pathe3, import_chokidar, import_picocolors, import_pick2, import_omit, import_cloneDeep, import_isEqual, excludedConfigPresetKeys, mergeReactRouterConfig, deepFreeze, entryExts;
732
+ var import_node_fs, import_node_child_process, import_pathe3, import_chokidar, import_picocolors, import_pick2, import_omit, import_cloneDeep, import_isEqual, excludedConfigPresetKeys, mergeReactRouterConfig, deepFreeze, entryExts;
722
733
  var init_config = __esm({
723
734
  "config/config.ts"() {
724
735
  "use strict";
725
736
  import_node_fs = __toESM(require("fs"));
726
737
  import_node_child_process = require("child_process");
727
- import_package_json = __toESM(require("@npmcli/package-json"));
728
738
  init_vite_node();
729
739
  import_pathe3 = __toESM(require("pathe"));
730
740
  import_chokidar = __toESM(require("chokidar"));
@@ -1673,8 +1683,8 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1673
1683
  return mergeEnvironmentOptions(getBaseOptions({ viteUserConfig }), {
1674
1684
  resolve: {
1675
1685
  external: (
1676
- // If `unstable_viteEnvironmentApi` is `true`, `resolve.external` is set in the `configEnvironment` hook
1677
- ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? void 0 : ssrExternals
1686
+ // If `v8_viteEnvironmentApi` is `true`, `resolve.external` is set in the `configEnvironment` hook
1687
+ ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? void 0 : ssrExternals
1678
1688
  ),
1679
1689
  conditions: [...baseConditions, ...maybeDefaultServerConditions],
1680
1690
  externalConditions: [...baseConditions, ...defaultExternalConditions]
@@ -1689,7 +1699,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1689
1699
  copyPublicDir: false,
1690
1700
  // The client only uses assets in the public directory
1691
1701
  rollupOptions: {
1692
- input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id,
1702
+ input: (ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id,
1693
1703
  output: {
1694
1704
  entryFileNames: serverBuildFile,
1695
1705
  format: serverModuleFormat
@@ -1714,14 +1724,14 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1714
1724
  let code = (0, import_node_fs3.readFileSync)(routeFilePath, "utf-8");
1715
1725
  return [
1716
1726
  `${routeFilePath}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
1717
- ...ctx.reactRouterConfig.future.unstable_splitRouteModules && !isRootRoute ? routeChunkExportNames.map(
1727
+ ...ctx.reactRouterConfig.future.v8_splitRouteModules && !isRootRoute ? routeChunkExportNames.map(
1718
1728
  (exportName) => code.includes(exportName) ? getRouteChunkModuleId(routeFilePath, exportName) : null
1719
1729
  ) : []
1720
1730
  ].filter(isNonNullable);
1721
1731
  }
1722
1732
  )
1723
1733
  ],
1724
- output: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.rollupOptions?.output : viteUserConfig?.build?.rollupOptions?.output) ?? {
1734
+ output: (ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.rollupOptions?.output : viteUserConfig?.build?.rollupOptions?.output) ?? {
1725
1735
  entryFileNames: ({ moduleIds }) => {
1726
1736
  let routeChunkModuleId = moduleIds.find(isRouteChunkModuleId);
1727
1737
  let routeChunkName = routeChunkModuleId ? getRouteChunkNameFromModuleId(routeChunkModuleId)?.replace(
@@ -1729,7 +1739,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1729
1739
  ""
1730
1740
  ) : null;
1731
1741
  let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
1732
- let assetsDir = (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
1742
+ let assetsDir = (ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
1733
1743
  return path7.posix.join(
1734
1744
  assetsDir,
1735
1745
  `[name]${routeChunkSuffix}-[hash].js`
@@ -1902,12 +1912,12 @@ async function build(root, viteBuildOptions) {
1902
1912
  }
1903
1913
  let config = configResult.value;
1904
1914
  let viteMajor = parseInt(vite2.version.split(".")[0], 10);
1905
- if (config.future.unstable_viteEnvironmentApi && viteMajor === 5) {
1915
+ if (config.future.v8_viteEnvironmentApi && viteMajor === 5) {
1906
1916
  throw new Error(
1907
- "The future.unstable_viteEnvironmentApi option is not supported in Vite 5"
1917
+ "The future.v8_viteEnvironmentApi option is not supported in Vite 5"
1908
1918
  );
1909
1919
  }
1910
- const useViteEnvironmentApi = config.future.unstable_viteEnvironmentApi || await hasReactRouterRscPlugin({ root, viteBuildOptions });
1920
+ const useViteEnvironmentApi = config.future.v8_viteEnvironmentApi || await hasReactRouterRscPlugin({ root, viteBuildOptions });
1911
1921
  return await (useViteEnvironmentApi ? viteAppBuild(root, viteBuildOptions) : viteBuild(root, viteBuildOptions));
1912
1922
  }
1913
1923
  async function viteAppBuild(root, {
@@ -2142,7 +2152,6 @@ var import_picocolors9 = __toESM(require("picocolors"));
2142
2152
  var import_node_fs4 = require("fs");
2143
2153
  var import_promises3 = require("fs/promises");
2144
2154
  var path8 = __toESM(require("path"));
2145
- var import_package_json2 = __toESM(require("@npmcli/package-json"));
2146
2155
  var import_exit_hook = __toESM(require("exit-hook"));
2147
2156
  var import_picocolors8 = __toESM(require("picocolors"));
2148
2157
  var import_react_router3 = require("react-router");
@@ -2308,8 +2317,9 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
2308
2317
  );
2309
2318
  return;
2310
2319
  }
2311
- let pkgJson = await import_package_json2.default.load(rootDirectory);
2312
- let deps = pkgJson.content.dependencies ?? {};
2320
+ let { readPackageJSON } = await import("pkg-types");
2321
+ let pkgJson = await readPackageJSON(rootDirectory);
2322
+ let deps = pkgJson.dependencies ?? {};
2313
2323
  if (!deps["@react-router/node"]) {
2314
2324
  console.error(import_picocolors8.default.red(`No default server entry detected.`));
2315
2325
  return;
package/dist/config.d.ts CHANGED
@@ -37,20 +37,20 @@ type ServerBundlesBuildManifest = BaseBuildManifest & {
37
37
  };
38
38
  type ServerModuleFormat = "esm" | "cjs";
39
39
  interface FutureConfig {
40
+ unstable_optimizeDeps: boolean;
41
+ unstable_subResourceIntegrity: boolean;
40
42
  /**
41
43
  * Enable route middleware
42
44
  */
43
45
  v8_middleware: boolean;
44
- unstable_optimizeDeps: boolean;
45
46
  /**
46
47
  * Automatically split route modules into multiple chunks when possible.
47
48
  */
48
- unstable_splitRouteModules: boolean | "enforce";
49
- unstable_subResourceIntegrity: boolean;
49
+ v8_splitRouteModules: boolean | "enforce";
50
50
  /**
51
- * Use Vite Environment API (experimental)
51
+ * Use Vite Environment API
52
52
  */
53
- unstable_viteEnvironmentApi: boolean;
53
+ v8_viteEnvironmentApi: boolean;
54
54
  }
55
55
  type BuildManifest = DefaultBuildManifest | ServerBundlesBuildManifest;
56
56
  type BuildEndHook = (args: {
package/dist/config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v7.9.5
2
+ * @react-router/dev v7.10.1
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 v7.9.5
2
+ * @react-router/dev v7.10.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v7.9.5
2
+ * @react-router/dev v7.10.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -108,7 +108,6 @@ function getVite() {
108
108
  // config/config.ts
109
109
  var import_node_fs = __toESM(require("fs"));
110
110
  var import_node_child_process = require("child_process");
111
- var import_package_json = __toESM(require("@npmcli/package-json"));
112
111
 
113
112
  // vite/ssr-externals.ts
114
113
  var ssrExternals = isReactRouterRepo() ? [
@@ -522,12 +521,23 @@ async function resolveConfig({
522
521
  );
523
522
  }
524
523
  }
524
+ let futureConfig = userAndPresetConfigs.future;
525
+ if (futureConfig?.unstable_splitRouteModules !== void 0) {
526
+ return err(
527
+ 'The "future.unstable_splitRouteModules" flag has been stabilized as "future.v8_splitRouteModules"'
528
+ );
529
+ }
530
+ if (futureConfig?.unstable_viteEnvironmentApi !== void 0) {
531
+ return err(
532
+ 'The "future.unstable_viteEnvironmentApi" flag has been stabilized as "future.v8_viteEnvironmentApi"'
533
+ );
534
+ }
525
535
  let future = {
526
- v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false,
527
536
  unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
528
- unstable_splitRouteModules: userAndPresetConfigs.future?.unstable_splitRouteModules ?? false,
529
537
  unstable_subResourceIntegrity: userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
530
- unstable_viteEnvironmentApi: userAndPresetConfigs.future?.unstable_viteEnvironmentApi ?? false
538
+ v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false,
539
+ v8_splitRouteModules: userAndPresetConfigs.future?.v8_splitRouteModules ?? false,
540
+ v8_viteEnvironmentApi: userAndPresetConfigs.future?.v8_viteEnvironmentApi ?? false
531
541
  };
532
542
  let reactRouterConfig = deepFreeze({
533
543
  appDirectory,
@@ -786,7 +796,7 @@ var cloudflareDevProxyVitePlugin = (options = {}) => {
786
796
  };
787
797
  },
788
798
  configEnvironment: async (name, options2) => {
789
- if (!future.unstable_viteEnvironmentApi) {
799
+ if (!future.v8_viteEnvironmentApi) {
790
800
  return;
791
801
  }
792
802
  if (name !== "client") {
package/dist/vite.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v7.9.5
2
+ * @react-router/dev v7.10.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -68,7 +68,6 @@ var import_picocolors2 = require("picocolors");
68
68
  // config/config.ts
69
69
  var import_node_fs = __toESM(require("fs"));
70
70
  var import_node_child_process = require("child_process");
71
- var import_package_json = __toESM(require("@npmcli/package-json"));
72
71
 
73
72
  // vite/vite.ts
74
73
  var import_pathe2 = __toESM(require("pathe"));
@@ -549,12 +548,23 @@ async function resolveConfig({
549
548
  );
550
549
  }
551
550
  }
551
+ let futureConfig = userAndPresetConfigs.future;
552
+ if (futureConfig?.unstable_splitRouteModules !== void 0) {
553
+ return err(
554
+ 'The "future.unstable_splitRouteModules" flag has been stabilized as "future.v8_splitRouteModules"'
555
+ );
556
+ }
557
+ if (futureConfig?.unstable_viteEnvironmentApi !== void 0) {
558
+ return err(
559
+ 'The "future.unstable_viteEnvironmentApi" flag has been stabilized as "future.v8_viteEnvironmentApi"'
560
+ );
561
+ }
552
562
  let future = {
553
- v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false,
554
563
  unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
555
- unstable_splitRouteModules: userAndPresetConfigs.future?.unstable_splitRouteModules ?? false,
556
564
  unstable_subResourceIntegrity: userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
557
- unstable_viteEnvironmentApi: userAndPresetConfigs.future?.unstable_viteEnvironmentApi ?? false
565
+ v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false,
566
+ v8_splitRouteModules: userAndPresetConfigs.future?.v8_splitRouteModules ?? false,
567
+ v8_viteEnvironmentApi: userAndPresetConfigs.future?.v8_viteEnvironmentApi ?? false
558
568
  };
559
569
  let reactRouterConfig = deepFreeze({
560
570
  appDirectory,
@@ -735,9 +745,10 @@ async function resolveEntryFiles({
735
745
  `Could not find package.json in ${rootDirectory} or any of its parent directories. Please add a package.json, or provide a custom entry.server.tsx/jsx file in your app directory.`
736
746
  );
737
747
  }
748
+ let { readPackageJSON, sortPackage, updatePackage } = await import("pkg-types");
738
749
  let packageJsonDirectory = import_pathe3.default.dirname(packageJsonPath);
739
- let pkgJson = await import_package_json.default.load(packageJsonDirectory);
740
- let deps = pkgJson.content.dependencies ?? {};
750
+ let pkgJson = await readPackageJSON(packageJsonDirectory);
751
+ let deps = pkgJson.dependencies ?? {};
741
752
  if (!deps["@react-router/node"]) {
742
753
  throw new Error(
743
754
  `Could not determine server runtime. Please install @react-router/node, or provide a custom entry.server.tsx/jsx file in your app directory.`
@@ -747,13 +758,11 @@ async function resolveEntryFiles({
747
758
  console.log(
748
759
  "adding `isbot@5` to your package.json, you should commit this change"
749
760
  );
750
- pkgJson.update({
751
- dependencies: {
752
- ...pkgJson.content.dependencies,
753
- isbot: "^5"
754
- }
761
+ await updatePackage(packageJsonPath, (pkg) => {
762
+ pkg.dependencies ??= {};
763
+ pkg.dependencies.isbot = "^5";
764
+ sortPackage(pkg);
755
765
  });
756
- await pkgJson.save();
757
766
  let packageManager = detectPackageManager() ?? "npm";
758
767
  (0, import_node_child_process.execSync)(`${packageManager} install`, {
759
768
  cwd: packageJsonDirectory,
@@ -2737,7 +2746,7 @@ var getServerBundleRouteIds = (vitePluginContext, ctx) => {
2737
2746
  if (!ctx.buildManifest) {
2738
2747
  return void 0;
2739
2748
  }
2740
- let environmentName = ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? vitePluginContext.environment.name : ctx.environmentBuildContext?.name;
2749
+ let environmentName = ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? vitePluginContext.environment.name : ctx.environmentBuildContext?.name;
2741
2750
  if (!environmentName || !isSsrBundleEnvironmentName(environmentName)) {
2742
2751
  return void 0;
2743
2752
  }
@@ -2787,7 +2796,7 @@ var reactRouterVitePlugin = () => {
2787
2796
  }
2788
2797
  return;
2789
2798
  }
2790
- let injectedPluginContext = !reactRouterConfig.future.unstable_viteEnvironmentApi && viteCommand === "build" ? extractPluginContext(viteUserConfig) : void 0;
2799
+ let injectedPluginContext = !reactRouterConfig.future.v8_viteEnvironmentApi && viteCommand === "build" ? extractPluginContext(viteUserConfig) : void 0;
2791
2800
  let { entryClientFilePath, entryServerFilePath } = await resolveEntryFiles({
2792
2801
  rootDirectory,
2793
2802
  reactRouterConfig
@@ -2881,7 +2890,7 @@ var reactRouterVitePlugin = () => {
2881
2890
  }`;
2882
2891
  }).join(",\n ")}
2883
2892
  };
2884
- ${ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteCommand === "serve" ? `
2893
+ ${ctx.reactRouterConfig.future.v8_viteEnvironmentApi && viteCommand === "serve" ? `
2885
2894
  export const unstable_getCriticalCss = ({ pathname }) => {
2886
2895
  return {
2887
2896
  rel: "stylesheet",
@@ -2959,7 +2968,7 @@ var reactRouterVitePlugin = () => {
2959
2968
  viteChildCompiler,
2960
2969
  ctx
2961
2970
  );
2962
- let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
2971
+ let enforceSplitRouteModules = ctx.reactRouterConfig.future.v8_splitRouteModules === "enforce";
2963
2972
  for (let route of Object.values(ctx.reactRouterConfig.routes)) {
2964
2973
  let routeFile = path6.join(ctx.reactRouterConfig.appDirectory, route.file);
2965
2974
  let sourceExports = routeManifestExports[route.id];
@@ -3071,7 +3080,7 @@ var reactRouterVitePlugin = () => {
3071
3080
  viteChildCompiler,
3072
3081
  ctx
3073
3082
  );
3074
- let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
3083
+ let enforceSplitRouteModules = ctx.reactRouterConfig.future.v8_splitRouteModules === "enforce";
3075
3084
  for (let [key, route] of Object.entries(ctx.reactRouterConfig.routes)) {
3076
3085
  let routeFile = route.file;
3077
3086
  let sourceExports = routeManifestExports[key];
@@ -3190,17 +3199,17 @@ var reactRouterVitePlugin = () => {
3190
3199
  logger: vite2.createLogger("warn", { prefix: "[react-router]" })
3191
3200
  });
3192
3201
  }
3202
+ await loadDotenv({
3203
+ rootDirectory,
3204
+ viteUserConfig,
3205
+ mode
3206
+ });
3193
3207
  reactRouterConfigLoader = await createConfigLoader({
3194
3208
  rootDirectory,
3195
3209
  mode,
3196
3210
  watch: viteCommand === "serve"
3197
3211
  });
3198
3212
  await updatePluginContext();
3199
- await loadDotenv({
3200
- rootDirectory,
3201
- viteUserConfig,
3202
- mode
3203
- });
3204
3213
  let environments = await getEnvironmentsOptions(ctx, viteCommand, {
3205
3214
  viteUserConfig
3206
3215
  });
@@ -3266,7 +3275,7 @@ var reactRouterVitePlugin = () => {
3266
3275
  // will throw an error that the file is not allowed to be read.
3267
3276
  // https://vitejs.dev/config/server-options#server-fs-allow
3268
3277
  server: viteUserConfig.server?.fs?.allow ? { fs: { allow: defaultEntries } } : void 0,
3269
- ...ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? {
3278
+ ...ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? {
3270
3279
  environments,
3271
3280
  build: {
3272
3281
  // This isn't honored by the SSR environment config (which seems
@@ -3305,7 +3314,7 @@ var reactRouterVitePlugin = () => {
3305
3314
  };
3306
3315
  },
3307
3316
  configEnvironment(name, options) {
3308
- if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && (ctx.buildManifest?.serverBundles ? isSsrBundleEnvironmentName(name) : name === "ssr")) {
3317
+ if (ctx.reactRouterConfig.future.v8_viteEnvironmentApi && (ctx.buildManifest?.serverBundles ? isSsrBundleEnvironmentName(name) : name === "ssr")) {
3309
3318
  const vite2 = getVite();
3310
3319
  return {
3311
3320
  resolve: {
@@ -3441,7 +3450,7 @@ var reactRouterVitePlugin = () => {
3441
3450
  }
3442
3451
  }
3443
3452
  );
3444
- if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi) {
3453
+ if (ctx.reactRouterConfig.future.v8_viteEnvironmentApi) {
3445
3454
  viteDevServer.middlewares.use(async (req, res, next) => {
3446
3455
  let [reqPathname, reqSearch] = (req.url ?? "").split("?");
3447
3456
  if (reqPathname.endsWith("/@react-router/critical.css")) {
@@ -3469,7 +3478,7 @@ var reactRouterVitePlugin = () => {
3469
3478
  viteDevServer.middlewares.use(async (req, res, next) => {
3470
3479
  try {
3471
3480
  let build;
3472
- if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi) {
3481
+ if (ctx.reactRouterConfig.future.v8_viteEnvironmentApi) {
3473
3482
  let vite2 = getVite();
3474
3483
  let ssrEnvironment = viteDevServer.environments.ssr;
3475
3484
  if (!vite2.isRunnableDevEnvironment(ssrEnvironment)) {
@@ -3506,17 +3515,17 @@ var reactRouterVitePlugin = () => {
3506
3515
  // the SSR build and move server-only assets to client assets directory
3507
3516
  async handler() {
3508
3517
  let { future } = ctx.reactRouterConfig;
3509
- if (future.unstable_viteEnvironmentApi ? this.environment.name === "client" : !viteConfigEnv.isSsrBuild) {
3518
+ if (future.v8_viteEnvironmentApi ? this.environment.name === "client" : !viteConfigEnv.isSsrBuild) {
3510
3519
  return;
3511
3520
  }
3512
3521
  invariant(viteConfig);
3513
3522
  let clientBuildDirectory = getClientBuildDirectory(
3514
3523
  ctx.reactRouterConfig
3515
3524
  );
3516
- let serverBuildDirectory = future.unstable_viteEnvironmentApi ? this.environment.config?.build?.outDir : ctx.environmentBuildContext?.options.build?.outDir ?? getServerBuildDirectory(ctx.reactRouterConfig);
3525
+ let serverBuildDirectory = future.v8_viteEnvironmentApi ? this.environment.config?.build?.outDir : ctx.environmentBuildContext?.options.build?.outDir ?? getServerBuildDirectory(ctx.reactRouterConfig);
3517
3526
  let ssrViteManifest = await loadViteManifest(serverBuildDirectory);
3518
3527
  let ssrAssetPaths = getViteManifestAssetPaths(ssrViteManifest);
3519
- let userSsrEmitAssets = (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.ssrEmitAssets ?? viteUserConfig.environments?.ssr?.build?.emitAssets : null) ?? viteUserConfig.build?.ssrEmitAssets ?? false;
3528
+ let userSsrEmitAssets = (ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.ssrEmitAssets ?? viteUserConfig.environments?.ssr?.build?.emitAssets : null) ?? viteUserConfig.build?.ssrEmitAssets ?? false;
3520
3529
  let movedAssetPaths = [];
3521
3530
  let removedAssetPaths = [];
3522
3531
  let copiedAssetPaths = [];
@@ -3730,7 +3739,7 @@ var reactRouterVitePlugin = () => {
3730
3739
  reason: "Split round modules disabled"
3731
3740
  });
3732
3741
  }
3733
- let enforceSplitRouteModules = ctx.reactRouterConfig.future.unstable_splitRouteModules === "enforce";
3742
+ let enforceSplitRouteModules = ctx.reactRouterConfig.future.v8_splitRouteModules === "enforce";
3734
3743
  if (enforceSplitRouteModules && chunkName === "main" && chunk) {
3735
3744
  let exportNames = getExportNames(chunk.code);
3736
3745
  validateRouteChunks({
@@ -4642,7 +4651,7 @@ async function detectRouteChunksIfEnabled(cache, ctx, id, input) {
4642
4651
  }
4643
4652
  };
4644
4653
  }
4645
- if (!ctx.reactRouterConfig.future.unstable_splitRouteModules) {
4654
+ if (!ctx.reactRouterConfig.future.v8_splitRouteModules) {
4646
4655
  return noRouteChunks();
4647
4656
  }
4648
4657
  if (isRootRouteModuleId(ctx, id)) {
@@ -4656,7 +4665,7 @@ async function detectRouteChunksIfEnabled(cache, ctx, id, input) {
4656
4665
  return detectRouteChunks(code, cache, cacheKey);
4657
4666
  }
4658
4667
  async function getRouteChunkIfEnabled(cache, ctx, id, chunkName, input) {
4659
- if (!ctx.reactRouterConfig.future.unstable_splitRouteModules) {
4668
+ if (!ctx.reactRouterConfig.future.v8_splitRouteModules) {
4660
4669
  return null;
4661
4670
  }
4662
4671
  let code = await resolveRouteFileCode(ctx, input);
@@ -4760,7 +4769,7 @@ async function getBuildManifest({
4760
4769
  if (typeof serverBundleId !== "string") {
4761
4770
  throw new Error(`The "serverBundles" function must return a string`);
4762
4771
  }
4763
- if (reactRouterConfig.future.unstable_viteEnvironmentApi) {
4772
+ if (reactRouterConfig.future.v8_viteEnvironmentApi) {
4764
4773
  if (!/^[a-zA-Z0-9_]+$/.test(serverBundleId)) {
4765
4774
  throw new Error(
4766
4775
  `The "serverBundles" function must only return strings containing alphanumeric characters and underscores.`
@@ -4848,8 +4857,8 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4848
4857
  return mergeEnvironmentOptions(getBaseOptions({ viteUserConfig }), {
4849
4858
  resolve: {
4850
4859
  external: (
4851
- // If `unstable_viteEnvironmentApi` is `true`, `resolve.external` is set in the `configEnvironment` hook
4852
- ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? void 0 : ssrExternals
4860
+ // If `v8_viteEnvironmentApi` is `true`, `resolve.external` is set in the `configEnvironment` hook
4861
+ ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? void 0 : ssrExternals
4853
4862
  ),
4854
4863
  conditions: [...baseConditions, ...maybeDefaultServerConditions],
4855
4864
  externalConditions: [...baseConditions, ...defaultExternalConditions]
@@ -4864,7 +4873,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4864
4873
  copyPublicDir: false,
4865
4874
  // The client only uses assets in the public directory
4866
4875
  rollupOptions: {
4867
- input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id,
4876
+ input: (ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id,
4868
4877
  output: {
4869
4878
  entryFileNames: serverBuildFile,
4870
4879
  format: serverModuleFormat
@@ -4889,14 +4898,14 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4889
4898
  let code = (0, import_node_fs2.readFileSync)(routeFilePath, "utf-8");
4890
4899
  return [
4891
4900
  `${routeFilePath}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
4892
- ...ctx.reactRouterConfig.future.unstable_splitRouteModules && !isRootRoute ? routeChunkExportNames.map(
4901
+ ...ctx.reactRouterConfig.future.v8_splitRouteModules && !isRootRoute ? routeChunkExportNames.map(
4893
4902
  (exportName) => code.includes(exportName) ? getRouteChunkModuleId(routeFilePath, exportName) : null
4894
4903
  ) : []
4895
4904
  ].filter(isNonNullable);
4896
4905
  }
4897
4906
  )
4898
4907
  ],
4899
- output: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.rollupOptions?.output : viteUserConfig?.build?.rollupOptions?.output) ?? {
4908
+ output: (ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.rollupOptions?.output : viteUserConfig?.build?.rollupOptions?.output) ?? {
4900
4909
  entryFileNames: ({ moduleIds }) => {
4901
4910
  let routeChunkModuleId = moduleIds.find(isRouteChunkModuleId);
4902
4911
  let routeChunkName = routeChunkModuleId ? getRouteChunkNameFromModuleId(routeChunkModuleId)?.replace(
@@ -4904,7 +4913,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4904
4913
  ""
4905
4914
  ) : null;
4906
4915
  let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
4907
- let assetsDir = (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
4916
+ let assetsDir = (ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
4908
4917
  return path6.posix.join(
4909
4918
  assetsDir,
4910
4919
  `[name]${routeChunkSuffix}-[hash].js`
@@ -5337,6 +5346,11 @@ function reactRouterRSCVitePlugin() {
5337
5346
  viteCommand = command;
5338
5347
  const rootDirectory = getRootDirectory(viteUserConfig);
5339
5348
  const watch2 = command === "serve";
5349
+ await loadDotenv({
5350
+ rootDirectory,
5351
+ viteUserConfig,
5352
+ mode
5353
+ });
5340
5354
  configLoader = await createConfigLoader({
5341
5355
  rootDirectory,
5342
5356
  mode,
@@ -5349,12 +5363,12 @@ function reactRouterRSCVitePlugin() {
5349
5363
  if (userConfig.routeDiscovery) errors.push("routeDiscovery");
5350
5364
  if (userConfig.serverBundles) errors.push("serverBundles");
5351
5365
  if (userConfig.ssr === false) errors.push("ssr: false");
5352
- if (userConfig.future?.unstable_splitRouteModules)
5353
- errors.push("future.unstable_splitRouteModules");
5354
- if (userConfig.future?.unstable_viteEnvironmentApi === false)
5355
- errors.push("future.unstable_viteEnvironmentApi: false");
5356
5366
  if (userConfig.future?.v8_middleware === false)
5357
5367
  errors.push("future.v8_middleware: false");
5368
+ if (userConfig.future?.v8_splitRouteModules)
5369
+ errors.push("future.v8_splitRouteModules");
5370
+ if (userConfig.future?.v8_viteEnvironmentApi === false)
5371
+ errors.push("future.v8_viteEnvironmentApi: false");
5358
5372
  if (userConfig.future?.unstable_subResourceIntegrity)
5359
5373
  errors.push("future.unstable_subResourceIntegrity");
5360
5374
  if (errors.length) {
@@ -5372,11 +5386,6 @@ ${errors.map((x) => ` - ${x}`).join("\n")}
5372
5386
  "When using the React Router `basename` and the Vite `base` config, the `basename` config must begin with `base` for the default Vite dev server."
5373
5387
  );
5374
5388
  }
5375
- await loadDotenv({
5376
- rootDirectory,
5377
- viteUserConfig,
5378
- mode
5379
- });
5380
5389
  const vite2 = await import("vite");
5381
5390
  logger = vite2.createLogger(viteUserConfig.logLevel, {
5382
5391
  prefix: "[react-router]"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c0va23/react-router-dev",
3
- "version": "7.9.5",
3
+ "version": "7.10.1",
4
4
  "description": "Dev tools and CLI for React Router",
5
5
  "homepage": "https://reactrouter.com",
6
6
  "bugs": {
@@ -67,7 +67,6 @@
67
67
  "@babel/preset-typescript": "^7.27.1",
68
68
  "@babel/traverse": "^7.27.7",
69
69
  "@babel/types": "^7.27.7",
70
- "@npmcli/package-json": "^4.0.1",
71
70
  "@remix-run/node-fetch-server": "^0.9.0",
72
71
  "arg": "^5.0.1",
73
72
  "babel-dead-code-elimination": "^1.0.6",
@@ -81,13 +80,14 @@
81
80
  "p-map": "^7.0.3",
82
81
  "pathe": "^1.1.2",
83
82
  "picocolors": "^1.1.1",
83
+ "pkg-types": "^2.3.0",
84
84
  "prettier": "^3.6.2",
85
85
  "react-refresh": "^0.14.0",
86
86
  "semver": "^7.3.7",
87
87
  "tinyglobby": "^0.2.14",
88
- "valibot": "^1.1.0",
88
+ "valibot": "^1.2.0",
89
89
  "vite-node": "^3.2.2",
90
- "@react-router/node": "7.9.5"
90
+ "@react-router/node": "7.10.1"
91
91
  },
92
92
  "devDependencies": {
93
93
  "@types/babel__core": "^7.20.5",
@@ -107,19 +107,19 @@
107
107
  "fast-glob": "3.2.11",
108
108
  "tsup": "^8.3.0",
109
109
  "typescript": "^5.1.6",
110
- "vite": "^6.1.0",
110
+ "vite": "^6.3.0",
111
111
  "wireit": "0.14.9",
112
112
  "wrangler": "^4.23.0",
113
- "@react-router/serve": "7.9.5",
114
- "react-router": "^7.9.5"
113
+ "@react-router/serve": "7.10.1",
114
+ "react-router": "^7.10.1"
115
115
  },
116
116
  "peerDependencies": {
117
117
  "@vitejs/plugin-rsc": "*",
118
118
  "typescript": "^5.1.0",
119
119
  "vite": "^5.1.0 || ^6.0.0 || ^7.0.0",
120
120
  "wrangler": "^3.28.2 || ^4.0.0",
121
- "@react-router/serve": "^7.9.5",
122
- "react-router": "^7.9.5"
121
+ "@react-router/serve": "^7.10.1",
122
+ "react-router": "^7.10.1"
123
123
  },
124
124
  "peerDependenciesMeta": {
125
125
  "@vitejs/plugin-rsc": {