@react-router/dev 0.0.0-experimental-4d16948 → 0.0.0-experimental-23decd7bc

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,79 @@
1
1
  # `@react-router/dev`
2
2
 
3
+ ## 7.6.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Add Vite 7 support ([#13748](https://github.com/remix-run/react-router/pull/13748))
8
+ - Skip `package.json` resolution checks when a custom `entry.server.(j|t)sx` file is provided. ([#13744](https://github.com/remix-run/react-router/pull/13744))
9
+ - Add validation for a route's id not being 'root' ([#13792](https://github.com/remix-run/react-router/pull/13792))
10
+ - Updated dependencies:
11
+ - `@react-router/node@7.6.3`
12
+ - `react-router@7.6.3`
13
+ - `@react-router/serve@7.6.3`
14
+
15
+ ## 7.6.2
16
+
17
+ ### Patch Changes
18
+
19
+ - Avoid additional `with-props` chunk in Framework Mode by moving route module component prop logic from the Vite plugin to `react-router` ([#13650](https://github.com/remix-run/react-router/pull/13650))
20
+
21
+ - When `future.unstable_viteEnvironmentApi` is enabled and an absolute Vite `base` has been configured, ensure critical CSS is handled correctly during development ([#13598](https://github.com/remix-run/react-router/pull/13598))
22
+
23
+ - Update `vite-node` ([#13673](https://github.com/remix-run/react-router/pull/13673))
24
+
25
+ - Fix typegen for non-{.js,.jsx,.ts,.tsx} routes like .mdx ([#12453](https://github.com/remix-run/react-router/pull/12453))
26
+
27
+ - Fix href types for optional dynamic params ([#13725](https://github.com/remix-run/react-router/pull/13725))
28
+
29
+ 7.6.1 introduced fixes for `href` when using optional static segments,
30
+ but those fixes caused regressions with how optional dynamic params worked in 7.6.0:
31
+
32
+ ```ts
33
+ // 7.6.0
34
+ href("/users/:id?"); // ✅
35
+ href("/users/:id?", { id: 1 }); // ✅
36
+
37
+ // 7.6.1
38
+ href("/users/:id?"); // ❌
39
+ href("/users/:id?", { id: 1 }); // ❌
40
+ ```
41
+
42
+ Now, optional static segments are expanded into different paths for `href`, but optional dynamic params are not.
43
+ This way `href` can unambiguously refer to an exact URL path, all while keeping the number of path options to a minimum.
44
+
45
+ ```ts
46
+ // 7.6.2
47
+
48
+ // path: /users/:id?/edit?
49
+ href("
50
+ // ^ suggestions when cursor is here:
51
+ //
52
+ // /users/:id?
53
+ // /users/:id?/edit
54
+ ```
55
+
56
+ Additionally, you can pass `params` from component props without needing to narrow them manually:
57
+
58
+ ```ts
59
+ declare const params: { id?: number };
60
+
61
+ // 7.6.0
62
+ href("/users/:id?", params);
63
+
64
+ // 7.6.1
65
+ href("/users/:id?", params); // ❌
66
+ "id" in params ? href("/users/:id", params) : href("/users"); // works... but is annoying
67
+
68
+ // 7.6.2
69
+ href("/users/:id?", params); // restores behavior of 7.6.0
70
+ ```
71
+
72
+ - Updated dependencies:
73
+ - `react-router@7.6.2`
74
+ - `@react-router/node@7.6.2`
75
+ - `@react-router/serve@7.6.2`
76
+
3
77
  ## 7.6.1
4
78
 
5
79
  ### 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-4d16948
3
+ * @react-router/dev v0.0.0-experimental-23decd7bc
4
4
  *
5
5
  * Copyright (c) Remix Software Inc.
6
6
  *
@@ -130,6 +130,11 @@ async function createContext({
130
130
  }) {
131
131
  await preloadVite();
132
132
  const vite2 = getVite();
133
+ const [{ ViteNodeServer }, { ViteNodeRunner }, { installSourcemapsSupport }] = await Promise.all([
134
+ import("vite-node/server"),
135
+ import("vite-node/client"),
136
+ import("vite-node/source-map")
137
+ ]);
133
138
  const devServer = await vite2.createServer({
134
139
  root,
135
140
  mode,
@@ -159,11 +164,11 @@ async function createContext({
159
164
  plugins: []
160
165
  });
161
166
  await devServer.pluginContainer.buildStart({});
162
- const server = new import_server.ViteNodeServer(devServer);
163
- (0, import_source_map.installSourcemapsSupport)({
167
+ const server = new ViteNodeServer(devServer);
168
+ installSourcemapsSupport({
164
169
  getSourceMap: (source) => server.getSourceMap(source)
165
170
  });
166
- const runner = new import_client.ViteNodeRunner({
171
+ const runner = new ViteNodeRunner({
167
172
  root: devServer.config.root,
168
173
  base: devServer.config.base,
169
174
  fetchModule(id) {
@@ -175,13 +180,9 @@ async function createContext({
175
180
  });
176
181
  return { devServer, server, runner };
177
182
  }
178
- var import_server, import_client, import_source_map;
179
183
  var init_vite_node = __esm({
180
184
  "vite/vite-node.ts"() {
181
185
  "use strict";
182
- import_server = require("vite-node/server");
183
- import_client = require("vite-node/client");
184
- import_source_map = require("vite-node/source-map");
185
186
  init_vite();
186
187
  init_ssr_externals();
187
188
  }
@@ -272,7 +273,12 @@ var init_routes = __esm({
272
273
  return !(typeof value === "object" && value !== null && "then" in value && "catch" in value);
273
274
  }, "Invalid type: Expected object but received a promise. Did you forget to await?"),
274
275
  v.object({
275
- id: v.optional(v.string()),
276
+ id: v.optional(
277
+ v.pipe(
278
+ v.string(),
279
+ v.notValue("root", "A route cannot use the reserved id 'root'.")
280
+ )
281
+ ),
276
282
  path: v.optional(v.string()),
277
283
  index: v.optional(v.boolean()),
278
284
  caseSensitive: v.optional(v.boolean()),
@@ -928,7 +934,7 @@ function generateRoutes(ctx) {
928
934
  lineages.set(route.id, lineage2);
929
935
  const fullpath2 = fullpath(lineage2);
930
936
  if (!fullpath2) continue;
931
- const pages = explodeOptionalSegments(fullpath2);
937
+ const pages = expand(fullpath2);
932
938
  pages.forEach((page) => allPages.add(page));
933
939
  lineage2.forEach(({ id }) => {
934
940
  let routePages = routeToPages.get(id);
@@ -1136,9 +1142,13 @@ function getRouteAnnotations({
1136
1142
  }
1137
1143
  function relativeImportSource(from, to) {
1138
1144
  let path8 = Path3.relative(Path3.dirname(from), to);
1145
+ let extension = Path3.extname(path8);
1139
1146
  path8 = Path3.join(Path3.dirname(path8), Pathe.filename(path8));
1140
1147
  if (!path8.startsWith("../")) path8 = "./" + path8;
1141
- return path8 + ".js";
1148
+ if (!extension || /\.(js|ts)x?$/.test(extension)) {
1149
+ extension = ".js";
1150
+ }
1151
+ return path8 + extension;
1142
1152
  }
1143
1153
  function rootDirsPath(ctx, typesPath) {
1144
1154
  const rel = Path3.relative(typesDirectory(ctx), typesPath);
@@ -1157,28 +1167,27 @@ function paramsType(path8) {
1157
1167
  })
1158
1168
  );
1159
1169
  }
1160
- function explodeOptionalSegments(path8) {
1161
- let segments = path8.split("/");
1162
- if (segments.length === 0) return [];
1163
- let [first, ...rest] = segments;
1164
- let isOptional = first.endsWith("?");
1165
- let required = first.replace(/\?$/, "");
1166
- if (rest.length === 0) {
1167
- return isOptional ? [required, ""] : [required];
1168
- }
1169
- let restExploded = explodeOptionalSegments(rest.join("/"));
1170
- let result = [];
1171
- result.push(
1172
- ...restExploded.map(
1173
- (subpath) => subpath === "" ? required : [required, subpath].join("/")
1174
- )
1175
- );
1176
- if (isOptional) {
1177
- result.push(...restExploded);
1178
- }
1179
- return result.map(
1180
- (exploded) => path8.startsWith("/") && exploded === "" ? "/" : exploded
1181
- );
1170
+ function expand(fullpath2) {
1171
+ function recurse(segments2, index) {
1172
+ if (index === segments2.length) return [""];
1173
+ const segment = segments2[index];
1174
+ const isOptional = segment.endsWith("?");
1175
+ const isDynamic = segment.startsWith(":");
1176
+ const required = segment.replace(/\?$/, "");
1177
+ const keep = !isOptional || isDynamic;
1178
+ const kept = isDynamic ? segment : required;
1179
+ const withoutSegment = recurse(segments2, index + 1);
1180
+ const withSegment = withoutSegment.map((rest) => [kept, rest].join("/"));
1181
+ if (keep) return withSegment;
1182
+ return [...withoutSegment, ...withSegment];
1183
+ }
1184
+ const segments = fullpath2.split("/");
1185
+ const expanded = /* @__PURE__ */ new Set();
1186
+ for (let result of recurse(segments, 0)) {
1187
+ if (result !== "/") result = result.replace(/\/$/, "");
1188
+ expanded.add(result);
1189
+ }
1190
+ return expanded;
1182
1191
  }
1183
1192
  var import_dedent, Path3, Pathe, t2;
1184
1193
  var init_generate = __esm({
@@ -1445,7 +1454,7 @@ async function cleanBuildDirectory(viteConfig, ctx) {
1445
1454
  return !relativePath.startsWith("..") && !path6.isAbsolute(relativePath);
1446
1455
  };
1447
1456
  if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
1448
- await fse.remove(buildDirectory);
1457
+ await (0, import_promises2.rm)(buildDirectory, { force: true, recursive: true });
1449
1458
  }
1450
1459
  }
1451
1460
  async function cleanViteManifests(environmentsOptions, ctx) {
@@ -1458,15 +1467,15 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1458
1467
  );
1459
1468
  await Promise.all(
1460
1469
  viteManifestPaths.map(async (viteManifestPath) => {
1461
- let manifestExists = await fse.pathExists(viteManifestPath);
1470
+ let manifestExists = (0, import_node_fs3.existsSync)(viteManifestPath);
1462
1471
  if (!manifestExists) return;
1463
1472
  if (!ctx.viteManifestEnabled) {
1464
- await fse.remove(viteManifestPath);
1473
+ await (0, import_promises2.rm)(viteManifestPath, { force: true, recursive: true });
1465
1474
  }
1466
1475
  let viteDir = path6.dirname(viteManifestPath);
1467
- let viteDirFiles = await fse.readdir(viteDir);
1476
+ let viteDirFiles = await (0, import_promises2.readdir)(viteDir, { recursive: true });
1468
1477
  if (viteDirFiles.length === 0) {
1469
- await fse.remove(viteDir);
1478
+ await (0, import_promises2.rm)(viteDir, { force: true, recursive: true });
1470
1479
  }
1471
1480
  })
1472
1481
  );
@@ -1532,13 +1541,13 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1532
1541
  },
1533
1542
  build: {
1534
1543
  // We move SSR-only assets to client assets. Note that the
1535
- // SSR build can also emit code-split JS files (e.g. by
1544
+ // SSR build can also emit code-split JS files (e.g., by
1536
1545
  // dynamic import) under the same assets directory
1537
1546
  // regardless of "ssrEmitAssets" option, so we also need to
1538
- // keep these JS files have to be kept as-is.
1547
+ // keep these JS files to be kept as-is.
1539
1548
  ssrEmitAssets: true,
1540
1549
  copyPublicDir: false,
1541
- // Assets in the public directory are only used by the client
1550
+ // The client only uses assets in the public directory
1542
1551
  rollupOptions: {
1543
1552
  input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id,
1544
1553
  output: {
@@ -1562,7 +1571,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1562
1571
  route.file
1563
1572
  );
1564
1573
  let isRootRoute = route.file === ctx.reactRouterConfig.routes.root.file;
1565
- let code = fse.readFileSync(routeFilePath, "utf-8");
1574
+ let code = (0, import_node_fs3.readFileSync)(routeFilePath, "utf-8");
1566
1575
  return [
1567
1576
  `${routeFilePath}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
1568
1577
  ...ctx.reactRouterConfig.future.unstable_splitRouteModules && !isRootRoute ? routeChunkExportNames.map(
@@ -1631,18 +1640,19 @@ function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
1631
1640
  function isNonNullable(x) {
1632
1641
  return x != null;
1633
1642
  }
1634
- var import_node_crypto, fs4, path6, url, fse, babel2, import_react_router2, import_es_module_lexer, import_pick3, import_jsesc, import_picocolors4, import_kebabCase, CLIENT_NON_COMPONENT_EXPORTS, CLIENT_ROUTE_EXPORTS, BUILD_CLIENT_ROUTE_QUERY_STRING, SSR_BUNDLE_PREFIX, virtualHmrRuntime, virtualInjectHmrRuntime, virtual, getServerBuildDirectory, getClientBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER;
1643
+ var import_node_crypto, import_node_fs3, import_promises2, path6, url, babel2, import_react_router2, import_es_module_lexer, import_tinyglobby, import_pick3, import_jsesc, import_picocolors4, import_kebabCase, CLIENT_NON_COMPONENT_EXPORTS, CLIENT_ROUTE_EXPORTS, BUILD_CLIENT_ROUTE_QUERY_STRING, SSR_BUNDLE_PREFIX, virtualHmrRuntime, virtualInjectHmrRuntime, virtual, getServerBuildDirectory, getClientBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER;
1635
1644
  var init_plugin = __esm({
1636
1645
  "vite/plugin.ts"() {
1637
1646
  "use strict";
1638
1647
  import_node_crypto = require("crypto");
1639
- fs4 = __toESM(require("fs"));
1648
+ import_node_fs3 = require("fs");
1649
+ import_promises2 = require("fs/promises");
1640
1650
  path6 = __toESM(require("path"));
1641
1651
  url = __toESM(require("url"));
1642
- fse = __toESM(require("fs-extra"));
1643
1652
  babel2 = __toESM(require("@babel/core"));
1644
1653
  import_react_router2 = require("react-router");
1645
1654
  import_es_module_lexer = require("es-module-lexer");
1655
+ import_tinyglobby = require("tinyglobby");
1646
1656
  import_pick3 = __toESM(require("lodash/pick"));
1647
1657
  import_jsesc = __toESM(require("jsesc"));
1648
1658
  import_picocolors4 = __toESM(require("picocolors"));
@@ -1698,7 +1708,9 @@ var init_plugin = __esm({
1698
1708
  "config",
1699
1709
  "defaults"
1700
1710
  );
1701
- defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename2) => path6.join(defaultEntriesDir, filename2));
1711
+ defaultEntries = (0, import_node_fs3.readdirSync)(defaultEntriesDir).map(
1712
+ (filename2) => path6.join(defaultEntriesDir, filename2)
1713
+ );
1702
1714
  invariant(defaultEntries.length > 0, "No default entries found");
1703
1715
  REACT_REFRESH_HEADER = `
1704
1716
  import RefreshRuntime from "${virtualHmrRuntime.id}";
@@ -1978,8 +1990,9 @@ var import_semver = __toESM(require("semver"));
1978
1990
  var import_picocolors8 = __toESM(require("picocolors"));
1979
1991
 
1980
1992
  // cli/commands.ts
1993
+ var import_node_fs4 = require("fs");
1994
+ var import_promises3 = require("fs/promises");
1981
1995
  var path7 = __toESM(require("path"));
1982
- var import_fs_extra = __toESM(require("fs-extra"));
1983
1996
  var import_package_json2 = __toESM(require("@npmcli/package-json"));
1984
1997
  var import_exit_hook = __toESM(require("exit-hook"));
1985
1998
  var import_picocolors7 = __toESM(require("picocolors"));
@@ -2153,21 +2166,21 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
2153
2166
  let useTypeScript = flags.typescript ?? true;
2154
2167
  let outputExtension = useTypeScript ? "tsx" : "jsx";
2155
2168
  let outputEntry = `${entry}.${outputExtension}`;
2156
- let outputFile2 = path7.resolve(appDirectory, outputEntry);
2169
+ let outputFile = path7.resolve(appDirectory, outputEntry);
2157
2170
  if (!useTypeScript) {
2158
2171
  let javascript = transpile(contents, {
2159
2172
  cwd: rootDirectory,
2160
2173
  filename: isServerEntry ? defaultEntryServer : defaultEntryClient
2161
2174
  });
2162
- await import_fs_extra.default.writeFile(outputFile2, javascript, "utf-8");
2175
+ await (0, import_promises3.writeFile)(outputFile, javascript, "utf-8");
2163
2176
  } else {
2164
- await import_fs_extra.default.writeFile(outputFile2, contents, "utf-8");
2177
+ await (0, import_promises3.writeFile)(outputFile, contents, "utf-8");
2165
2178
  }
2166
2179
  console.log(
2167
2180
  import_picocolors7.default.blue(
2168
2181
  `Entry file ${entry} created at ${path7.relative(
2169
2182
  rootDirectory,
2170
- outputFile2
2183
+ outputFile
2171
2184
  )}.`
2172
2185
  )
2173
2186
  );
@@ -2181,7 +2194,7 @@ function resolveRootDirectory(root, flags) {
2181
2194
  async function checkForEntry(rootDirectory, appDirectory, entries2) {
2182
2195
  for (let entry of entries2) {
2183
2196
  let entryPath = path7.resolve(appDirectory, entry);
2184
- let exists = await import_fs_extra.default.pathExists(entryPath);
2197
+ let exists = (0, import_node_fs4.existsSync)(entryPath);
2185
2198
  if (exists) {
2186
2199
  let relative7 = path7.relative(rootDirectory, entryPath);
2187
2200
  console.error(import_picocolors7.default.red(`Entry file ${relative7} already exists.`));
@@ -2191,12 +2204,12 @@ async function checkForEntry(rootDirectory, appDirectory, entries2) {
2191
2204
  }
2192
2205
  async function createServerEntry(rootDirectory, appDirectory, inputFile) {
2193
2206
  await checkForEntry(rootDirectory, appDirectory, serverEntries);
2194
- let contents = await import_fs_extra.default.readFile(inputFile, "utf-8");
2207
+ let contents = await (0, import_promises3.readFile)(inputFile, "utf-8");
2195
2208
  return contents;
2196
2209
  }
2197
2210
  async function createClientEntry(rootDirectory, appDirectory, inputFile) {
2198
2211
  await checkForEntry(rootDirectory, appDirectory, clientEntries);
2199
- let contents = await import_fs_extra.default.readFile(inputFile, "utf-8");
2212
+ let contents = await (0, import_promises3.readFile)(inputFile, "utf-8");
2200
2213
  return contents;
2201
2214
  }
2202
2215
  async function typegen(root, flags) {
package/dist/config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v0.0.0-experimental-4d16948
2
+ * @react-router/dev v0.0.0-experimental-23decd7bc
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 v0.0.0-experimental-4d16948
2
+ * @react-router/dev v0.0.0-experimental-23decd7bc
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -74,7 +74,12 @@ var routeConfigEntrySchema = v.pipe(
74
74
  return !(typeof value === "object" && value !== null && "then" in value && "catch" in value);
75
75
  }, "Invalid type: Expected object but received a promise. Did you forget to await?"),
76
76
  v.object({
77
- id: v.optional(v.string()),
77
+ id: v.optional(
78
+ v.pipe(
79
+ v.string(),
80
+ v.notValue("root", "A route cannot use the reserved id 'root'.")
81
+ )
82
+ ),
78
83
  path: v.optional(v.string()),
79
84
  index: v.optional(v.boolean()),
80
85
  caseSensitive: v.optional(v.boolean()),
@@ -1,6 +1,6 @@
1
1
  import { UNSAFE_MiddlewareEnabled, unstable_InitialContext, AppLoadContext } from 'react-router';
2
2
  import { Plugin } from 'vite';
3
- import { GetPlatformProxyOptions, PlatformProxy } from 'wrangler';
3
+ import { PlatformProxy, GetPlatformProxyOptions } from 'wrangler';
4
4
 
5
5
  type MaybePromise<T> = T | Promise<T>;
6
6
  type CfProperties = Record<string, unknown>;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v0.0.0-experimental-4d16948
2
+ * @react-router/dev v0.0.0-experimental-23decd7bc
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -174,11 +174,6 @@ var import_node_fs = __toESM(require("fs"));
174
174
  var import_node_child_process = require("child_process");
175
175
  var import_package_json = __toESM(require("@npmcli/package-json"));
176
176
 
177
- // vite/vite-node.ts
178
- var import_server = require("vite-node/server");
179
- var import_client = require("vite-node/client");
180
- var import_source_map = require("vite-node/source-map");
181
-
182
177
  // vite/ssr-externals.ts
183
178
  var ssrExternals = isReactRouterRepo() ? [
184
179
  // This is only needed within this repo because these packages
@@ -202,6 +197,11 @@ async function createContext({
202
197
  }) {
203
198
  await preloadVite();
204
199
  const vite2 = getVite();
200
+ const [{ ViteNodeServer }, { ViteNodeRunner }, { installSourcemapsSupport }] = await Promise.all([
201
+ import("vite-node/server"),
202
+ import("vite-node/client"),
203
+ import("vite-node/source-map")
204
+ ]);
205
205
  const devServer = await vite2.createServer({
206
206
  root,
207
207
  mode,
@@ -231,11 +231,11 @@ async function createContext({
231
231
  plugins: []
232
232
  });
233
233
  await devServer.pluginContainer.buildStart({});
234
- const server = new import_server.ViteNodeServer(devServer);
235
- (0, import_source_map.installSourcemapsSupport)({
234
+ const server = new ViteNodeServer(devServer);
235
+ installSourcemapsSupport({
236
236
  getSourceMap: (source) => server.getSourceMap(source)
237
237
  });
238
- const runner = new import_client.ViteNodeRunner({
238
+ const runner = new ViteNodeRunner({
239
239
  root: devServer.config.root,
240
240
  base: devServer.config.base,
241
241
  fetchModule(id) {
@@ -269,7 +269,12 @@ var routeConfigEntrySchema = v.pipe(
269
269
  return !(typeof value === "object" && value !== null && "then" in value && "catch" in value);
270
270
  }, "Invalid type: Expected object but received a promise. Did you forget to await?"),
271
271
  v.object({
272
- id: v.optional(v.string()),
272
+ id: v.optional(
273
+ v.pipe(
274
+ v.string(),
275
+ v.notValue("root", "A route cannot use the reserved id 'root'.")
276
+ )
277
+ ),
273
278
  path: v.optional(v.string()),
274
279
  index: v.optional(v.boolean()),
275
280
  caseSensitive: v.optional(v.boolean()),
package/dist/vite.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v0.0.0-experimental-4d16948
2
+ * @react-router/dev v0.0.0-experimental-23decd7bc
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -46,13 +46,14 @@ module.exports = __toCommonJS(vite_exports);
46
46
 
47
47
  // vite/plugin.ts
48
48
  var import_node_crypto = require("crypto");
49
- var fs3 = __toESM(require("fs"));
49
+ var import_node_fs2 = require("fs");
50
+ var import_promises2 = require("fs/promises");
50
51
  var path5 = __toESM(require("path"));
51
52
  var url = __toESM(require("url"));
52
- var fse = __toESM(require("fs-extra"));
53
53
  var babel = __toESM(require("@babel/core"));
54
54
  var import_react_router2 = require("react-router");
55
55
  var import_es_module_lexer = require("es-module-lexer");
56
+ var import_tinyglobby = require("tinyglobby");
56
57
  var import_pick3 = __toESM(require("lodash/pick"));
57
58
  var import_jsesc = __toESM(require("jsesc"));
58
59
  var import_picocolors3 = __toESM(require("picocolors"));
@@ -68,11 +69,6 @@ var import_node_fs = __toESM(require("fs"));
68
69
  var import_node_child_process = require("child_process");
69
70
  var import_package_json = __toESM(require("@npmcli/package-json"));
70
71
 
71
- // vite/vite-node.ts
72
- var import_server = require("vite-node/server");
73
- var import_client = require("vite-node/client");
74
- var import_source_map = require("vite-node/source-map");
75
-
76
72
  // vite/vite.ts
77
73
  var import_pathe2 = __toESM(require("pathe"));
78
74
 
@@ -140,6 +136,11 @@ async function createContext({
140
136
  }) {
141
137
  await preloadVite();
142
138
  const vite2 = getVite();
139
+ const [{ ViteNodeServer }, { ViteNodeRunner }, { installSourcemapsSupport }] = await Promise.all([
140
+ import("vite-node/server"),
141
+ import("vite-node/client"),
142
+ import("vite-node/source-map")
143
+ ]);
143
144
  const devServer = await vite2.createServer({
144
145
  root,
145
146
  mode,
@@ -169,11 +170,11 @@ async function createContext({
169
170
  plugins: []
170
171
  });
171
172
  await devServer.pluginContainer.buildStart({});
172
- const server = new import_server.ViteNodeServer(devServer);
173
- (0, import_source_map.installSourcemapsSupport)({
173
+ const server = new ViteNodeServer(devServer);
174
+ installSourcemapsSupport({
174
175
  getSourceMap: (source) => server.getSourceMap(source)
175
176
  });
176
- const runner = new import_client.ViteNodeRunner({
177
+ const runner = new ViteNodeRunner({
177
178
  root: devServer.config.root,
178
179
  base: devServer.config.base,
179
180
  fetchModule(id) {
@@ -207,7 +208,12 @@ var routeConfigEntrySchema = v.pipe(
207
208
  return !(typeof value === "object" && value !== null && "then" in value && "catch" in value);
208
209
  }, "Invalid type: Expected object but received a promise. Did you forget to await?"),
209
210
  v.object({
210
- id: v.optional(v.string()),
211
+ id: v.optional(
212
+ v.pipe(
213
+ v.string(),
214
+ v.notValue("root", "A route cannot use the reserved id 'root'.")
215
+ )
216
+ ),
211
217
  path: v.optional(v.string()),
212
218
  index: v.optional(v.boolean()),
213
219
  caseSensitive: v.optional(v.boolean()),
@@ -684,22 +690,22 @@ async function resolveEntryFiles({
684
690
  let userEntryServerFile = findEntry(appDirectory, "entry.server");
685
691
  let entryServerFile;
686
692
  let entryClientFile = userEntryClientFile || "entry.client.tsx";
687
- let packageJsonPath = findEntry(rootDirectory, "package", {
688
- extensions: [".json"],
689
- absolute: true,
690
- walkParents: true
691
- });
692
- if (!packageJsonPath) {
693
- throw new Error(
694
- `Could not find package.json in ${rootDirectory} or any of its parent directories`
695
- );
696
- }
697
- let packageJsonDirectory = import_pathe3.default.dirname(packageJsonPath);
698
- let pkgJson = await import_package_json.default.load(packageJsonDirectory);
699
- let deps = pkgJson.content.dependencies ?? {};
700
693
  if (userEntryServerFile) {
701
694
  entryServerFile = userEntryServerFile;
702
695
  } else {
696
+ let packageJsonPath = findEntry(rootDirectory, "package", {
697
+ extensions: [".json"],
698
+ absolute: true,
699
+ walkParents: true
700
+ });
701
+ if (!packageJsonPath) {
702
+ throw new Error(
703
+ `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.`
704
+ );
705
+ }
706
+ let packageJsonDirectory = import_pathe3.default.dirname(packageJsonPath);
707
+ let pkgJson = await import_package_json.default.load(packageJsonDirectory);
708
+ let deps = pkgJson.content.dependencies ?? {};
703
709
  if (!deps["@react-router/node"]) {
704
710
  throw new Error(
705
711
  `Could not determine server runtime. Please install @react-router/node, or provide a custom entry.server.tsx/jsx file in your app directory.`
@@ -915,7 +921,7 @@ function generateRoutes(ctx) {
915
921
  lineages.set(route.id, lineage2);
916
922
  const fullpath2 = fullpath(lineage2);
917
923
  if (!fullpath2) continue;
918
- const pages = explodeOptionalSegments(fullpath2);
924
+ const pages = expand(fullpath2);
919
925
  pages.forEach((page) => allPages.add(page));
920
926
  lineage2.forEach(({ id }) => {
921
927
  let routePages = routeToPages.get(id);
@@ -1123,9 +1129,13 @@ function getRouteAnnotations({
1123
1129
  }
1124
1130
  function relativeImportSource(from, to) {
1125
1131
  let path6 = Path3.relative(Path3.dirname(from), to);
1132
+ let extension = Path3.extname(path6);
1126
1133
  path6 = Path3.join(Path3.dirname(path6), Pathe.filename(path6));
1127
1134
  if (!path6.startsWith("../")) path6 = "./" + path6;
1128
- return path6 + ".js";
1135
+ if (!extension || /\.(js|ts)x?$/.test(extension)) {
1136
+ extension = ".js";
1137
+ }
1138
+ return path6 + extension;
1129
1139
  }
1130
1140
  function rootDirsPath(ctx, typesPath) {
1131
1141
  const rel = Path3.relative(typesDirectory(ctx), typesPath);
@@ -1144,28 +1154,27 @@ function paramsType(path6) {
1144
1154
  })
1145
1155
  );
1146
1156
  }
1147
- function explodeOptionalSegments(path6) {
1148
- let segments = path6.split("/");
1149
- if (segments.length === 0) return [];
1150
- let [first, ...rest] = segments;
1151
- let isOptional = first.endsWith("?");
1152
- let required = first.replace(/\?$/, "");
1153
- if (rest.length === 0) {
1154
- return isOptional ? [required, ""] : [required];
1157
+ function expand(fullpath2) {
1158
+ function recurse(segments2, index) {
1159
+ if (index === segments2.length) return [""];
1160
+ const segment = segments2[index];
1161
+ const isOptional = segment.endsWith("?");
1162
+ const isDynamic = segment.startsWith(":");
1163
+ const required = segment.replace(/\?$/, "");
1164
+ const keep = !isOptional || isDynamic;
1165
+ const kept = isDynamic ? segment : required;
1166
+ const withoutSegment = recurse(segments2, index + 1);
1167
+ const withSegment = withoutSegment.map((rest) => [kept, rest].join("/"));
1168
+ if (keep) return withSegment;
1169
+ return [...withoutSegment, ...withSegment];
1155
1170
  }
1156
- let restExploded = explodeOptionalSegments(rest.join("/"));
1157
- let result = [];
1158
- result.push(
1159
- ...restExploded.map(
1160
- (subpath) => subpath === "" ? required : [required, subpath].join("/")
1161
- )
1162
- );
1163
- if (isOptional) {
1164
- result.push(...restExploded);
1171
+ const segments = fullpath2.split("/");
1172
+ const expanded = /* @__PURE__ */ new Set();
1173
+ for (let result of recurse(segments, 0)) {
1174
+ if (result !== "/") result = result.replace(/\/$/, "");
1175
+ expanded.add(result);
1165
1176
  }
1166
- return result.map(
1167
- (exploded) => path6.startsWith("/") && exploded === "" ? "/" : exploded
1168
- );
1177
+ return expanded;
1169
1178
  }
1170
1179
 
1171
1180
  // typegen/index.ts
@@ -2444,8 +2453,8 @@ function dedupe(array2) {
2444
2453
  return [...new Set(array2)];
2445
2454
  }
2446
2455
  var writeFileSafe = async (file, contents) => {
2447
- await fse.ensureDir(path5.dirname(file));
2448
- await fse.writeFile(file, contents);
2456
+ await (0, import_promises2.mkdir)(path5.dirname(file), { recursive: true });
2457
+ await (0, import_promises2.writeFile)(file, contents);
2449
2458
  };
2450
2459
  var getExportNames = (code) => {
2451
2460
  let [, exportSpecifiers] = (0, import_es_module_lexer.parse)(code);
@@ -2479,7 +2488,7 @@ var compileRouteFile = async (viteChildCompiler, ctx, routeFile, readRouteFile)
2479
2488
  };
2480
2489
  let [id, code] = await Promise.all([
2481
2490
  resolveId(),
2482
- readRouteFile?.() ?? fse.readFile(routePath, "utf-8"),
2491
+ readRouteFile?.() ?? (0, import_promises2.readFile)(routePath, "utf-8"),
2483
2492
  // pluginContainer.transform(...) fails if we don't do this first:
2484
2493
  moduleGraph.ensureEntryFromUrl(url2, ssr)
2485
2494
  ]);
@@ -2541,7 +2550,9 @@ var defaultEntriesDir = path5.resolve(
2541
2550
  "config",
2542
2551
  "defaults"
2543
2552
  );
2544
- var defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename2) => path5.join(defaultEntriesDir, filename2));
2553
+ var defaultEntries = (0, import_node_fs2.readdirSync)(defaultEntriesDir).map(
2554
+ (filename2) => path5.join(defaultEntriesDir, filename2)
2555
+ );
2545
2556
  invariant(defaultEntries.length > 0, "No default entries found");
2546
2557
  var reactRouterDevLoadContext = () => void 0;
2547
2558
  var reactRouterVitePlugin = () => {
@@ -2678,7 +2689,7 @@ var reactRouterVitePlugin = () => {
2678
2689
  ` : ""}`;
2679
2690
  };
2680
2691
  let loadViteManifest = async (directory) => {
2681
- let manifestContents = await fse.readFile(
2692
+ let manifestContents = await (0, import_promises2.readFile)(
2682
2693
  path5.resolve(directory, ".vite", "manifest.json"),
2683
2694
  "utf-8"
2684
2695
  );
@@ -2700,7 +2711,7 @@ var reactRouterVitePlugin = () => {
2700
2711
  };
2701
2712
  let generateSriManifest = async (ctx2) => {
2702
2713
  let clientBuildDirectory = getClientBuildDirectory(ctx2.reactRouterConfig);
2703
- let entries = fs3.readdirSync(clientBuildDirectory, {
2714
+ let entries = (0, import_node_fs2.readdirSync)(clientBuildDirectory, {
2704
2715
  withFileTypes: true,
2705
2716
  recursive: true
2706
2717
  });
@@ -2710,7 +2721,7 @@ var reactRouterVitePlugin = () => {
2710
2721
  const entryNormalizedPath = "parentPath" in entry && typeof entry.parentPath === "string" ? entry.parentPath : entry.path;
2711
2722
  let contents;
2712
2723
  try {
2713
- contents = await fse.readFile(
2724
+ contents = await (0, import_promises2.readFile)(
2714
2725
  path5.join(entryNormalizedPath, entry.name),
2715
2726
  "utf-8"
2716
2727
  );
@@ -2966,6 +2977,7 @@ var reactRouterVitePlugin = () => {
2966
2977
  config: async (_viteUserConfig, _viteConfigEnv) => {
2967
2978
  await preloadVite();
2968
2979
  let vite2 = getVite();
2980
+ let viteMajorVersion = parseInt(vite2.version.split(".")[0], 10);
2969
2981
  viteUserConfig = _viteUserConfig;
2970
2982
  viteConfigEnv = _viteConfigEnv;
2971
2983
  viteCommand = viteConfigEnv.command;
@@ -2995,7 +3007,7 @@ var reactRouterVitePlugin = () => {
2995
3007
  vite2.loadEnv(
2996
3008
  viteConfigEnv.mode,
2997
3009
  viteUserConfig.envDir ?? ctx.rootDirectory,
2998
- // We override default prefix of "VITE_" with a blank string since
3010
+ // We override the default prefix of "VITE_" with a blank string since
2999
3011
  // we're targeting the server, so we want to load all environment
3000
3012
  // variables, not just those explicitly marked for the client
3001
3013
  ""
@@ -3024,7 +3036,13 @@ var reactRouterVitePlugin = () => {
3024
3036
  ...Object.values(ctx.reactRouterConfig.routes).map(
3025
3037
  (route) => resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
3026
3038
  )
3027
- ] : [],
3039
+ ].map(
3040
+ (entry) => (
3041
+ // In Vite 7, the `optimizeDeps.entries` option only accepts glob patterns.
3042
+ // In prior versions, absolute file paths were treated differently.
3043
+ viteMajorVersion >= 7 ? (0, import_tinyglobby.escapePath)(entry) : entry
3044
+ )
3045
+ ) : [],
3028
3046
  include: [
3029
3047
  // Pre-bundle React dependencies to avoid React duplicates,
3030
3048
  // even if React dependencies are not direct dependencies.
@@ -3059,7 +3077,7 @@ var reactRouterVitePlugin = () => {
3059
3077
  conditions: viteCommand === "build" ? viteClientConditions : ["development", ...viteClientConditions]
3060
3078
  },
3061
3079
  base: viteUserConfig.base,
3062
- // When consumer provides an allow list for files that can be read by
3080
+ // When consumer provides an allowlist for files that can be read by
3063
3081
  // the server, ensure that the default entry files are included.
3064
3082
  // If we don't do this and a default entry file is used, the server
3065
3083
  // will throw an error that the file is not allowed to be read.
@@ -3351,15 +3369,15 @@ var reactRouterVitePlugin = () => {
3351
3369
  let src = path5.join(serverBuildDirectory, ssrAssetPath);
3352
3370
  let dest = path5.join(clientBuildDirectory, ssrAssetPath);
3353
3371
  if (!userSsrEmitAssets) {
3354
- if (!fse.existsSync(dest)) {
3355
- await fse.move(src, dest);
3372
+ if (!(0, import_node_fs2.existsSync)(dest)) {
3373
+ await (0, import_promises2.rename)(src, dest);
3356
3374
  movedAssetPaths.push(dest);
3357
3375
  } else {
3358
- await fse.remove(src);
3376
+ await (0, import_promises2.rm)(src, { force: true, recursive: true });
3359
3377
  removedAssetPaths.push(dest);
3360
3378
  }
3361
- } else if (!fse.existsSync(dest)) {
3362
- await fse.copy(src, dest);
3379
+ } else if (!(0, import_node_fs2.existsSync)(dest)) {
3380
+ await (0, import_promises2.cp)(src, dest, { recursive: true });
3363
3381
  copiedAssetPaths.push(dest);
3364
3382
  }
3365
3383
  }
@@ -3370,7 +3388,7 @@ var reactRouterVitePlugin = () => {
3370
3388
  await Promise.all(
3371
3389
  ssrCssPaths.map(async (cssPath) => {
3372
3390
  let src = path5.join(serverBuildDirectory, cssPath);
3373
- await fse.remove(src);
3391
+ await (0, import_promises2.rm)(src, { force: true, recursive: true });
3374
3392
  removedAssetPaths.push(src);
3375
3393
  })
3376
3394
  );
@@ -3381,9 +3399,9 @@ var reactRouterVitePlugin = () => {
3381
3399
  await Promise.all(
3382
3400
  Array.from(cleanedAssetDirs).map(async (dir) => {
3383
3401
  try {
3384
- const files = await fse.readdir(dir);
3402
+ const files = await (0, import_promises2.readdir)(dir, { recursive: true });
3385
3403
  if (files.length === 0) {
3386
- await fse.remove(dir);
3404
+ await (0, import_promises2.rm)(dir, { force: true, recursive: true });
3387
3405
  }
3388
3406
  } catch {
3389
3407
  }
@@ -3447,7 +3465,7 @@ var reactRouterVitePlugin = () => {
3447
3465
  "due to ssr:false"
3448
3466
  ].join(" ")
3449
3467
  );
3450
- fse.removeSync(serverBuildDirectory);
3468
+ (0, import_node_fs2.rmSync)(serverBuildDirectory, { force: true, recursive: true });
3451
3469
  }
3452
3470
  }
3453
3471
  },
@@ -3465,7 +3483,7 @@ var reactRouterVitePlugin = () => {
3465
3483
  // primarily ensures code is never duplicated across a route module and
3466
3484
  // its chunks. If we didn't have this plugin, any app that explicitly
3467
3485
  // imports a route module would result in duplicate code since the app
3468
- // would contain code for both the unprocessed route module as well as its
3486
+ // would contain code for both the unprocessed route module and its
3469
3487
  // individual chunks. This is because, since they have different module
3470
3488
  // IDs, they are treated as completely separate modules even though they
3471
3489
  // all reference the same underlying file. This plugin addresses this by
@@ -3771,11 +3789,8 @@ var reactRouterVitePlugin = () => {
3771
3789
  );
3772
3790
  return [
3773
3791
  "const exports = {}",
3774
- await fse.readFile(reactRefreshRuntimePath, "utf8"),
3775
- await fse.readFile(
3776
- require.resolve("./static/refresh-utils.cjs"),
3777
- "utf8"
3778
- ),
3792
+ await (0, import_promises2.readFile)(reactRefreshRuntimePath, "utf8"),
3793
+ await (0, import_promises2.readFile)(require.resolve("./static/refresh-utils.cjs"), "utf8"),
3779
3794
  "export default exports"
3780
3795
  ].join("\n");
3781
3796
  }
@@ -3858,10 +3873,10 @@ var reactRouterVitePlugin = () => {
3858
3873
  {
3859
3874
  name: "react-router-server-change-trigger-client-hmr",
3860
3875
  // This hook is only available in Vite v6+ so this is a no-op in v5.
3861
- // Previously the server and client modules were shared in a single module
3876
+ // Previously, the server and client modules were shared in a single module
3862
3877
  // graph. This meant that changes to server code automatically resulted in
3863
- // client HMR updates. In Vite v6+ these module graphs are separate from
3864
- // each other so we need to manually trigger client HMR updates if server
3878
+ // client HMR updates. In Vite v6+, these module graphs are separate from
3879
+ // each other, so we need to manually trigger client HMR updates if server
3865
3880
  // code has changed.
3866
3881
  hotUpdate({ server, modules }) {
3867
3882
  if (this.environment.name !== "ssr" && modules.length <= 0) {
@@ -4055,7 +4070,7 @@ async function handleSpaMode(viteConfig, reactRouterConfig, serverBuildDirectory
4055
4070
  "SPA Mode: Did you forget to include `<Scripts/>` in your root route? Your pre-rendered HTML cannot hydrate without `<Scripts />`."
4056
4071
  );
4057
4072
  }
4058
- await fse.writeFile(path5.join(clientBuildDirectory, filename2), html);
4073
+ await (0, import_promises2.writeFile)(path5.join(clientBuildDirectory, filename2), html);
4059
4074
  let prettyDir = path5.relative(process.cwd(), clientBuildDirectory);
4060
4075
  let prettyPath = path5.join(prettyDir, filename2);
4061
4076
  if (build.prerender.length > 0) {
@@ -4186,8 +4201,8 @@ ${normalizedPath}`
4186
4201
  }
4187
4202
  let outdir = path5.relative(process.cwd(), clientBuildDirectory);
4188
4203
  let outfile = path5.join(outdir, ...normalizedPath.split("/"));
4189
- await fse.ensureDir(path5.dirname(outfile));
4190
- await fse.outputFile(outfile, data);
4204
+ await (0, import_promises2.mkdir)(path5.dirname(outfile), { recursive: true });
4205
+ await (0, import_promises2.writeFile)(outfile, data);
4191
4206
  viteConfig.logger.info(
4192
4207
  `Prerender (data): ${prerenderPath} -> ${import_picocolors3.default.bold(outfile)}`
4193
4208
  );
@@ -4225,8 +4240,8 @@ ${html}`
4225
4240
  }
4226
4241
  let outdir = path5.relative(process.cwd(), clientBuildDirectory);
4227
4242
  let outfile = path5.join(outdir, ...normalizedPath.split("/"), "index.html");
4228
- await fse.ensureDir(path5.dirname(outfile));
4229
- await fse.outputFile(outfile, html);
4243
+ await (0, import_promises2.mkdir)(path5.dirname(outfile), { recursive: true });
4244
+ await (0, import_promises2.writeFile)(outfile, html);
4230
4245
  viteConfig.logger.info(
4231
4246
  `Prerender (html): ${prerenderPath} -> ${import_picocolors3.default.bold(outfile)}`
4232
4247
  );
@@ -4244,8 +4259,8 @@ ${content.toString("utf8")}`
4244
4259
  }
4245
4260
  let outdir = path5.relative(process.cwd(), clientBuildDirectory);
4246
4261
  let outfile = path5.join(outdir, ...normalizedPath.split("/"));
4247
- await fse.ensureDir(path5.dirname(outfile));
4248
- await fse.outputFile(outfile, content);
4262
+ await (0, import_promises2.mkdir)(path5.dirname(outfile), { recursive: true });
4263
+ await (0, import_promises2.writeFile)(outfile, content);
4249
4264
  viteConfig.logger.info(
4250
4265
  `Prerender (resource): ${prerenderPath} -> ${import_picocolors3.default.bold(outfile)}`
4251
4266
  );
@@ -4498,7 +4513,7 @@ async function cleanBuildDirectory(viteConfig, ctx) {
4498
4513
  return !relativePath.startsWith("..") && !path5.isAbsolute(relativePath);
4499
4514
  };
4500
4515
  if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
4501
- await fse.remove(buildDirectory);
4516
+ await (0, import_promises2.rm)(buildDirectory, { force: true, recursive: true });
4502
4517
  }
4503
4518
  }
4504
4519
  async function cleanViteManifests(environmentsOptions, ctx) {
@@ -4511,15 +4526,15 @@ async function cleanViteManifests(environmentsOptions, ctx) {
4511
4526
  );
4512
4527
  await Promise.all(
4513
4528
  viteManifestPaths.map(async (viteManifestPath) => {
4514
- let manifestExists = await fse.pathExists(viteManifestPath);
4529
+ let manifestExists = (0, import_node_fs2.existsSync)(viteManifestPath);
4515
4530
  if (!manifestExists) return;
4516
4531
  if (!ctx.viteManifestEnabled) {
4517
- await fse.remove(viteManifestPath);
4532
+ await (0, import_promises2.rm)(viteManifestPath, { force: true, recursive: true });
4518
4533
  }
4519
4534
  let viteDir = path5.dirname(viteManifestPath);
4520
- let viteDirFiles = await fse.readdir(viteDir);
4535
+ let viteDirFiles = await (0, import_promises2.readdir)(viteDir, { recursive: true });
4521
4536
  if (viteDirFiles.length === 0) {
4522
- await fse.remove(viteDir);
4537
+ await (0, import_promises2.rm)(viteDir, { force: true, recursive: true });
4523
4538
  }
4524
4539
  })
4525
4540
  );
@@ -4655,13 +4670,13 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4655
4670
  },
4656
4671
  build: {
4657
4672
  // We move SSR-only assets to client assets. Note that the
4658
- // SSR build can also emit code-split JS files (e.g. by
4673
+ // SSR build can also emit code-split JS files (e.g., by
4659
4674
  // dynamic import) under the same assets directory
4660
4675
  // regardless of "ssrEmitAssets" option, so we also need to
4661
- // keep these JS files have to be kept as-is.
4676
+ // keep these JS files to be kept as-is.
4662
4677
  ssrEmitAssets: true,
4663
4678
  copyPublicDir: false,
4664
- // Assets in the public directory are only used by the client
4679
+ // The client only uses assets in the public directory
4665
4680
  rollupOptions: {
4666
4681
  input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id,
4667
4682
  output: {
@@ -4685,7 +4700,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4685
4700
  route.file
4686
4701
  );
4687
4702
  let isRootRoute = route.file === ctx.reactRouterConfig.routes.root.file;
4688
- let code = fse.readFileSync(routeFilePath, "utf-8");
4703
+ let code = (0, import_node_fs2.readFileSync)(routeFilePath, "utf-8");
4689
4704
  return [
4690
4705
  `${routeFilePath}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
4691
4706
  ...ctx.reactRouterConfig.future.unstable_splitRouteModules && !isRootRoute ? routeChunkExportNames.map(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-router/dev",
3
- "version": "0.0.0-experimental-4d16948",
3
+ "version": "0.0.0-experimental-23decd7bc",
4
4
  "description": "Dev tools and CLI for React Router",
5
5
  "homepage": "https://reactrouter.com",
6
6
  "bugs": {
@@ -75,7 +75,6 @@
75
75
  "dedent": "^1.5.3",
76
76
  "es-module-lexer": "^1.3.1",
77
77
  "exit-hook": "2.2.1",
78
- "fs-extra": "^10.0.0",
79
78
  "jsesc": "3.0.2",
80
79
  "lodash": "^4.17.21",
81
80
  "pathe": "^1.1.2",
@@ -84,9 +83,10 @@
84
83
  "react-refresh": "^0.14.0",
85
84
  "semver": "^7.3.7",
86
85
  "set-cookie-parser": "^2.6.0",
86
+ "tinyglobby": "^0.2.14",
87
87
  "valibot": "^0.41.0",
88
88
  "vite-node": "^3.1.4",
89
- "@react-router/node": "0.0.0-experimental-4d16948"
89
+ "@react-router/node": "0.0.0-experimental-23decd7bc"
90
90
  },
91
91
  "devDependencies": {
92
92
  "@types/babel__core": "^7.20.5",
@@ -94,7 +94,6 @@
94
94
  "@types/babel__traverse": "^7.20.5",
95
95
  "@types/dedent": "^0.7.0",
96
96
  "@types/express": "^4.17.9",
97
- "@types/fs-extra": "^8.1.2",
98
97
  "@types/jsesc": "^3.0.1",
99
98
  "@types/lodash": "^4.14.182",
100
99
  "@types/node": "^20.0.0",
@@ -110,15 +109,15 @@
110
109
  "vite": "^6.1.0",
111
110
  "wireit": "0.14.9",
112
111
  "wrangler": "^4.2.0",
113
- "react-router": "^0.0.0-experimental-4d16948",
114
- "@react-router/serve": "0.0.0-experimental-4d16948"
112
+ "@react-router/serve": "0.0.0-experimental-23decd7bc",
113
+ "react-router": "^0.0.0-experimental-23decd7bc"
115
114
  },
116
115
  "peerDependencies": {
117
116
  "typescript": "^5.1.0",
118
- "vite": "^5.1.0 || ^6.0.0",
117
+ "vite": "^5.1.0 || ^6.0.0 || ^7.0.0",
119
118
  "wrangler": "^3.28.2 || ^4.0.0",
120
- "@react-router/serve": "^0.0.0-experimental-4d16948",
121
- "react-router": "^0.0.0-experimental-4d16948"
119
+ "@react-router/serve": "^0.0.0-experimental-23decd7bc",
120
+ "react-router": "^0.0.0-experimental-23decd7bc"
122
121
  },
123
122
  "peerDependenciesMeta": {
124
123
  "@react-router/serve": {