@react-router/dev 0.0.0-experimental-ab0e85b04 → 0.0.0-experimental-818f8e08d

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/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-ab0e85b04
3
+ * @react-router/dev v0.0.0-experimental-818f8e08d
4
4
  *
5
5
  * Copyright (c) Remix Software Inc.
6
6
  *
@@ -125,15 +125,13 @@ var init_ssr_externals = __esm({
125
125
  // vite/vite-node.ts
126
126
  async function createContext({
127
127
  root,
128
- mode,
129
- customLogger
128
+ mode
130
129
  }) {
131
130
  await preloadVite();
132
131
  const vite2 = getVite();
133
132
  const devServer = await vite2.createServer({
134
133
  root,
135
134
  mode,
136
- customLogger,
137
135
  server: {
138
136
  preTransformRequests: false,
139
137
  hmr: false,
@@ -216,7 +214,7 @@ function validateRouteConfig({
216
214
  `Route config in "${routeConfigFile}" is invalid.`,
217
215
  root ? `${root}` : [],
218
216
  nested ? Object.entries(nested).map(
219
- ([path8, message]) => `Path: routes.${path8}
217
+ ([path9, message]) => `Path: routes.${path9}
220
218
  ${message}`
221
219
  ) : []
222
220
  ].flat().join("\n\n")
@@ -301,8 +299,7 @@ function err(error) {
301
299
  async function resolveConfig({
302
300
  root,
303
301
  viteNodeContext,
304
- reactRouterConfigFile,
305
- skipRoutes
302
+ reactRouterConfigFile
306
303
  }) {
307
304
  let reactRouterUserConfig = {};
308
305
  if (reactRouterConfigFile) {
@@ -418,50 +415,45 @@ async function resolveConfig({
418
415
  `Could not find a root route module in the app directory as "${rootRouteDisplayPath}"`
419
416
  );
420
417
  }
421
- let routes2 = {};
422
- if (!skipRoutes) {
423
- routes2 = {
424
- root: { path: "", id: "root", file: rootRouteFile }
425
- };
426
- let routeConfigFile = findEntry(appDirectory, "routes");
427
- try {
428
- if (!routeConfigFile) {
429
- let routeConfigDisplayPath = import_pathe3.default.relative(
430
- root,
431
- import_pathe3.default.join(appDirectory, "routes.ts")
432
- );
433
- return err(
434
- `Route config file not found at "${routeConfigDisplayPath}".`
435
- );
436
- }
437
- setAppDirectory(appDirectory);
438
- let routeConfigExport = (await viteNodeContext.runner.executeFile(
439
- import_pathe3.default.join(appDirectory, routeConfigFile)
440
- )).default;
441
- let routeConfig = await routeConfigExport;
442
- let result = validateRouteConfig({
443
- routeConfigFile,
444
- routeConfig
445
- });
446
- if (!result.valid) {
447
- return err(result.message);
448
- }
449
- routes2 = {
450
- ...routes2,
451
- ...configRoutesToRouteManifest(appDirectory, routeConfig)
452
- };
453
- } catch (error) {
454
- return err(
455
- [
456
- import_picocolors.default.red(`Route config in "${routeConfigFile}" is invalid.`),
457
- "",
458
- error.loc?.file && error.loc?.column && error.frame ? [
459
- import_pathe3.default.relative(appDirectory, error.loc.file) + ":" + error.loc.line + ":" + error.loc.column,
460
- error.frame.trim?.()
461
- ] : error.stack
462
- ].flat().join("\n")
418
+ let routes2 = {
419
+ root: { path: "", id: "root", file: rootRouteFile }
420
+ };
421
+ let routeConfigFile = findEntry(appDirectory, "routes");
422
+ try {
423
+ if (!routeConfigFile) {
424
+ let routeConfigDisplayPath = import_pathe3.default.relative(
425
+ root,
426
+ import_pathe3.default.join(appDirectory, "routes.ts")
463
427
  );
428
+ return err(`Route config file not found at "${routeConfigDisplayPath}".`);
464
429
  }
430
+ setAppDirectory(appDirectory);
431
+ let routeConfigExport = (await viteNodeContext.runner.executeFile(
432
+ import_pathe3.default.join(appDirectory, routeConfigFile)
433
+ )).default;
434
+ let routeConfig = await routeConfigExport;
435
+ let result = validateRouteConfig({
436
+ routeConfigFile,
437
+ routeConfig
438
+ });
439
+ if (!result.valid) {
440
+ return err(result.message);
441
+ }
442
+ routes2 = {
443
+ ...routes2,
444
+ ...configRoutesToRouteManifest(appDirectory, routeConfig)
445
+ };
446
+ } catch (error) {
447
+ return err(
448
+ [
449
+ import_picocolors.default.red(`Route config in "${routeConfigFile}" is invalid.`),
450
+ "",
451
+ error.loc?.file && error.loc?.column && error.frame ? [
452
+ import_pathe3.default.relative(appDirectory, error.loc.file) + ":" + error.loc.line + ":" + error.loc.column,
453
+ error.frame.trim?.()
454
+ ] : error.stack
455
+ ].flat().join("\n")
456
+ );
465
457
  }
466
458
  let future = {
467
459
  unstable_middleware: reactRouterUserConfig.future?.unstable_middleware ?? false,
@@ -492,34 +484,24 @@ async function resolveConfig({
492
484
  async function createConfigLoader({
493
485
  rootDirectory: root,
494
486
  watch: watch2,
495
- mode,
496
- skipRoutes
487
+ mode
497
488
  }) {
498
- root = import_pathe3.default.normalize(root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd());
499
- let vite2 = await import("vite");
489
+ root = root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
500
490
  let viteNodeContext = await createContext({
501
491
  root,
502
- mode,
503
- // Filter out any info level logs from vite-node
504
- customLogger: vite2.createLogger("warn", {
505
- prefix: "[react-router]"
506
- })
492
+ mode
507
493
  });
508
- let reactRouterConfigFile;
509
- let updateReactRouterConfigFile = () => {
510
- reactRouterConfigFile = findEntry(root, "react-router.config", {
511
- absolute: true
512
- });
513
- };
514
- updateReactRouterConfigFile();
515
- let getConfig = () => resolveConfig({ root, viteNodeContext, reactRouterConfigFile, skipRoutes });
494
+ let reactRouterConfigFile = findEntry(root, "react-router.config", {
495
+ absolute: true
496
+ });
497
+ let getConfig = () => resolveConfig({ root, viteNodeContext, reactRouterConfigFile });
516
498
  let appDirectory;
517
499
  let initialConfigResult = await getConfig();
518
500
  if (!initialConfigResult.ok) {
519
501
  throw new Error(initialConfigResult.error);
520
502
  }
521
- appDirectory = import_pathe3.default.normalize(initialConfigResult.value.appDirectory);
522
- let currentConfig = initialConfigResult.value;
503
+ appDirectory = initialConfigResult.value.appDirectory;
504
+ let lastConfig = initialConfigResult.value;
523
505
  let fsWatcher;
524
506
  let changeHandlers = [];
525
507
  return {
@@ -532,71 +514,41 @@ async function createConfigLoader({
532
514
  }
533
515
  changeHandlers.push(handler);
534
516
  if (!fsWatcher) {
535
- fsWatcher = import_chokidar.default.watch([root, appDirectory], {
536
- ignoreInitial: true,
537
- ignored: (path8) => {
538
- let dirname6 = import_pathe3.default.dirname(path8);
539
- return !dirname6.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
540
- // that are at the root level, not nested in subdirectories
541
- path8 !== root && // Watch the root directory itself
542
- dirname6 !== root;
543
- }
544
- });
517
+ fsWatcher = import_chokidar.default.watch(
518
+ [
519
+ ...reactRouterConfigFile ? [reactRouterConfigFile] : [],
520
+ appDirectory
521
+ ],
522
+ { ignoreInitial: true }
523
+ );
545
524
  fsWatcher.on("all", async (...args) => {
546
525
  let [event, rawFilepath] = args;
547
526
  let filepath = import_pathe3.default.normalize(rawFilepath);
548
- let fileAddedOrRemoved = event === "add" || event === "unlink";
549
- let appFileAddedOrRemoved = fileAddedOrRemoved && filepath.startsWith(import_pathe3.default.normalize(appDirectory));
550
- let rootRelativeFilepath = import_pathe3.default.relative(root, filepath);
551
- let configFileAddedOrRemoved = fileAddedOrRemoved && isEntryFile("react-router.config", rootRelativeFilepath);
552
- if (configFileAddedOrRemoved) {
553
- updateReactRouterConfigFile();
554
- }
555
- let moduleGraphChanged = configFileAddedOrRemoved || Boolean(
527
+ let appFileAddedOrRemoved = appDirectory && (event === "add" || event === "unlink") && filepath.startsWith(import_pathe3.default.normalize(appDirectory));
528
+ let configCodeUpdated = Boolean(
556
529
  viteNodeContext.devServer?.moduleGraph.getModuleById(filepath)
557
530
  );
558
- if (!moduleGraphChanged && !appFileAddedOrRemoved) {
559
- return;
531
+ if (configCodeUpdated || appFileAddedOrRemoved) {
532
+ viteNodeContext.devServer?.moduleGraph.invalidateAll();
533
+ viteNodeContext.runner?.moduleCache.clear();
560
534
  }
561
- viteNodeContext.devServer?.moduleGraph.invalidateAll();
562
- viteNodeContext.runner?.moduleCache.clear();
563
- let result = await getConfig();
564
- let prevAppDirectory = appDirectory;
565
- appDirectory = import_pathe3.default.normalize(
566
- (result.value ?? currentConfig).appDirectory
567
- );
568
- if (appDirectory !== prevAppDirectory) {
569
- fsWatcher.unwatch(prevAppDirectory);
570
- fsWatcher.add(appDirectory);
571
- }
572
- let configCodeChanged = configFileAddedOrRemoved || reactRouterConfigFile !== void 0 && isEntryFileDependency(
573
- viteNodeContext.devServer.moduleGraph,
574
- reactRouterConfigFile,
575
- filepath
576
- );
577
- let routeConfigFile = !skipRoutes ? findEntry(appDirectory, "routes", {
578
- absolute: true
579
- }) : void 0;
580
- let routeConfigCodeChanged = routeConfigFile !== void 0 && isEntryFileDependency(
581
- viteNodeContext.devServer.moduleGraph,
582
- routeConfigFile,
583
- filepath
584
- );
585
- let configChanged = result.ok && !(0, import_isEqual.default)(omitRoutes(currentConfig), omitRoutes(result.value));
586
- let routeConfigChanged = result.ok && !(0, import_isEqual.default)(currentConfig?.routes, result.value.routes);
587
- for (let handler2 of changeHandlers) {
588
- handler2({
589
- result,
590
- configCodeChanged,
591
- routeConfigCodeChanged,
592
- configChanged,
593
- routeConfigChanged,
594
- path: filepath,
595
- event
596
- });
597
- }
598
- if (result.ok) {
599
- currentConfig = result.value;
535
+ if (appFileAddedOrRemoved || configCodeUpdated) {
536
+ let result = await getConfig();
537
+ let configChanged = result.ok && !(0, import_isEqual.default)(lastConfig, result.value);
538
+ let routeConfigChanged = result.ok && !(0, import_isEqual.default)(lastConfig?.routes, result.value.routes);
539
+ for (let handler2 of changeHandlers) {
540
+ handler2({
541
+ result,
542
+ configCodeUpdated,
543
+ configChanged,
544
+ routeConfigChanged,
545
+ path: filepath,
546
+ event
547
+ });
548
+ }
549
+ if (result.ok) {
550
+ lastConfig = result.value;
551
+ }
600
552
  }
601
553
  });
602
554
  }
@@ -615,28 +567,17 @@ async function createConfigLoader({
615
567
  }
616
568
  async function loadConfig({
617
569
  rootDirectory,
618
- mode,
619
- skipRoutes
570
+ mode
620
571
  }) {
621
572
  let configLoader = await createConfigLoader({
622
573
  rootDirectory,
623
574
  mode,
624
- skipRoutes,
625
575
  watch: false
626
576
  });
627
577
  let config = await configLoader.getConfig();
628
578
  await configLoader.close();
629
579
  return config;
630
580
  }
631
- function omitRoutes(config) {
632
- return {
633
- ...config,
634
- routes: {}
635
- };
636
- }
637
- function isEntryFile(entryBasename, filename3) {
638
- return entryExts.some((ext) => filename3 === `${entryBasename}${ext}`);
639
- }
640
581
  function findEntry(dir, basename2, options) {
641
582
  let currentDir = import_pathe3.default.resolve(dir);
642
583
  let { root } = import_pathe3.default.parse(currentDir);
@@ -657,30 +598,6 @@ function findEntry(dir, basename2, options) {
657
598
  currentDir = parentDir;
658
599
  }
659
600
  }
660
- function isEntryFileDependency(moduleGraph, entryFilepath, filepath, visited = /* @__PURE__ */ new Set()) {
661
- entryFilepath = import_pathe3.default.normalize(entryFilepath);
662
- filepath = import_pathe3.default.normalize(filepath);
663
- if (visited.has(filepath)) {
664
- return false;
665
- }
666
- visited.add(filepath);
667
- if (filepath === entryFilepath) {
668
- return true;
669
- }
670
- let mod = moduleGraph.getModuleById(filepath);
671
- if (!mod) {
672
- return false;
673
- }
674
- for (let importer of mod.importers) {
675
- if (!importer.id) {
676
- continue;
677
- }
678
- if (importer.id === entryFilepath || isEntryFileDependency(moduleGraph, entryFilepath, importer.id, visited)) {
679
- return true;
680
- }
681
- }
682
- return false;
683
- }
684
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;
685
602
  var init_config = __esm({
686
603
  "config/config.ts"() {
@@ -801,21 +718,21 @@ var init_babel = __esm({
801
718
 
802
719
  // typegen/paths.ts
803
720
  function getTypesDir(ctx) {
804
- return Path3.join(ctx.rootDirectory, ".react-router/types");
721
+ return Path2.join(ctx.rootDirectory, ".react-router/types");
805
722
  }
806
723
  function getTypesPath(ctx, route) {
807
- return Path3.join(
724
+ return Path2.join(
808
725
  getTypesDir(ctx),
809
- Path3.relative(ctx.rootDirectory, ctx.config.appDirectory),
810
- Path3.dirname(route.file),
726
+ Path2.relative(ctx.rootDirectory, ctx.config.appDirectory),
727
+ Path2.dirname(route.file),
811
728
  "+types/" + Pathe.filename(route.file) + ".ts"
812
729
  );
813
730
  }
814
- var Path3, Pathe;
731
+ var Path2, Pathe;
815
732
  var init_paths = __esm({
816
733
  "typegen/paths.ts"() {
817
734
  "use strict";
818
- Path3 = __toESM(require("pathe"));
735
+ Path2 = __toESM(require("pathe"));
819
736
  Pathe = __toESM(require("pathe/utils"));
820
737
  }
821
738
  });
@@ -855,7 +772,7 @@ function lineage(routes2, route) {
855
772
  }
856
773
  function fullpath(lineage2) {
857
774
  if (lineage2.length === 1 && lineage2[0].id === "root") return "/";
858
- return "/" + lineage2.map((route) => route.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path8) => path8 !== void 0 && path8 !== "").join("/");
775
+ return "/" + lineage2.map((route) => route.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path9) => path9 !== void 0 && path9 !== "").join("/");
859
776
  }
860
777
  var init_route = __esm({
861
778
  "typegen/route.ts"() {
@@ -870,8 +787,8 @@ function generate2(ctx, route) {
870
787
  const typesPath = getTypesPath(ctx, route);
871
788
  const parents = lineage2.slice(0, -1);
872
789
  const parentTypeImports = parents.map((parent, i) => {
873
- const rel = Path4.relative(
874
- Path4.dirname(typesPath),
790
+ const rel = Path3.relative(
791
+ Path3.dirname(typesPath),
875
792
  getTypesPath(ctx, parent)
876
793
  );
877
794
  const indent = i === 0 ? "" : " ".repeat(2);
@@ -933,17 +850,17 @@ function formatParamProperties(fullpath2) {
933
850
  );
934
851
  return properties.join("; ");
935
852
  }
936
- var import_dedent, Path4, Pathe2, noExtension;
853
+ var import_dedent, Path3, Pathe2, noExtension;
937
854
  var init_generate = __esm({
938
855
  "typegen/generate.ts"() {
939
856
  "use strict";
940
857
  import_dedent = __toESM(require("dedent"));
941
- Path4 = __toESM(require("pathe"));
858
+ Path3 = __toESM(require("pathe"));
942
859
  Pathe2 = __toESM(require("pathe/utils"));
943
860
  init_paths();
944
861
  init_params();
945
862
  init_route();
946
- noExtension = (path8) => Path4.join(Path4.dirname(path8), Pathe2.filename(path8));
863
+ noExtension = (path9) => Path3.join(Path3.dirname(path9), Pathe2.filename(path9));
947
864
  }
948
865
  });
949
866
 
@@ -956,22 +873,20 @@ async function watch(rootDirectory, { mode, logger }) {
956
873
  const ctx = await createContext2({ rootDirectory, mode, watch: true });
957
874
  await writeAll(ctx);
958
875
  logger?.info(import_picocolors3.default.green("generated types"), { timestamp: true, clear: true });
959
- ctx.configLoader.onChange(
960
- async ({ result, configChanged, routeConfigChanged }) => {
961
- if (!result.ok) {
962
- logger?.error(import_picocolors3.default.red(result.error), { timestamp: true, clear: true });
963
- return;
964
- }
965
- ctx.config = result.value;
966
- if (configChanged || routeConfigChanged) {
967
- await writeAll(ctx);
968
- logger?.info(import_picocolors3.default.green("regenerated types"), {
969
- timestamp: true,
970
- clear: true
971
- });
972
- }
876
+ ctx.configLoader.onChange(async ({ result, routeConfigChanged }) => {
877
+ if (!result.ok) {
878
+ logger?.error(import_picocolors3.default.red(result.error), { timestamp: true, clear: true });
879
+ return;
973
880
  }
974
- );
881
+ ctx.config = result.value;
882
+ if (routeConfigChanged) {
883
+ await writeAll(ctx);
884
+ logger?.info(import_picocolors3.default.green("regenerated types"), {
885
+ timestamp: true,
886
+ clear: true
887
+ });
888
+ }
889
+ });
975
890
  return {
976
891
  close: async () => await ctx.configLoader.close()
977
892
  };
@@ -999,12 +914,12 @@ async function writeAll(ctx) {
999
914
  Object.values(ctx.config.routes).forEach((route) => {
1000
915
  const typesPath = getTypesPath(ctx, route);
1001
916
  const content = generate2(ctx, route);
1002
- import_node_fs3.default.mkdirSync(Path5.dirname(typesPath), { recursive: true });
917
+ import_node_fs3.default.mkdirSync(Path4.dirname(typesPath), { recursive: true });
1003
918
  import_node_fs3.default.writeFileSync(typesPath, content);
1004
919
  });
1005
- const registerPath = Path5.join(typegenDir, "+register.ts");
920
+ const registerPath = Path4.join(typegenDir, "+register.ts");
1006
921
  import_node_fs3.default.writeFileSync(registerPath, register(ctx));
1007
- const virtualPath = Path5.join(typegenDir, "+virtual.d.ts");
922
+ const virtualPath = Path4.join(typegenDir, "+virtual.d.ts");
1008
923
  import_node_fs3.default.writeFileSync(virtualPath, virtual);
1009
924
  }
1010
925
  function register(ctx) {
@@ -1015,25 +930,21 @@ function register(ctx) {
1015
930
  interface Register {
1016
931
  params: Params;
1017
932
  }
1018
-
1019
- interface Future {
1020
- unstable_middleware: ${ctx.config.future.unstable_middleware}
1021
- }
1022
933
  }
1023
934
  `;
1024
935
  const { t: t2 } = babel_exports;
1025
- const fullpaths = /* @__PURE__ */ new Set();
1026
- Object.values(ctx.config.routes).forEach((route) => {
1027
- if (route.id !== "root" && !route.path) return;
1028
- const lineage2 = lineage(ctx.config.routes, route);
1029
- const fullpath2 = fullpath(lineage2);
1030
- fullpaths.add(fullpath2);
1031
- });
936
+ const indexPaths = new Set(
937
+ Object.values(ctx.config.routes).filter((route) => route.index).map((route) => route.path)
938
+ );
1032
939
  const typeParams = t2.tsTypeAliasDeclaration(
1033
940
  t2.identifier("Params"),
1034
941
  null,
1035
942
  t2.tsTypeLiteral(
1036
- Array.from(fullpaths).map((fullpath2) => {
943
+ Object.values(ctx.config.routes).map((route) => {
944
+ if (route.id !== "root" && !route.path) return void 0;
945
+ if (!route.index && indexPaths.has(route.path)) return void 0;
946
+ const lineage2 = lineage(ctx.config.routes, route);
947
+ const fullpath2 = fullpath(lineage2);
1037
948
  const params = parse2(fullpath2);
1038
949
  return t2.tsPropertySignature(
1039
950
  t2.stringLiteral(fullpath2),
@@ -1050,18 +961,18 @@ function register(ctx) {
1050
961
  )
1051
962
  )
1052
963
  );
1053
- })
964
+ }).filter((x) => x !== void 0)
1054
965
  )
1055
966
  );
1056
967
  return [register2, generate(typeParams).code].join("\n\n");
1057
968
  }
1058
- var import_node_fs3, import_dedent2, Path5, import_picocolors3, virtual;
969
+ var import_node_fs3, import_dedent2, Path4, import_picocolors3, virtual;
1059
970
  var init_typegen = __esm({
1060
971
  "typegen/index.ts"() {
1061
972
  "use strict";
1062
973
  import_node_fs3 = __toESM(require("fs"));
1063
974
  import_dedent2 = __toESM(require("dedent"));
1064
- Path5 = __toESM(require("pathe"));
975
+ Path4 = __toESM(require("pathe"));
1065
976
  import_picocolors3 = __toESM(require("picocolors"));
1066
977
  init_config();
1067
978
  init_babel();
@@ -1103,24 +1014,23 @@ var init_node_adapter = __esm({
1103
1014
  });
1104
1015
 
1105
1016
  // vite/resolve-file-url.ts
1106
- var path4;
1017
+ var path5;
1107
1018
  var init_resolve_file_url = __esm({
1108
1019
  "vite/resolve-file-url.ts"() {
1109
1020
  "use strict";
1110
- path4 = __toESM(require("path"));
1021
+ path5 = __toESM(require("path"));
1111
1022
  init_vite();
1112
1023
  }
1113
1024
  });
1114
1025
 
1115
1026
  // vite/styles.ts
1116
- var path5, import_react_router, cssFileRegExp, cssModulesRegExp;
1027
+ var path6, import_react_router, cssFileRegExp, cssModulesRegExp;
1117
1028
  var init_styles = __esm({
1118
1029
  "vite/styles.ts"() {
1119
1030
  "use strict";
1120
- path5 = __toESM(require("path"));
1031
+ path6 = __toESM(require("path"));
1121
1032
  import_react_router = require("react-router");
1122
1033
  init_resolve_file_url();
1123
- init_babel();
1124
1034
  cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
1125
1035
  cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
1126
1036
  }
@@ -1267,8 +1177,8 @@ function getServerBundleIds(ctx) {
1267
1177
  async function cleanBuildDirectory(viteConfig, ctx) {
1268
1178
  let buildDirectory = ctx.reactRouterConfig.buildDirectory;
1269
1179
  let isWithinRoot = () => {
1270
- let relativePath = path6.relative(ctx.rootDirectory, buildDirectory);
1271
- return !relativePath.startsWith("..") && !path6.isAbsolute(relativePath);
1180
+ let relativePath = path7.relative(ctx.rootDirectory, buildDirectory);
1181
+ return !relativePath.startsWith("..") && !path7.isAbsolute(relativePath);
1272
1182
  };
1273
1183
  if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
1274
1184
  await fse.remove(buildDirectory);
@@ -1279,7 +1189,7 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1279
1189
  ([environmentName, options]) => {
1280
1190
  let outDir = options.build?.outDir;
1281
1191
  invariant(outDir, `Expected build.outDir for ${environmentName}`);
1282
- return path6.join(outDir, ".vite/manifest.json");
1192
+ return path7.join(outDir, ".vite/manifest.json");
1283
1193
  }
1284
1194
  );
1285
1195
  await Promise.all(
@@ -1289,7 +1199,7 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1289
1199
  if (!ctx.viteManifestEnabled) {
1290
1200
  await fse.remove(viteManifestPath);
1291
1201
  }
1292
- let viteDir = path6.dirname(viteManifestPath);
1202
+ let viteDir = path7.dirname(viteManifestPath);
1293
1203
  let viteDirFiles = await fse.readdir(viteDir);
1294
1204
  if (viteDirFiles.length === 0) {
1295
1205
  await fse.remove(viteDir);
@@ -1306,10 +1216,10 @@ function mergeEnvironmentOptions(base, ...overrides) {
1306
1216
  }
1307
1217
  async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1308
1218
  let { serverBuildFile, serverModuleFormat } = ctx.reactRouterConfig;
1309
- let packageRoot = path6.dirname(
1219
+ let packageRoot = path7.dirname(
1310
1220
  require.resolve("@react-router/dev/package.json")
1311
1221
  );
1312
- let { moduleSyncEnabled } = await import(`file:///${path6.join(packageRoot, "module-sync-enabled/index.mjs")}`);
1222
+ let { moduleSyncEnabled } = await import(`file:///${path7.join(packageRoot, "module-sync-enabled/index.mjs")}`);
1313
1223
  let vite2 = getVite();
1314
1224
  let viteServerConditions = [
1315
1225
  ...vite2.defaultServerConditions ?? [],
@@ -1383,7 +1293,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1383
1293
  ctx.entryClientFilePath,
1384
1294
  ...Object.values(ctx.reactRouterConfig.routes).flatMap(
1385
1295
  (route) => {
1386
- let routeFilePath = path6.resolve(
1296
+ let routeFilePath = path7.resolve(
1387
1297
  ctx.reactRouterConfig.appDirectory,
1388
1298
  route.file
1389
1299
  );
@@ -1407,7 +1317,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1407
1317
  ) : null;
1408
1318
  let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
1409
1319
  let assetsDir = (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
1410
- return path6.posix.join(
1320
+ return path7.posix.join(
1411
1321
  assetsDir,
1412
1322
  `[name]${routeChunkSuffix}-[hash].js`
1413
1323
  );
@@ -1443,6 +1353,9 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1443
1353
  }
1444
1354
  });
1445
1355
  }
1356
+ if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteCommand === "serve") {
1357
+ environmentOptionsResolvers[CSS_DEV_HELPER_ENVIRONMENT_NAME] = () => ({});
1358
+ }
1446
1359
  return environmentOptionsResolvers;
1447
1360
  }
1448
1361
  function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
@@ -1457,13 +1370,13 @@ function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
1457
1370
  function isNonNullable(x) {
1458
1371
  return x != null;
1459
1372
  }
1460
- 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, virtual2, getServerBuildDirectory, getClientBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER;
1373
+ var import_node_crypto, fs4, path7, 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, CSS_DEV_HELPER_ENVIRONMENT_NAME, virtualHmrRuntime, virtualInjectHmrRuntime, virtual2, getServerBuildDirectory, getClientBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER;
1461
1374
  var init_plugin = __esm({
1462
1375
  "vite/plugin.ts"() {
1463
1376
  "use strict";
1464
1377
  import_node_crypto = require("crypto");
1465
1378
  fs4 = __toESM(require("fs"));
1466
- path6 = __toESM(require("path"));
1379
+ path7 = __toESM(require("path"));
1467
1380
  url = __toESM(require("url"));
1468
1381
  fse = __toESM(require("fs-extra"));
1469
1382
  babel2 = __toESM(require("@babel/core"));
@@ -1505,6 +1418,7 @@ var init_plugin = __esm({
1505
1418
  ];
1506
1419
  BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-route";
1507
1420
  SSR_BUNDLE_PREFIX = "ssrBundle_";
1421
+ CSS_DEV_HELPER_ENVIRONMENT_NAME = "__react_router_css_dev_helper__";
1508
1422
  virtualHmrRuntime = create("hmr-runtime");
1509
1423
  virtualInjectHmrRuntime = create("inject-hmr-runtime");
1510
1424
  virtual2 = {
@@ -1512,19 +1426,19 @@ var init_plugin = __esm({
1512
1426
  serverManifest: create("server-manifest"),
1513
1427
  browserManifest: create("browser-manifest")
1514
1428
  };
1515
- getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path6.join(
1429
+ getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path7.join(
1516
1430
  reactRouterConfig.buildDirectory,
1517
1431
  "server",
1518
1432
  ...serverBundleId ? [serverBundleId] : []
1519
1433
  );
1520
- getClientBuildDirectory = (reactRouterConfig) => path6.join(reactRouterConfig.buildDirectory, "client");
1521
- defaultEntriesDir = path6.resolve(
1522
- path6.dirname(require.resolve("@react-router/dev/package.json")),
1434
+ getClientBuildDirectory = (reactRouterConfig) => path7.join(reactRouterConfig.buildDirectory, "client");
1435
+ defaultEntriesDir = path7.resolve(
1436
+ path7.dirname(require.resolve("@react-router/dev/package.json")),
1523
1437
  "dist",
1524
1438
  "config",
1525
1439
  "defaults"
1526
1440
  );
1527
- defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename3) => path6.join(defaultEntriesDir, filename3));
1441
+ defaultEntries = fse.readdirSync(defaultEntriesDir).map((filename3) => path7.join(defaultEntriesDir, filename3));
1528
1442
  invariant(defaultEntries.length > 0, "No default entries found");
1529
1443
  REACT_REFRESH_HEADER = `
1530
1444
  import RefreshRuntime from "${virtualHmrRuntime.id}";
@@ -1560,10 +1474,7 @@ async function build(root, viteBuildOptions) {
1560
1474
  let vite2 = getVite();
1561
1475
  let configResult = await loadConfig({
1562
1476
  rootDirectory: root,
1563
- mode: viteBuildOptions.mode ?? "production",
1564
- // In this scope we only need future flags, so we can skip evaluating
1565
- // routes.ts until we're within the Vite build context
1566
- skipRoutes: true
1477
+ mode: viteBuildOptions.mode ?? "production"
1567
1478
  });
1568
1479
  if (!configResult.ok) {
1569
1480
  throw new Error(configResult.error);
@@ -1804,7 +1715,7 @@ var import_semver = __toESM(require("semver"));
1804
1715
  var import_picocolors8 = __toESM(require("picocolors"));
1805
1716
 
1806
1717
  // cli/commands.ts
1807
- var path7 = __toESM(require("path"));
1718
+ var path8 = __toESM(require("path"));
1808
1719
  var import_fs_extra = __toESM(require("fs-extra"));
1809
1720
  var import_package_json2 = __toESM(require("@npmcli/package-json"));
1810
1721
  var import_exit_hook = __toESM(require("exit-hook"));
@@ -1963,14 +1874,14 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
1963
1874
  console.error(import_picocolors7.default.red(`No default server entry detected.`));
1964
1875
  return;
1965
1876
  }
1966
- let defaultsDirectory = path7.resolve(
1967
- path7.dirname(require.resolve("@react-router/dev/package.json")),
1877
+ let defaultsDirectory = path8.resolve(
1878
+ path8.dirname(require.resolve("@react-router/dev/package.json")),
1968
1879
  "dist",
1969
1880
  "config",
1970
1881
  "defaults"
1971
1882
  );
1972
- let defaultEntryClient = path7.resolve(defaultsDirectory, "entry.client.tsx");
1973
- let defaultEntryServer = path7.resolve(
1883
+ let defaultEntryClient = path8.resolve(defaultsDirectory, "entry.client.tsx");
1884
+ let defaultEntryServer = path8.resolve(
1974
1885
  defaultsDirectory,
1975
1886
  `entry.server.node.tsx`
1976
1887
  );
@@ -1979,7 +1890,7 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
1979
1890
  let useTypeScript = flags.typescript ?? true;
1980
1891
  let outputExtension = useTypeScript ? "tsx" : "jsx";
1981
1892
  let outputEntry = `${entry}.${outputExtension}`;
1982
- let outputFile2 = path7.resolve(appDirectory, outputEntry);
1893
+ let outputFile2 = path8.resolve(appDirectory, outputEntry);
1983
1894
  if (!useTypeScript) {
1984
1895
  let javascript = transpile(contents, {
1985
1896
  cwd: rootDirectory,
@@ -1991,7 +1902,7 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
1991
1902
  }
1992
1903
  console.log(
1993
1904
  import_picocolors7.default.blue(
1994
- `Entry file ${entry} created at ${path7.relative(
1905
+ `Entry file ${entry} created at ${path8.relative(
1995
1906
  rootDirectory,
1996
1907
  outputFile2
1997
1908
  )}.`
@@ -2000,16 +1911,16 @@ async function generateEntry(entry, rootDirectory, flags = {}) {
2000
1911
  }
2001
1912
  function resolveRootDirectory(root, flags) {
2002
1913
  if (root) {
2003
- return path7.resolve(root);
1914
+ return path8.resolve(root);
2004
1915
  }
2005
- return process.env.REACT_ROUTER_ROOT || (flags?.config ? path7.dirname(path7.resolve(flags.config)) : process.cwd());
1916
+ return process.env.REACT_ROUTER_ROOT || (flags?.config ? path8.dirname(path8.resolve(flags.config)) : process.cwd());
2006
1917
  }
2007
1918
  async function checkForEntry(rootDirectory, appDirectory, entries2) {
2008
1919
  for (let entry of entries2) {
2009
- let entryPath = path7.resolve(appDirectory, entry);
1920
+ let entryPath = path8.resolve(appDirectory, entry);
2010
1921
  let exists = await import_fs_extra.default.pathExists(entryPath);
2011
1922
  if (exists) {
2012
- let relative8 = path7.relative(rootDirectory, entryPath);
1923
+ let relative8 = path8.relative(rootDirectory, entryPath);
2013
1924
  console.error(import_picocolors7.default.red(`Entry file ${relative8} already exists.`));
2014
1925
  return process.exit(1);
2015
1926
  }