@react-router/dev 0.0.0-experimental-701a32801 → 0.0.0-experimental-b2bc694a6

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,14 @@
1
1
  # `@react-router/dev`
2
2
 
3
+ ## 7.5.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies:
8
+ - `react-router@7.5.3`
9
+ - `@react-router/node@7.5.3`
10
+ - `@react-router/serve@7.5.3`
11
+
3
12
  ## 7.5.2
4
13
 
5
14
  ### 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-701a32801
3
+ * @react-router/dev v0.0.0-experimental-b2bc694a6
4
4
  *
5
5
  * Copyright (c) Remix Software Inc.
6
6
  *
@@ -143,6 +143,15 @@ async function createContext({
143
143
  optimizeDeps: {
144
144
  noDiscovery: true
145
145
  },
146
+ css: {
147
+ // This empty PostCSS config object prevents the PostCSS config file from
148
+ // being loaded. We don't need it in a React Router config context, and
149
+ // there's also an issue in Vite 5 when using a .ts PostCSS config file in
150
+ // an ESM project: https://github.com/vitejs/vite/issues/15869. Consumers
151
+ // can work around this in their own Vite config file, but they can't
152
+ // configure this internal usage of vite-node.
153
+ postcss: {}
154
+ },
146
155
  configFile: false,
147
156
  envFile: false,
148
157
  plugins: []
@@ -339,12 +348,17 @@ async function resolveConfig({
339
348
  serverModuleFormat: "esm",
340
349
  ssr: true
341
350
  };
351
+ let userAndPresetConfigs = mergeReactRouterConfig(
352
+ ...presets,
353
+ reactRouterUserConfig
354
+ );
342
355
  let {
343
356
  appDirectory: userAppDirectory,
344
357
  basename: basename2,
345
358
  buildDirectory: userBuildDirectory,
346
359
  buildEnd,
347
360
  prerender,
361
+ routeDiscovery: userRouteDiscovery,
348
362
  serverBuildFile,
349
363
  serverBundles,
350
364
  serverModuleFormat,
@@ -352,7 +366,7 @@ async function resolveConfig({
352
366
  } = {
353
367
  ...defaults,
354
368
  // Default values should be completely overridden by user/preset config, not merged
355
- ...mergeReactRouterConfig(...presets, reactRouterUserConfig)
369
+ ...userAndPresetConfigs
356
370
  };
357
371
  if (!ssr && serverBundles) {
358
372
  serverBundles = void 0;
@@ -363,6 +377,32 @@ async function resolveConfig({
363
377
  "The `prerender` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths"
364
378
  );
365
379
  }
380
+ let routeDiscovery;
381
+ if (userRouteDiscovery == null) {
382
+ if (ssr) {
383
+ routeDiscovery = {
384
+ mode: "lazy",
385
+ manifestPath: "/__manifest"
386
+ };
387
+ } else {
388
+ routeDiscovery = { mode: "initial" };
389
+ }
390
+ } else if (userRouteDiscovery.mode === "initial") {
391
+ routeDiscovery = userRouteDiscovery;
392
+ } else if (userRouteDiscovery.mode === "lazy") {
393
+ if (!ssr) {
394
+ return err(
395
+ 'The `routeDiscovery.mode` config cannot be set to "lazy" when setting `ssr:false`'
396
+ );
397
+ }
398
+ let { manifestPath } = userRouteDiscovery;
399
+ if (manifestPath != null && !manifestPath.startsWith("/")) {
400
+ return err(
401
+ 'The `routeDiscovery.manifestPath` config must be a root-relative pathname beginning with a slash (i.e., "/__manifest")'
402
+ );
403
+ }
404
+ routeDiscovery = userRouteDiscovery;
405
+ }
366
406
  let appDirectory = import_pathe3.default.resolve(root, userAppDirectory || "app");
367
407
  let buildDirectory = import_pathe3.default.resolve(root, userBuildDirectory);
368
408
  let rootRouteFile = findEntry(appDirectory, "root");
@@ -430,6 +470,7 @@ async function resolveConfig({
430
470
  future,
431
471
  prerender,
432
472
  routes: routes2,
473
+ routeDiscovery,
433
474
  serverBuildFile,
434
475
  serverBundles,
435
476
  serverModuleFormat,
@@ -442,12 +483,13 @@ async function resolveConfig({
442
483
  }
443
484
  async function createConfigLoader({
444
485
  rootDirectory: root,
445
- watch: watch2
486
+ watch: watch2,
487
+ mode
446
488
  }) {
447
489
  root = root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
448
490
  let viteNodeContext = await createContext({
449
491
  root,
450
- mode: watch2 ? "development" : "production"
492
+ mode
451
493
  });
452
494
  let reactRouterConfigFile = findEntry(root, "react-router.config", {
453
495
  absolute: true
@@ -523,9 +565,13 @@ async function createConfigLoader({
523
565
  }
524
566
  };
525
567
  }
526
- async function loadConfig({ rootDirectory }) {
568
+ async function loadConfig({
569
+ rootDirectory,
570
+ mode
571
+ }) {
527
572
  let configLoader = await createConfigLoader({
528
573
  rootDirectory,
574
+ mode,
529
575
  watch: false
530
576
  });
531
577
  let config = await configLoader.getConfig();
@@ -533,13 +579,24 @@ async function loadConfig({ rootDirectory }) {
533
579
  return config;
534
580
  }
535
581
  function findEntry(dir, basename2, options) {
536
- for (let ext of entryExts) {
537
- let file = import_pathe3.default.resolve(dir, basename2 + ext);
538
- if (import_node_fs.default.existsSync(file)) {
539
- return options?.absolute ?? false ? file : import_pathe3.default.relative(dir, file);
582
+ let currentDir = import_pathe3.default.resolve(dir);
583
+ let { root } = import_pathe3.default.parse(currentDir);
584
+ while (true) {
585
+ for (let ext of options?.extensions ?? entryExts) {
586
+ let file = import_pathe3.default.resolve(currentDir, basename2 + ext);
587
+ if (import_node_fs.default.existsSync(file)) {
588
+ return options?.absolute ?? false ? file : import_pathe3.default.relative(dir, file);
589
+ }
590
+ }
591
+ if (!options?.walkParents) {
592
+ return void 0;
540
593
  }
594
+ let parentDir = import_pathe3.default.dirname(currentDir);
595
+ if (currentDir === root || parentDir === currentDir) {
596
+ return void 0;
597
+ }
598
+ currentDir = parentDir;
541
599
  }
542
- return void 0;
543
600
  }
544
601
  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;
545
602
  var init_config = __esm({
@@ -808,12 +865,12 @@ var init_generate = __esm({
808
865
  });
809
866
 
810
867
  // typegen/index.ts
811
- async function run(rootDirectory) {
812
- const ctx = await createContext2({ rootDirectory, watch: false });
868
+ async function run(rootDirectory, { mode }) {
869
+ const ctx = await createContext2({ rootDirectory, mode, watch: false });
813
870
  await writeAll(ctx);
814
871
  }
815
- async function watch(rootDirectory, { logger } = {}) {
816
- const ctx = await createContext2({ rootDirectory, watch: true });
872
+ async function watch(rootDirectory, { mode, logger }) {
873
+ const ctx = await createContext2({ rootDirectory, mode, watch: true });
817
874
  await writeAll(ctx);
818
875
  logger?.info(import_picocolors3.default.green("generated types"), { timestamp: true, clear: true });
819
876
  ctx.configLoader.onChange(async ({ result, routeConfigChanged }) => {
@@ -836,9 +893,10 @@ async function watch(rootDirectory, { logger } = {}) {
836
893
  }
837
894
  async function createContext2({
838
895
  rootDirectory,
839
- watch: watch2
896
+ watch: watch2,
897
+ mode
840
898
  }) {
841
- const configLoader = await createConfigLoader({ rootDirectory, watch: watch2 });
899
+ const configLoader = await createConfigLoader({ rootDirectory, mode, watch: watch2 });
842
900
  const configResult = await configLoader.getConfig();
843
901
  if (!configResult.ok) {
844
902
  throw new Error(configResult.error);
@@ -933,6 +991,7 @@ var init_typegen = __esm({
933
991
  export const isSpaMode: ServerBuild["isSpaMode"];
934
992
  export const prerender: ServerBuild["prerender"];
935
993
  export const publicPath: ServerBuild["publicPath"];
994
+ export const routeDiscovery: ServerBuild["routeDiscovery"];
936
995
  export const routes: ServerBuild["routes"];
937
996
  export const ssr: ServerBuild["ssr"];
938
997
  export const unstable_getCriticalCss: ServerBuild["unstable_getCriticalCss"];
@@ -1257,8 +1316,9 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1257
1316
  ""
1258
1317
  ) : null;
1259
1318
  let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
1319
+ let assetsDir = (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
1260
1320
  return path7.posix.join(
1261
- (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : viteUserConfig?.build?.assetsDir) ?? "assets",
1321
+ assetsDir,
1262
1322
  `[name]${routeChunkSuffix}-[hash].js`
1263
1323
  );
1264
1324
  }
@@ -1412,7 +1472,10 @@ __export(build_exports, {
1412
1472
  async function build(root, viteBuildOptions) {
1413
1473
  await preloadVite();
1414
1474
  let vite2 = getVite();
1415
- let configResult = await loadConfig({ rootDirectory: root });
1475
+ let configResult = await loadConfig({
1476
+ rootDirectory: root,
1477
+ mode: viteBuildOptions.mode ?? "production"
1478
+ });
1416
1479
  if (!configResult.ok) {
1417
1480
  throw new Error(configResult.error);
1418
1481
  }
@@ -1738,9 +1801,12 @@ function transpile(tsx, options = {}) {
1738
1801
  init_profiler();
1739
1802
  init_typegen();
1740
1803
  init_vite();
1741
- async function routes(reactRouterRoot, flags = {}) {
1742
- let rootDirectory = reactRouterRoot ?? process.cwd();
1743
- let configResult = await loadConfig({ rootDirectory });
1804
+ async function routes(rootDirectory, flags = {}) {
1805
+ rootDirectory = resolveRootDirectory(rootDirectory, flags);
1806
+ let configResult = await loadConfig({
1807
+ rootDirectory,
1808
+ mode: flags.mode ?? "production"
1809
+ });
1744
1810
  if (!configResult.ok) {
1745
1811
  console.error(import_picocolors7.default.red(configResult.error));
1746
1812
  process.exit(1);
@@ -1749,9 +1815,7 @@ async function routes(reactRouterRoot, flags = {}) {
1749
1815
  console.log(formatRoutes(configResult.value.routes, format));
1750
1816
  }
1751
1817
  async function build2(root, options = {}) {
1752
- if (!root) {
1753
- root = process.env.REACT_ROUTER_ROOT || process.cwd();
1754
- }
1818
+ root = resolveRootDirectory(root, options);
1755
1819
  let { build: build3 } = await Promise.resolve().then(() => (init_build(), build_exports));
1756
1820
  if (options.profile) {
1757
1821
  await start();
@@ -1768,6 +1832,7 @@ async function dev2(root, options = {}) {
1768
1832
  await start();
1769
1833
  }
1770
1834
  (0, import_exit_hook.default)(() => stop(console.info));
1835
+ root = resolveRootDirectory(root, options);
1771
1836
  await dev3(root, options);
1772
1837
  await new Promise(() => {
1773
1838
  });
@@ -1779,14 +1844,17 @@ var conjunctionListFormat = new Intl.ListFormat("en", {
1779
1844
  style: "long",
1780
1845
  type: "conjunction"
1781
1846
  });
1782
- async function generateEntry(entry, reactRouterRoot, flags = {}) {
1847
+ async function generateEntry(entry, rootDirectory, flags = {}) {
1783
1848
  if (!entry) {
1784
- await generateEntry("entry.client", reactRouterRoot, flags);
1785
- await generateEntry("entry.server", reactRouterRoot, flags);
1849
+ await generateEntry("entry.client", rootDirectory, flags);
1850
+ await generateEntry("entry.server", rootDirectory, flags);
1786
1851
  return;
1787
1852
  }
1788
- let rootDirectory = reactRouterRoot ?? process.cwd();
1789
- let configResult = await loadConfig({ rootDirectory });
1853
+ rootDirectory = resolveRootDirectory(rootDirectory, flags);
1854
+ let configResult = await loadConfig({
1855
+ rootDirectory,
1856
+ mode: flags.mode ?? "production"
1857
+ });
1790
1858
  if (!configResult.ok) {
1791
1859
  console.error(import_picocolors7.default.red(configResult.error));
1792
1860
  return;
@@ -1841,6 +1909,12 @@ async function generateEntry(entry, reactRouterRoot, flags = {}) {
1841
1909
  )
1842
1910
  );
1843
1911
  }
1912
+ function resolveRootDirectory(root, flags) {
1913
+ if (root) {
1914
+ return path8.resolve(root);
1915
+ }
1916
+ return process.env.REACT_ROUTER_ROOT || (flags?.config ? path8.dirname(path8.resolve(flags.config)) : process.cwd());
1917
+ }
1844
1918
  async function checkForEntry(rootDirectory, appDirectory, entries2) {
1845
1919
  for (let entry of entries2) {
1846
1920
  let entryPath = path8.resolve(appDirectory, entry);
@@ -1863,17 +1937,22 @@ async function createClientEntry(rootDirectory, appDirectory, inputFile) {
1863
1937
  return contents;
1864
1938
  }
1865
1939
  async function typegen(root, flags) {
1866
- root ??= process.cwd();
1940
+ root = resolveRootDirectory(root, flags);
1867
1941
  if (flags.watch) {
1868
1942
  await preloadVite();
1869
1943
  const vite2 = getVite();
1870
1944
  const logger = vite2.createLogger("info", { prefix: "[react-router]" });
1871
- await watch(root, { logger });
1945
+ await watch(root, {
1946
+ mode: flags.mode ?? "development",
1947
+ logger
1948
+ });
1872
1949
  await new Promise(() => {
1873
1950
  });
1874
1951
  return;
1875
1952
  }
1876
- await run(root);
1953
+ await run(root, {
1954
+ mode: flags.mode ?? "production"
1955
+ });
1877
1956
  }
1878
1957
 
1879
1958
  // cli/run.ts
package/dist/config.d.ts CHANGED
@@ -102,6 +102,22 @@ type ReactRouterConfig = {
102
102
  * other platforms and tools.
103
103
  */
104
104
  presets?: Array<Preset>;
105
+ /**
106
+ * Control the "Lazy Route Discovery" behavior
107
+ *
108
+ * - `routeDiscovery.mode`: By default, this resolves to `lazy` which will
109
+ * lazily discover routes as the user navigates around your application.
110
+ * You can set this to `initial` to opt-out of this behavior and load all
111
+ * routes with the initial HTML document load.
112
+ * - `routeDiscovery.manifestPath`: The path to serve the manifest file from.
113
+ * Only applies to `mode: "lazy"` and defaults to `/__manifest`.
114
+ */
115
+ routeDiscovery?: {
116
+ mode: "lazy";
117
+ manifestPath?: string;
118
+ } | {
119
+ mode: "initial";
120
+ };
105
121
  /**
106
122
  * The file name of the server build output. This file
107
123
  * should end in a `.js` extension and should be deployed to your server.
@@ -148,6 +164,17 @@ type ResolvedReactRouterConfig = Readonly<{
148
164
  * function returning an array to dynamically generate URLs.
149
165
  */
150
166
  prerender: ReactRouterConfig["prerender"];
167
+ /**
168
+ * Control the "Lazy Route Discovery" behavior
169
+ *
170
+ * - `routeDiscovery.mode`: By default, this resolves to `lazy` which will
171
+ * lazily discover routes as the user navigates around your application.
172
+ * You can set this to `initial` to opt-out of this behavior and load all
173
+ * routes with the initial HTML document load.
174
+ * - `routeDiscovery.manifestPath`: The path to serve the manifest file from.
175
+ * Only applies to `mode: "lazy"` and defaults to `/__manifest`.
176
+ */
177
+ routeDiscovery: ReactRouterConfig["routeDiscovery"];
151
178
  /**
152
179
  * An object of all available routes, keyed by route id.
153
180
  */
package/dist/config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v0.0.0-experimental-701a32801
2
+ * @react-router/dev v0.0.0-experimental-b2bc694a6
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-701a32801
2
+ * @react-router/dev v0.0.0-experimental-b2bc694a6
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v0.0.0-experimental-701a32801
2
+ * @react-router/dev v0.0.0-experimental-b2bc694a6
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -113,7 +113,9 @@ function fromNodeRequest(nodeReq, nodeRes) {
113
113
  }
114
114
  async function toNodeRequest(res, nodeRes) {
115
115
  nodeRes.statusCode = res.status;
116
- nodeRes.statusMessage = res.statusText;
116
+ if (!nodeRes.req || nodeRes.req.httpVersionMajor < 2) {
117
+ nodeRes.statusMessage = res.statusText;
118
+ }
117
119
  let cookiesStrings = [];
118
120
  for (let [name, value] of res.headers) {
119
121
  if (name === "set-cookie") {
@@ -213,6 +215,15 @@ async function createContext({
213
215
  optimizeDeps: {
214
216
  noDiscovery: true
215
217
  },
218
+ css: {
219
+ // This empty PostCSS config object prevents the PostCSS config file from
220
+ // being loaded. We don't need it in a React Router config context, and
221
+ // there's also an issue in Vite 5 when using a .ts PostCSS config file in
222
+ // an ESM project: https://github.com/vitejs/vite/issues/15869. Consumers
223
+ // can work around this in their own Vite config file, but they can't
224
+ // configure this internal usage of vite-node.
225
+ postcss: {}
226
+ },
216
227
  configFile: false,
217
228
  envFile: false,
218
229
  plugins: []
@@ -432,12 +443,17 @@ async function resolveConfig({
432
443
  serverModuleFormat: "esm",
433
444
  ssr: true
434
445
  };
446
+ let userAndPresetConfigs = mergeReactRouterConfig(
447
+ ...presets,
448
+ reactRouterUserConfig
449
+ );
435
450
  let {
436
451
  appDirectory: userAppDirectory,
437
452
  basename,
438
453
  buildDirectory: userBuildDirectory,
439
454
  buildEnd,
440
455
  prerender,
456
+ routeDiscovery: userRouteDiscovery,
441
457
  serverBuildFile,
442
458
  serverBundles,
443
459
  serverModuleFormat,
@@ -445,7 +461,7 @@ async function resolveConfig({
445
461
  } = {
446
462
  ...defaults,
447
463
  // Default values should be completely overridden by user/preset config, not merged
448
- ...mergeReactRouterConfig(...presets, reactRouterUserConfig)
464
+ ...userAndPresetConfigs
449
465
  };
450
466
  if (!ssr && serverBundles) {
451
467
  serverBundles = void 0;
@@ -456,6 +472,32 @@ async function resolveConfig({
456
472
  "The `prerender` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths"
457
473
  );
458
474
  }
475
+ let routeDiscovery;
476
+ if (userRouteDiscovery == null) {
477
+ if (ssr) {
478
+ routeDiscovery = {
479
+ mode: "lazy",
480
+ manifestPath: "/__manifest"
481
+ };
482
+ } else {
483
+ routeDiscovery = { mode: "initial" };
484
+ }
485
+ } else if (userRouteDiscovery.mode === "initial") {
486
+ routeDiscovery = userRouteDiscovery;
487
+ } else if (userRouteDiscovery.mode === "lazy") {
488
+ if (!ssr) {
489
+ return err(
490
+ 'The `routeDiscovery.mode` config cannot be set to "lazy" when setting `ssr:false`'
491
+ );
492
+ }
493
+ let { manifestPath } = userRouteDiscovery;
494
+ if (manifestPath != null && !manifestPath.startsWith("/")) {
495
+ return err(
496
+ 'The `routeDiscovery.manifestPath` config must be a root-relative pathname beginning with a slash (i.e., "/__manifest")'
497
+ );
498
+ }
499
+ routeDiscovery = userRouteDiscovery;
500
+ }
459
501
  let appDirectory = import_pathe3.default.resolve(root, userAppDirectory || "app");
460
502
  let buildDirectory = import_pathe3.default.resolve(root, userBuildDirectory);
461
503
  let rootRouteFile = findEntry(appDirectory, "root");
@@ -523,6 +565,7 @@ async function resolveConfig({
523
565
  future,
524
566
  prerender,
525
567
  routes,
568
+ routeDiscovery,
526
569
  serverBuildFile,
527
570
  serverBundles,
528
571
  serverModuleFormat,
@@ -535,12 +578,13 @@ async function resolveConfig({
535
578
  }
536
579
  async function createConfigLoader({
537
580
  rootDirectory: root,
538
- watch
581
+ watch,
582
+ mode
539
583
  }) {
540
584
  root = root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
541
585
  let viteNodeContext = await createContext({
542
586
  root,
543
- mode: watch ? "development" : "production"
587
+ mode
544
588
  });
545
589
  let reactRouterConfigFile = findEntry(root, "react-router.config", {
546
590
  absolute: true
@@ -616,9 +660,13 @@ async function createConfigLoader({
616
660
  }
617
661
  };
618
662
  }
619
- async function loadConfig({ rootDirectory }) {
663
+ async function loadConfig({
664
+ rootDirectory,
665
+ mode
666
+ }) {
620
667
  let configLoader = await createConfigLoader({
621
668
  rootDirectory,
669
+ mode,
622
670
  watch: false
623
671
  });
624
672
  let config = await configLoader.getConfig();
@@ -627,13 +675,24 @@ async function loadConfig({ rootDirectory }) {
627
675
  }
628
676
  var entryExts = [".js", ".jsx", ".ts", ".tsx"];
629
677
  function findEntry(dir, basename, options) {
630
- for (let ext of entryExts) {
631
- let file = import_pathe3.default.resolve(dir, basename + ext);
632
- if (import_node_fs.default.existsSync(file)) {
633
- return options?.absolute ?? false ? file : import_pathe3.default.relative(dir, file);
678
+ let currentDir = import_pathe3.default.resolve(dir);
679
+ let { root } = import_pathe3.default.parse(currentDir);
680
+ while (true) {
681
+ for (let ext of options?.extensions ?? entryExts) {
682
+ let file = import_pathe3.default.resolve(currentDir, basename + ext);
683
+ if (import_node_fs.default.existsSync(file)) {
684
+ return options?.absolute ?? false ? file : import_pathe3.default.relative(dir, file);
685
+ }
686
+ }
687
+ if (!options?.walkParents) {
688
+ return void 0;
689
+ }
690
+ let parentDir = import_pathe3.default.dirname(currentDir);
691
+ if (currentDir === root || parentDir === currentDir) {
692
+ return void 0;
634
693
  }
694
+ currentDir = parentDir;
635
695
  }
636
- return void 0;
637
696
  }
638
697
 
639
698
  // vite/cloudflare-dev-proxy.ts
@@ -652,14 +711,15 @@ var cloudflareDevProxyVitePlugin = (options = {}) => {
652
711
  let future;
653
712
  return {
654
713
  name: PLUGIN_NAME,
655
- config: async (config) => {
714
+ config: async (config, configEnv) => {
656
715
  await preloadVite();
657
716
  const vite2 = getVite();
658
717
  const serverConditions = [
659
718
  ...vite2.defaultServerConditions ?? []
660
719
  ];
661
720
  let configResult = await loadConfig({
662
- rootDirectory: config.root ?? process.cwd()
721
+ rootDirectory: config.root ?? process.cwd(),
722
+ mode: configEnv.mode
663
723
  });
664
724
  if (!configResult.ok) {
665
725
  throw new Error(configResult.error);
package/dist/vite.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v0.0.0-experimental-701a32801
2
+ * @react-router/dev v0.0.0-experimental-b2bc694a6
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -154,6 +154,15 @@ async function createContext({
154
154
  optimizeDeps: {
155
155
  noDiscovery: true
156
156
  },
157
+ css: {
158
+ // This empty PostCSS config object prevents the PostCSS config file from
159
+ // being loaded. We don't need it in a React Router config context, and
160
+ // there's also an issue in Vite 5 when using a .ts PostCSS config file in
161
+ // an ESM project: https://github.com/vitejs/vite/issues/15869. Consumers
162
+ // can work around this in their own Vite config file, but they can't
163
+ // configure this internal usage of vite-node.
164
+ postcss: {}
165
+ },
157
166
  configFile: false,
158
167
  envFile: false,
159
168
  plugins: []
@@ -396,12 +405,17 @@ async function resolveConfig({
396
405
  serverModuleFormat: "esm",
397
406
  ssr: true
398
407
  };
408
+ let userAndPresetConfigs = mergeReactRouterConfig(
409
+ ...presets,
410
+ reactRouterUserConfig
411
+ );
399
412
  let {
400
413
  appDirectory: userAppDirectory,
401
414
  basename: basename2,
402
415
  buildDirectory: userBuildDirectory,
403
416
  buildEnd,
404
417
  prerender,
418
+ routeDiscovery: userRouteDiscovery,
405
419
  serverBuildFile,
406
420
  serverBundles,
407
421
  serverModuleFormat,
@@ -409,7 +423,7 @@ async function resolveConfig({
409
423
  } = {
410
424
  ...defaults,
411
425
  // Default values should be completely overridden by user/preset config, not merged
412
- ...mergeReactRouterConfig(...presets, reactRouterUserConfig)
426
+ ...userAndPresetConfigs
413
427
  };
414
428
  if (!ssr && serverBundles) {
415
429
  serverBundles = void 0;
@@ -420,6 +434,32 @@ async function resolveConfig({
420
434
  "The `prerender` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths"
421
435
  );
422
436
  }
437
+ let routeDiscovery;
438
+ if (userRouteDiscovery == null) {
439
+ if (ssr) {
440
+ routeDiscovery = {
441
+ mode: "lazy",
442
+ manifestPath: "/__manifest"
443
+ };
444
+ } else {
445
+ routeDiscovery = { mode: "initial" };
446
+ }
447
+ } else if (userRouteDiscovery.mode === "initial") {
448
+ routeDiscovery = userRouteDiscovery;
449
+ } else if (userRouteDiscovery.mode === "lazy") {
450
+ if (!ssr) {
451
+ return err(
452
+ 'The `routeDiscovery.mode` config cannot be set to "lazy" when setting `ssr:false`'
453
+ );
454
+ }
455
+ let { manifestPath } = userRouteDiscovery;
456
+ if (manifestPath != null && !manifestPath.startsWith("/")) {
457
+ return err(
458
+ 'The `routeDiscovery.manifestPath` config must be a root-relative pathname beginning with a slash (i.e., "/__manifest")'
459
+ );
460
+ }
461
+ routeDiscovery = userRouteDiscovery;
462
+ }
423
463
  let appDirectory = import_pathe3.default.resolve(root, userAppDirectory || "app");
424
464
  let buildDirectory = import_pathe3.default.resolve(root, userBuildDirectory);
425
465
  let rootRouteFile = findEntry(appDirectory, "root");
@@ -487,6 +527,7 @@ async function resolveConfig({
487
527
  future,
488
528
  prerender,
489
529
  routes,
530
+ routeDiscovery,
490
531
  serverBuildFile,
491
532
  serverBundles,
492
533
  serverModuleFormat,
@@ -499,12 +540,13 @@ async function resolveConfig({
499
540
  }
500
541
  async function createConfigLoader({
501
542
  rootDirectory: root,
502
- watch: watch2
543
+ watch: watch2,
544
+ mode
503
545
  }) {
504
546
  root = root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
505
547
  let viteNodeContext = await createContext({
506
548
  root,
507
- mode: watch2 ? "development" : "production"
549
+ mode
508
550
  });
509
551
  let reactRouterConfigFile = findEntry(root, "react-router.config", {
510
552
  absolute: true
@@ -595,7 +637,18 @@ async function resolveEntryFiles({
595
637
  let userEntryServerFile = findEntry(appDirectory, "entry.server");
596
638
  let entryServerFile;
597
639
  let entryClientFile = userEntryClientFile || "entry.client.tsx";
598
- let pkgJson = await import_package_json.default.load(rootDirectory);
640
+ let packageJsonPath = findEntry(rootDirectory, "package", {
641
+ extensions: [".json"],
642
+ absolute: true,
643
+ walkParents: true
644
+ });
645
+ if (!packageJsonPath) {
646
+ throw new Error(
647
+ `Could not find package.json in ${rootDirectory} or any of its parent directories`
648
+ );
649
+ }
650
+ let packageJsonDirectory = import_pathe3.default.dirname(packageJsonPath);
651
+ let pkgJson = await import_package_json.default.load(packageJsonDirectory);
599
652
  let deps = pkgJson.content.dependencies ?? {};
600
653
  if (userEntryServerFile) {
601
654
  entryServerFile = userEntryServerFile;
@@ -618,7 +671,7 @@ async function resolveEntryFiles({
618
671
  await pkgJson.save();
619
672
  let packageManager = detectPackageManager() ?? "npm";
620
673
  (0, import_node_child_process.execSync)(`${packageManager} install`, {
621
- cwd: rootDirectory,
674
+ cwd: packageJsonDirectory,
622
675
  stdio: "inherit"
623
676
  });
624
677
  }
@@ -630,13 +683,24 @@ async function resolveEntryFiles({
630
683
  }
631
684
  var entryExts = [".js", ".jsx", ".ts", ".tsx"];
632
685
  function findEntry(dir, basename2, options) {
633
- for (let ext of entryExts) {
634
- let file = import_pathe3.default.resolve(dir, basename2 + ext);
635
- if (import_node_fs.default.existsSync(file)) {
636
- return options?.absolute ?? false ? file : import_pathe3.default.relative(dir, file);
686
+ let currentDir = import_pathe3.default.resolve(dir);
687
+ let { root } = import_pathe3.default.parse(currentDir);
688
+ while (true) {
689
+ for (let ext of options?.extensions ?? entryExts) {
690
+ let file = import_pathe3.default.resolve(currentDir, basename2 + ext);
691
+ if (import_node_fs.default.existsSync(file)) {
692
+ return options?.absolute ?? false ? file : import_pathe3.default.relative(dir, file);
693
+ }
637
694
  }
695
+ if (!options?.walkParents) {
696
+ return void 0;
697
+ }
698
+ let parentDir = import_pathe3.default.dirname(currentDir);
699
+ if (currentDir === root || parentDir === currentDir) {
700
+ return void 0;
701
+ }
702
+ currentDir = parentDir;
638
703
  }
639
- return void 0;
640
704
  }
641
705
 
642
706
  // vite/babel.ts
@@ -778,8 +842,8 @@ function formatParamProperties(fullpath2) {
778
842
  }
779
843
 
780
844
  // typegen/index.ts
781
- async function watch(rootDirectory, { logger } = {}) {
782
- const ctx = await createContext2({ rootDirectory, watch: true });
845
+ async function watch(rootDirectory, { mode, logger }) {
846
+ const ctx = await createContext2({ rootDirectory, mode, watch: true });
783
847
  await writeAll(ctx);
784
848
  logger?.info(import_picocolors2.default.green("generated types"), { timestamp: true, clear: true });
785
849
  ctx.configLoader.onChange(async ({ result, routeConfigChanged }) => {
@@ -802,9 +866,10 @@ async function watch(rootDirectory, { logger } = {}) {
802
866
  }
803
867
  async function createContext2({
804
868
  rootDirectory,
805
- watch: watch2
869
+ watch: watch2,
870
+ mode
806
871
  }) {
807
- const configLoader = await createConfigLoader({ rootDirectory, watch: watch2 });
872
+ const configLoader = await createConfigLoader({ rootDirectory, mode, watch: watch2 });
808
873
  const configResult = await configLoader.getConfig();
809
874
  if (!configResult.ok) {
810
875
  throw new Error(configResult.error);
@@ -885,6 +950,7 @@ var virtual = import_dedent2.default`
885
950
  export const isSpaMode: ServerBuild["isSpaMode"];
886
951
  export const prerender: ServerBuild["prerender"];
887
952
  export const publicPath: ServerBuild["publicPath"];
953
+ export const routeDiscovery: ServerBuild["routeDiscovery"];
888
954
  export const routes: ServerBuild["routes"];
889
955
  export const ssr: ServerBuild["ssr"];
890
956
  export const unstable_getCriticalCss: ServerBuild["unstable_getCriticalCss"];
@@ -945,7 +1011,9 @@ function fromNodeRequest(nodeReq, nodeRes) {
945
1011
  }
946
1012
  async function toNodeRequest(res, nodeRes) {
947
1013
  nodeRes.statusCode = res.status;
948
- nodeRes.statusMessage = res.statusText;
1014
+ if (!nodeRes.req || nodeRes.req.httpVersionMajor < 2) {
1015
+ nodeRes.statusMessage = res.statusText;
1016
+ }
949
1017
  let cookiesStrings = [];
950
1018
  for (let [name, value] of res.headers) {
951
1019
  if (name === "set-cookie") {
@@ -2354,6 +2422,9 @@ var reactRouterVitePlugin = () => {
2354
2422
  export const ssr = ${ctx.reactRouterConfig.ssr};
2355
2423
  export const isSpaMode = ${isSpaMode};
2356
2424
  export const prerender = ${JSON.stringify(prerenderPaths)};
2425
+ export const routeDiscovery = ${JSON.stringify(
2426
+ ctx.reactRouterConfig.routeDiscovery
2427
+ )};
2357
2428
  export const publicPath = ${JSON.stringify(ctx.publicPath)};
2358
2429
  export const entry = { module: entryServer };
2359
2430
  export const routes = {
@@ -2687,14 +2758,17 @@ var reactRouterVitePlugin = () => {
2687
2758
  prefix: "[react-router]"
2688
2759
  });
2689
2760
  rootDirectory = viteUserConfig.root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
2761
+ let mode = viteConfigEnv.mode;
2690
2762
  if (viteCommand === "serve") {
2691
2763
  typegenWatcherPromise = watch(rootDirectory, {
2764
+ mode,
2692
2765
  // ignore `info` logs from typegen since they are redundant when Vite plugin logs are active
2693
2766
  logger: vite2.createLogger("warn", { prefix: "[react-router]" })
2694
2767
  });
2695
2768
  }
2696
2769
  reactRouterConfigLoader = await createConfigLoader({
2697
2770
  rootDirectory,
2771
+ mode,
2698
2772
  watch: viteCommand === "serve"
2699
2773
  });
2700
2774
  await updatePluginContext();
@@ -4371,8 +4445,9 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4371
4445
  ""
4372
4446
  ) : null;
4373
4447
  let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
4448
+ let assetsDir = (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
4374
4449
  return path6.posix.join(
4375
- (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : viteUserConfig?.build?.assetsDir) ?? "assets",
4450
+ assetsDir,
4376
4451
  `[name]${routeChunkSuffix}-[hash].js`
4377
4452
  );
4378
4453
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-router/dev",
3
- "version": "0.0.0-experimental-701a32801",
3
+ "version": "0.0.0-experimental-b2bc694a6",
4
4
  "description": "Dev tools and CLI for React Router",
5
5
  "homepage": "https://reactrouter.com",
6
6
  "bugs": {
@@ -86,7 +86,7 @@
86
86
  "set-cookie-parser": "^2.6.0",
87
87
  "valibot": "^0.41.0",
88
88
  "vite-node": "3.0.0-beta.2",
89
- "@react-router/node": "0.0.0-experimental-701a32801"
89
+ "@react-router/node": "0.0.0-experimental-b2bc694a6"
90
90
  },
91
91
  "devDependencies": {
92
92
  "@types/babel__core": "^7.20.5",
@@ -110,15 +110,15 @@
110
110
  "vite": "^6.1.0",
111
111
  "wireit": "0.14.9",
112
112
  "wrangler": "^4.2.0",
113
- "@react-router/serve": "0.0.0-experimental-701a32801",
114
- "react-router": "^0.0.0-experimental-701a32801"
113
+ "react-router": "^0.0.0-experimental-b2bc694a6",
114
+ "@react-router/serve": "0.0.0-experimental-b2bc694a6"
115
115
  },
116
116
  "peerDependencies": {
117
117
  "typescript": "^5.1.0",
118
118
  "vite": "^5.1.0 || ^6.0.0",
119
119
  "wrangler": "^3.28.2 || ^4.0.0",
120
- "@react-router/serve": "^0.0.0-experimental-701a32801",
121
- "react-router": "^0.0.0-experimental-701a32801"
120
+ "@react-router/serve": "^0.0.0-experimental-b2bc694a6",
121
+ "react-router": "^0.0.0-experimental-b2bc694a6"
122
122
  },
123
123
  "peerDependenciesMeta": {
124
124
  "@react-router/serve": {