@react-router/dev 7.2.0 → 7.3.0-pre.0

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,29 @@
1
1
  # `@react-router/dev`
2
2
 
3
+ ## 7.3.0-pre.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix support for custom client `build.rollupOptions.output.entryFileNames` ([#13098](https://github.com/remix-run/react-router/pull/13098))
8
+ - Fix usage of `prerender` option when `serverBundles` option has been configured or provided by a preset, e.g. `vercelPreset` from `@vercel/react-router` ([#13082](https://github.com/remix-run/react-router/pull/13082))
9
+ - Fix support for custom `build.assetsDir` ([#13077](https://github.com/remix-run/react-router/pull/13077))
10
+ - Remove unused dependencies ([#13134](https://github.com/remix-run/react-router/pull/13134))
11
+ - Stub all routes except root in "SPA Mode" server builds to avoid issues when route modules or their dependencies import non-SSR-friendly modules ([#13023](https://github.com/remix-run/react-router/pull/13023))
12
+ - Fix errors with `future.unstable_viteEnvironmentApi` when the `ssr` environment has been configured by another plugin to be a custom `Vite.DevEnvironment` rather than the default `Vite.RunnableDevEnvironment` ([#13008](https://github.com/remix-run/react-router/pull/13008))
13
+ - Remove unused Vite file system watcher ([#13133](https://github.com/remix-run/react-router/pull/13133))
14
+ - Fix support for custom SSR build input when `serverBundles` option has been configured ([#13107](https://github.com/remix-run/react-router/pull/13107))
15
+
16
+ Note that for consumers using the `future.unstable_viteEnvironmentApi` and `serverBundles` options together, hyphens are no longer supported in server bundle IDs since they also need to be valid Vite environment names.
17
+
18
+ - Fix dev server when using HTTPS by stripping HTTP/2 pseudo headers from dev server requests ([#12830](https://github.com/remix-run/react-router/pull/12830))
19
+ - Lazy load Cloudflare platform proxy on first dev server request when using the `cloudflareDevProxy` Vite plugin to avoid creating unnecessary workerd processes ([#13016](https://github.com/remix-run/react-router/pull/13016))
20
+ - When `future.unstable_viteEnvironmentApi` is enabled and the `ssr` environment has `optimizeDeps.noDiscovery` disabled, define `optimizeDeps.entries` and `optimizeDeps.include` ([#13007](https://github.com/remix-run/react-router/pull/13007))
21
+ - Fix duplicated entries in typegen for layout routes and their corresponding index route ([#13140](https://github.com/remix-run/react-router/pull/13140))
22
+ - Updated dependencies:
23
+ - `react-router@7.3.0-pre.0`
24
+ - `@react-router/node@7.3.0-pre.0`
25
+ - `@react-router/serve@7.3.0-pre.0`
26
+
3
27
  ## 7.2.0
4
28
 
5
29
  ### Minor Changes
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  Dev tools and CLI for React Router that enables framework features through bundler integration like server rendering, code splitting, HMR, etc.
2
2
 
3
3
  ```sh
4
- npm install @react-router/dev
4
+ npm install @react-router/dev --save-dev
5
5
  ```
package/dist/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * @react-router/dev v7.2.0
3
+ * @react-router/dev v7.3.0-pre.0
4
4
  *
5
5
  * Copyright (c) Remix Software Inc.
6
6
  *
@@ -100,27 +100,53 @@ var init_vite = __esm({
100
100
  }
101
101
  });
102
102
 
103
+ // vite/ssr-externals.ts
104
+ var ssrExternals;
105
+ var init_ssr_externals = __esm({
106
+ "vite/ssr-externals.ts"() {
107
+ "use strict";
108
+ init_is_react_router_repo();
109
+ ssrExternals = isReactRouterRepo() ? [
110
+ // This is only needed within this repo because these packages
111
+ // are linked to a directory outside of node_modules so Vite
112
+ // treats them as internal code by default.
113
+ "react-router",
114
+ "react-router-dom",
115
+ "@react-router/architect",
116
+ "@react-router/cloudflare",
117
+ "@react-router/dev",
118
+ "@react-router/express",
119
+ "@react-router/node",
120
+ "@react-router/serve"
121
+ ] : void 0;
122
+ }
123
+ });
124
+
103
125
  // vite/vite-node.ts
104
- async function createContext(viteConfig = {}) {
126
+ async function createContext({
127
+ root,
128
+ mode
129
+ }) {
105
130
  await preloadVite();
106
131
  const vite2 = getVite();
107
- const devServer = await vite2.createServer(
108
- vite2.mergeConfig(
109
- {
110
- server: {
111
- preTransformRequests: false,
112
- hmr: false
113
- },
114
- optimizeDeps: {
115
- noDiscovery: true
116
- },
117
- configFile: false,
118
- envFile: false,
119
- plugins: []
120
- },
121
- viteConfig
122
- )
123
- );
132
+ const devServer = await vite2.createServer({
133
+ root,
134
+ mode,
135
+ server: {
136
+ preTransformRequests: false,
137
+ hmr: false,
138
+ watch: null
139
+ },
140
+ ssr: {
141
+ external: ssrExternals
142
+ },
143
+ optimizeDeps: {
144
+ noDiscovery: true
145
+ },
146
+ configFile: false,
147
+ envFile: false,
148
+ plugins: []
149
+ });
124
150
  await devServer.pluginContainer.buildStart({});
125
151
  const server = new import_server.ViteNodeServer(devServer);
126
152
  (0, import_source_map.installSourcemapsSupport)({
@@ -146,6 +172,7 @@ var init_vite_node = __esm({
146
172
  import_client = require("vite-node/client");
147
173
  import_source_map = require("vite-node/source-map");
148
174
  init_vite();
175
+ init_ssr_externals();
149
176
  }
150
177
  });
151
178
 
@@ -389,6 +416,7 @@ async function resolveConfig({
389
416
  );
390
417
  }
391
418
  let future = {
419
+ unstable_middleware: reactRouterUserConfig.future?.unstable_middleware ?? false,
392
420
  unstable_optimizeDeps: reactRouterUserConfig.future?.unstable_optimizeDeps ?? false,
393
421
  unstable_splitRouteModules: reactRouterUserConfig.future?.unstable_splitRouteModules ?? false,
394
422
  unstable_viteEnvironmentApi: reactRouterUserConfig.future?.unstable_viteEnvironmentApi ?? false
@@ -418,11 +446,7 @@ async function createConfigLoader({
418
446
  root = root ?? process.env.REACT_ROUTER_ROOT ?? process.cwd();
419
447
  let viteNodeContext = await createContext({
420
448
  root,
421
- mode: watch2 ? "development" : "production",
422
- server: !watch2 ? { watch: null } : {},
423
- ssr: {
424
- external: ssrExternals
425
- }
449
+ mode: watch2 ? "development" : "production"
426
450
  });
427
451
  let reactRouterConfigFile = findEntry(root, "react-router.config", {
428
452
  absolute: true
@@ -516,7 +540,7 @@ function findEntry(dir, basename2, options) {
516
540
  }
517
541
  return void 0;
518
542
  }
519
- 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, branchRouteProperties, configRouteToBranchRoute, mergeReactRouterConfig, deepFreeze, ssrExternals, entryExts;
543
+ 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;
520
544
  var init_config = __esm({
521
545
  "config/config.ts"() {
522
546
  "use strict";
@@ -533,15 +557,7 @@ var init_config = __esm({
533
557
  import_isEqual = __toESM(require("lodash/isEqual"));
534
558
  init_routes();
535
559
  init_detectPackageManager();
536
- init_is_react_router_repo();
537
560
  excludedConfigPresetKeys = ["presets"];
538
- branchRouteProperties = [
539
- "id",
540
- "path",
541
- "file",
542
- "index"
543
- ];
544
- configRouteToBranchRoute = (configRoute) => (0, import_pick2.default)(configRoute, branchRouteProperties);
545
561
  mergeReactRouterConfig = (...configs) => {
546
562
  let reducer = (configA, configB) => {
547
563
  let mergeRequired = (key) => configA[key] !== void 0 && configB[key] !== void 0;
@@ -580,19 +596,6 @@ var init_config = __esm({
580
596
  });
581
597
  return o;
582
598
  };
583
- ssrExternals = isReactRouterRepo() ? [
584
- // This is only needed within this repo because these packages
585
- // are linked to a directory outside of node_modules so Vite
586
- // treats them as internal code by default.
587
- "react-router",
588
- "react-router-dom",
589
- "@react-router/architect",
590
- "@react-router/cloudflare",
591
- "@react-router/dev",
592
- "@react-router/express",
593
- "@react-router/node",
594
- "@react-router/serve"
595
- ] : void 0;
596
599
  entryExts = [".js", ".jsx", ".ts", ".tsx"];
597
600
  }
598
601
  });
@@ -769,6 +772,8 @@ function generate2(ctx, route) {
769
772
  export type HeadersArgs = T.HeadersArgs
770
773
  export type HeadersFunction = (args: HeadersArgs) => Headers | HeadersInit
771
774
 
775
+ export type unstable_MiddlewareFunction = T.CreateServerMiddlewareFunction<Info>
776
+ export type unstable_ClientMiddlewareFunction = T.CreateClientMiddlewareFunction<Info>
772
777
  export type LoaderArgs = T.CreateServerLoaderArgs<Info>
773
778
  export type ClientLoaderArgs = T.CreateClientLoaderArgs<Info>
774
779
  export type ActionArgs = T.CreateServerActionArgs<Info>
@@ -867,12 +872,16 @@ function register(ctx) {
867
872
  }
868
873
  `;
869
874
  const { t: t2 } = babel_exports;
875
+ const indexPaths = new Set(
876
+ Object.values(ctx.config.routes).filter((route) => route.index).map((route) => route.path)
877
+ );
870
878
  const typeParams = t2.tsTypeAliasDeclaration(
871
879
  t2.identifier("Params"),
872
880
  null,
873
881
  t2.tsTypeLiteral(
874
882
  Object.values(ctx.config.routes).map((route) => {
875
883
  if (route.id !== "root" && !route.path) return void 0;
884
+ if (!route.index && indexPaths.has(route.path)) return void 0;
876
885
  const lineage2 = lineage(ctx.config.routes, route);
877
886
  const fullpath2 = fullpath(lineage2);
878
887
  const params = parse2(fullpath2);
@@ -944,7 +953,6 @@ var init_styles = __esm({
944
953
  path6 = __toESM(require("path"));
945
954
  import_react_router = require("react-router");
946
955
  init_resolve_file_url();
947
- init_vite();
948
956
  cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
949
957
  cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
950
958
  }
@@ -1069,68 +1077,22 @@ async function resolveViteConfig({
1069
1077
  }
1070
1078
  return viteConfig;
1071
1079
  }
1072
- async function extractPluginContext(viteConfig) {
1080
+ function extractPluginContext(viteConfig) {
1073
1081
  return viteConfig["__reactRouterPluginContext"];
1074
1082
  }
1075
1083
  function isSeverBundleEnvironmentName(name) {
1076
1084
  return name.startsWith(SSR_BUNDLE_PREFIX);
1077
1085
  }
1078
- function getServerEnvironmentEntries(record, buildManifest) {
1086
+ function getServerEnvironmentEntries(ctx, record) {
1079
1087
  return Object.entries(record).filter(
1080
- ([name]) => buildManifest.serverBundles ? isSeverBundleEnvironmentName(name) : name === "ssr"
1088
+ ([name]) => ctx.buildManifest?.serverBundles ? isSeverBundleEnvironmentName(name) : name === "ssr"
1081
1089
  );
1082
1090
  }
1083
- function getServerEnvironmentKeys(record, buildManifest) {
1084
- return getServerEnvironmentEntries(record, buildManifest).map(([key]) => key);
1091
+ function getServerEnvironmentKeys(ctx, record) {
1092
+ return getServerEnvironmentEntries(ctx, record).map(([key]) => key);
1085
1093
  }
1086
- function getAddressableRoutes(routes2) {
1087
- let nonAddressableIds = /* @__PURE__ */ new Set();
1088
- for (let id in routes2) {
1089
- let route = routes2[id];
1090
- if (route.index) {
1091
- invariant(
1092
- route.parentId,
1093
- `Expected index route "${route.id}" to have "parentId" set`
1094
- );
1095
- nonAddressableIds.add(route.parentId);
1096
- }
1097
- if (typeof route.path !== "string" && !route.index) {
1098
- nonAddressableIds.add(id);
1099
- }
1100
- }
1101
- return Object.values(routes2).filter(
1102
- (route) => !nonAddressableIds.has(route.id)
1103
- );
1104
- }
1105
- function getRouteBranch(routes2, routeId) {
1106
- let branch = [];
1107
- let currentRouteId = routeId;
1108
- while (currentRouteId) {
1109
- let route = routes2[currentRouteId];
1110
- invariant(route, `Missing route for ${currentRouteId}`);
1111
- branch.push(route);
1112
- currentRouteId = route.parentId;
1113
- }
1114
- return branch.reverse();
1115
- }
1116
- function hasServerBundles(buildManifest) {
1117
- return Object.keys(buildManifest.serverBundles ?? {}).length > 0;
1118
- }
1119
- function getRoutesByServerBundleId(buildManifest) {
1120
- if (!buildManifest.routeIdToServerBundleId) {
1121
- return {};
1122
- }
1123
- let routesByServerBundleId = {};
1124
- for (let [routeId, serverBundleId] of Object.entries(
1125
- buildManifest.routeIdToServerBundleId
1126
- )) {
1127
- routesByServerBundleId[serverBundleId] ??= {};
1128
- let branch = getRouteBranch(buildManifest.routes, routeId);
1129
- for (let route of branch) {
1130
- routesByServerBundleId[serverBundleId][route.id] = route;
1131
- }
1132
- }
1133
- return routesByServerBundleId;
1094
+ function getServerBundleIds(ctx) {
1095
+ return ctx.buildManifest?.serverBundles ? Object.keys(ctx.buildManifest.serverBundles) : void 0;
1134
1096
  }
1135
1097
  async function cleanBuildDirectory(viteConfig, ctx) {
1136
1098
  let buildDirectory = ctx.reactRouterConfig.buildDirectory;
@@ -1165,65 +1127,6 @@ async function cleanViteManifests(environmentsOptions, ctx) {
1165
1127
  })
1166
1128
  );
1167
1129
  }
1168
- async function getBuildManifest(ctx) {
1169
- let { routes: routes2, serverBundles, appDirectory } = ctx.reactRouterConfig;
1170
- if (!serverBundles) {
1171
- return { routes: routes2 };
1172
- }
1173
- let { normalizePath } = await import("vite");
1174
- let serverBuildDirectory = getServerBuildDirectory(ctx);
1175
- let resolvedAppDirectory = path7.resolve(ctx.rootDirectory, appDirectory);
1176
- let rootRelativeRoutes = Object.fromEntries(
1177
- Object.entries(routes2).map(([id, route]) => {
1178
- let filePath = path7.join(resolvedAppDirectory, route.file);
1179
- let rootRelativeFilePath = normalizePath(
1180
- path7.relative(ctx.rootDirectory, filePath)
1181
- );
1182
- return [id, { ...route, file: rootRelativeFilePath }];
1183
- })
1184
- );
1185
- let buildManifest = {
1186
- serverBundles: {},
1187
- routeIdToServerBundleId: {},
1188
- routes: rootRelativeRoutes
1189
- };
1190
- await Promise.all(
1191
- getAddressableRoutes(routes2).map(async (route) => {
1192
- let branch = getRouteBranch(routes2, route.id);
1193
- let serverBundleId = await serverBundles({
1194
- branch: branch.map(
1195
- (route2) => configRouteToBranchRoute({
1196
- ...route2,
1197
- // Ensure absolute paths are passed to the serverBundles function
1198
- file: path7.join(resolvedAppDirectory, route2.file)
1199
- })
1200
- )
1201
- });
1202
- if (typeof serverBundleId !== "string") {
1203
- throw new Error(`The "serverBundles" function must return a string`);
1204
- }
1205
- if (!/^[a-zA-Z0-9-_]+$/.test(serverBundleId)) {
1206
- throw new Error(
1207
- `The "serverBundles" function must only return strings containing alphanumeric characters, hyphens and underscores.`
1208
- );
1209
- }
1210
- buildManifest.routeIdToServerBundleId[route.id] = serverBundleId;
1211
- buildManifest.serverBundles[serverBundleId] ??= {
1212
- id: serverBundleId,
1213
- file: normalizePath(
1214
- path7.join(
1215
- path7.relative(
1216
- ctx.rootDirectory,
1217
- path7.join(serverBuildDirectory, serverBundleId)
1218
- ),
1219
- ctx.reactRouterConfig.serverBuildFile
1220
- )
1221
- )
1222
- };
1223
- })
1224
- );
1225
- return buildManifest;
1226
- }
1227
1130
  function mergeEnvironmentOptions(base, ...overrides) {
1228
1131
  let vite2 = getVite();
1229
1132
  return overrides.reduce(
@@ -1231,7 +1134,7 @@ function mergeEnvironmentOptions(base, ...overrides) {
1231
1134
  base
1232
1135
  );
1233
1136
  }
1234
- async function getEnvironmentOptionsResolvers(ctx, buildManifest, viteCommand) {
1137
+ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
1235
1138
  let { serverBuildFile, serverModuleFormat } = ctx.reactRouterConfig;
1236
1139
  let packageRoot = path7.dirname(
1237
1140
  require.resolve("@react-router/dev/package.json")
@@ -1275,7 +1178,15 @@ async function getEnvironmentOptionsResolvers(ctx, buildManifest, viteCommand) {
1275
1178
  let conditions = viteCommand === "build" ? viteServerConditions : ["development", ...viteServerConditions];
1276
1179
  return mergeEnvironmentOptions(getBaseOptions({ viteUserConfig }), {
1277
1180
  resolve: {
1278
- external: ssrExternals,
1181
+ external: (
1182
+ // This check is required to honor the "noExternal: true" config
1183
+ // provided by vite-plugin-cloudflare within this repo. When compiling
1184
+ // for Cloudflare, all server dependencies are externalized, but our
1185
+ // `ssrExternals` config inadvertently overrides this. This doesn't
1186
+ // impact consumers because for them `ssrExternals` is undefined and
1187
+ // Cloudflare's "noExternal: true" config remains intact.
1188
+ ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteUserConfig.environments?.ssr?.resolve?.noExternal === true ? void 0 : ssrExternals
1189
+ ),
1279
1190
  conditions,
1280
1191
  externalConditions: conditions
1281
1192
  },
@@ -1289,6 +1200,7 @@ async function getEnvironmentOptionsResolvers(ctx, buildManifest, viteCommand) {
1289
1200
  copyPublicDir: false,
1290
1201
  // Assets in the public directory are only used by the client
1291
1202
  rollupOptions: {
1203
+ input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id,
1292
1204
  output: {
1293
1205
  entryFileNames: serverBuildFile,
1294
1206
  format: serverModuleFormat
@@ -1320,12 +1232,15 @@ async function getEnvironmentOptionsResolvers(ctx, buildManifest, viteCommand) {
1320
1232
  }
1321
1233
  )
1322
1234
  ],
1323
- output: {
1324
- entryFileNames({ moduleIds }) {
1235
+ output: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.rollupOptions?.output : viteUserConfig?.build?.rollupOptions?.output) ?? {
1236
+ entryFileNames: ({ moduleIds }) => {
1325
1237
  let routeChunkModuleId = moduleIds.find(isRouteChunkModuleId);
1326
1238
  let routeChunkName = routeChunkModuleId ? getRouteChunkNameFromModuleId(routeChunkModuleId) : null;
1327
1239
  let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
1328
- return `assets/[name]${routeChunkSuffix}-[hash].js`;
1240
+ return path7.posix.join(
1241
+ (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : viteUserConfig?.build?.assetsDir) ?? "assets",
1242
+ `[name]${routeChunkSuffix}-[hash].js`
1243
+ );
1329
1244
  }
1330
1245
  }
1331
1246
  },
@@ -1333,22 +1248,17 @@ async function getEnvironmentOptionsResolvers(ctx, buildManifest, viteCommand) {
1333
1248
  }
1334
1249
  })
1335
1250
  };
1336
- if (hasServerBundles(buildManifest)) {
1337
- for (let [serverBundleId, routes2] of Object.entries(
1338
- getRoutesByServerBundleId(buildManifest)
1339
- )) {
1340
- const serverBundleEnvironmentId = serverBundleId.replaceAll("-", "_");
1341
- const environmentName = `${SSR_BUNDLE_PREFIX}${serverBundleEnvironmentId}`;
1251
+ let serverBundleIds = getServerBundleIds(ctx);
1252
+ if (serverBundleIds) {
1253
+ for (let serverBundleId of serverBundleIds) {
1254
+ const environmentName = `${SSR_BUNDLE_PREFIX}${serverBundleId}`;
1342
1255
  environmentOptionsResolvers[environmentName] = ({ viteUserConfig }) => mergeEnvironmentOptions(
1343
1256
  getBaseServerOptions({ viteUserConfig }),
1344
1257
  {
1345
1258
  build: {
1346
- outDir: getServerBuildDirectory(ctx, { serverBundleId }),
1347
- rollupOptions: {
1348
- input: `${virtual.serverBuild.id}?route-ids=${Object.keys(
1349
- routes2
1350
- ).join(",")}`
1351
- }
1259
+ outDir: getServerBuildDirectory(ctx.reactRouterConfig, {
1260
+ serverBundleId
1261
+ })
1352
1262
  }
1353
1263
  },
1354
1264
  // Ensure server bundle environments extend the user's SSR
@@ -1359,13 +1269,27 @@ async function getEnvironmentOptionsResolvers(ctx, buildManifest, viteCommand) {
1359
1269
  } else {
1360
1270
  environmentOptionsResolvers.ssr = ({ viteUserConfig }) => mergeEnvironmentOptions(getBaseServerOptions({ viteUserConfig }), {
1361
1271
  build: {
1362
- outDir: getServerBuildDirectory(ctx),
1363
- rollupOptions: {
1364
- input: (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi ? viteUserConfig.environments?.ssr?.build?.rollupOptions?.input : viteUserConfig.build?.rollupOptions?.input) ?? virtual.serverBuild.id
1365
- }
1366
- }
1272
+ outDir: getServerBuildDirectory(ctx.reactRouterConfig)
1273
+ },
1274
+ optimizeDeps: ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteUserConfig.environments?.ssr?.optimizeDeps?.noDiscovery === false ? {
1275
+ entries: [
1276
+ vite2.normalizePath(ctx.entryServerFilePath),
1277
+ ...Object.values(ctx.reactRouterConfig.routes).map(
1278
+ (route) => resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
1279
+ )
1280
+ ],
1281
+ include: [
1282
+ "react",
1283
+ "react/jsx-dev-runtime",
1284
+ "react-dom/server",
1285
+ "react-router"
1286
+ ]
1287
+ } : void 0
1367
1288
  });
1368
1289
  }
1290
+ if (ctx.reactRouterConfig.future.unstable_viteEnvironmentApi && viteCommand === "serve") {
1291
+ environmentOptionsResolvers[CSS_DEV_HELPER_ENVIRONMENT_NAME] = () => ({});
1292
+ }
1369
1293
  return environmentOptionsResolvers;
1370
1294
  }
1371
1295
  function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
@@ -1380,7 +1304,7 @@ function resolveEnvironmentsOptions(environmentResolvers, resolverOptions) {
1380
1304
  function isNonNullable(x) {
1381
1305
  return x != null;
1382
1306
  }
1383
- var import_node_crypto, path7, url, fse, babel2, import_react_router2, import_es_module_lexer, import_pick3, import_jsesc, import_picocolors4, import_kebabCase, BUILD_CLIENT_ROUTE_QUERY_STRING, SSR_BUNDLE_PREFIX, virtualHmrRuntime, virtualInjectHmrRuntime, virtual, getServerBuildDirectory, getClientBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER;
1307
+ var import_node_crypto, 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, resolveRelativeRouteFilePath, virtual, getServerBuildDirectory, getClientBuildDirectory, defaultEntriesDir, defaultEntries, REACT_REFRESH_HEADER;
1384
1308
  var init_plugin = __esm({
1385
1309
  "vite/plugin.ts"() {
1386
1310
  "use strict";
@@ -1404,21 +1328,45 @@ var init_plugin = __esm({
1404
1328
  init_resolve_file_url();
1405
1329
  init_combine_urls();
1406
1330
  init_remove_exports();
1331
+ init_ssr_externals();
1407
1332
  init_route_chunks();
1408
1333
  init_vite();
1409
1334
  init_config();
1410
1335
  init_with_props();
1336
+ CLIENT_NON_COMPONENT_EXPORTS = [
1337
+ "clientAction",
1338
+ "clientLoader",
1339
+ "unstable_clientMiddleware",
1340
+ "handle",
1341
+ "meta",
1342
+ "links",
1343
+ "shouldRevalidate"
1344
+ ];
1345
+ CLIENT_ROUTE_EXPORTS = [
1346
+ ...CLIENT_NON_COMPONENT_EXPORTS,
1347
+ "default",
1348
+ "ErrorBoundary",
1349
+ "HydrateFallback",
1350
+ "Layout"
1351
+ ];
1411
1352
  BUILD_CLIENT_ROUTE_QUERY_STRING = "?__react-router-build-client-route";
1412
1353
  SSR_BUNDLE_PREFIX = "ssrBundle_";
1354
+ CSS_DEV_HELPER_ENVIRONMENT_NAME = "__react_router_css_dev_helper__";
1413
1355
  virtualHmrRuntime = create("hmr-runtime");
1414
1356
  virtualInjectHmrRuntime = create("inject-hmr-runtime");
1357
+ resolveRelativeRouteFilePath = (route, reactRouterConfig) => {
1358
+ let vite2 = getVite();
1359
+ let file = route.file;
1360
+ let fullPath = path7.resolve(reactRouterConfig.appDirectory, file);
1361
+ return vite2.normalizePath(fullPath);
1362
+ };
1415
1363
  virtual = {
1416
1364
  serverBuild: create("server-build"),
1417
1365
  serverManifest: create("server-manifest"),
1418
1366
  browserManifest: create("browser-manifest")
1419
1367
  };
1420
- getServerBuildDirectory = (ctx, { serverBundleId } = {}) => path7.join(
1421
- ctx.reactRouterConfig.buildDirectory,
1368
+ getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path7.join(
1369
+ reactRouterConfig.buildDirectory,
1422
1370
  "server",
1423
1371
  ...serverBundleId ? [serverBundleId] : []
1424
1372
  );
@@ -1562,7 +1510,7 @@ async function viteBuild(root, {
1562
1510
  }
1563
1511
  ]
1564
1512
  });
1565
- let ctx = await extractPluginContext(viteConfig);
1513
+ let ctx = extractPluginContext(viteConfig);
1566
1514
  if (!ctx) {
1567
1515
  console.error(
1568
1516
  import_picocolors5.default.red("React Router Vite plugin not found in Vite config")
@@ -1592,14 +1540,16 @@ async function viteBuild(root, {
1592
1540
  optimizeDeps: { force },
1593
1541
  clearScreen,
1594
1542
  logLevel,
1595
- ...{ __reactRouterEnvironmentBuildContext: environmentBuildContext }
1543
+ ...{
1544
+ __reactRouterPluginContext: ctx,
1545
+ __reactRouterEnvironmentBuildContext: environmentBuildContext
1546
+ }
1596
1547
  });
1597
1548
  }
1598
- let { reactRouterConfig } = ctx;
1599
- let buildManifest = await getBuildManifest(ctx);
1549
+ let { reactRouterConfig, buildManifest } = ctx;
1550
+ invariant(buildManifest, "Expected build manifest to be present");
1600
1551
  let environmentOptionsResolvers = await getEnvironmentOptionsResolvers(
1601
1552
  ctx,
1602
- buildManifest,
1603
1553
  "build"
1604
1554
  );
1605
1555
  let environmentsOptions = resolveEnvironmentsOptions(
@@ -1609,8 +1559,8 @@ async function viteBuild(root, {
1609
1559
  await cleanBuildDirectory(viteConfig, ctx);
1610
1560
  await buildEnvironment("client");
1611
1561
  let serverEnvironmentNames = getServerEnvironmentKeys(
1612
- environmentOptionsResolvers,
1613
- buildManifest
1562
+ ctx,
1563
+ environmentOptionsResolvers
1614
1564
  );
1615
1565
  await Promise.all(serverEnvironmentNames.map(buildEnvironment));
1616
1566
  await cleanViteManifests(environmentsOptions, ctx);
@@ -15,6 +15,8 @@ export default function handleRequest(
15
15
  responseHeaders: Headers,
16
16
  routerContext: EntryContext,
17
17
  loadContext: AppLoadContext
18
+ // If you have middleware enabled:
19
+ // loadContext: unstable_RouterContextProvider
18
20
  ) {
19
21
  return new Promise((resolve, reject) => {
20
22
  let shellRendered = false;
package/dist/config.d.ts CHANGED
@@ -37,15 +37,19 @@ type ServerBundlesBuildManifest = BaseBuildManifest & {
37
37
  };
38
38
  type ServerModuleFormat = "esm" | "cjs";
39
39
  interface FutureConfig {
40
+ /**
41
+ * Enable route middleware
42
+ */
43
+ unstable_middleware: boolean;
40
44
  unstable_optimizeDeps: boolean;
41
45
  /**
42
46
  * Automatically split route modules into multiple chunks when possible.
43
47
  */
44
- unstable_splitRouteModules?: boolean | "enforce";
48
+ unstable_splitRouteModules: boolean | "enforce";
45
49
  /**
46
50
  * Use Vite Environment API (experimental)
47
51
  */
48
- unstable_viteEnvironmentApi?: boolean;
52
+ unstable_viteEnvironmentApi: boolean;
49
53
  }
50
54
  type BuildManifest = DefaultBuildManifest | ServerBundlesBuildManifest;
51
55
  type BuildEndHook = (args: {
package/dist/config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v7.2.0
2
+ * @react-router/dev v7.3.0-pre.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
package/dist/routes.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v7.2.0
2
+ * @react-router/dev v7.3.0-pre.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,7 +1,8 @@
1
- import { AppLoadContext } from 'react-router';
1
+ import { UNSAFE_MiddlewareEnabled, unstable_InitialContext, AppLoadContext } from 'react-router';
2
2
  import { Plugin } from 'vite';
3
3
  import { GetPlatformProxyOptions, PlatformProxy } from 'wrangler';
4
4
 
5
+ type MaybePromise<T> = T | Promise<T>;
5
6
  type CfProperties = Record<string, unknown>;
6
7
  type LoadContext<Env, Cf extends CfProperties> = {
7
8
  cloudflare: Omit<PlatformProxy<Env, Cf>, "dispose">;
@@ -9,7 +10,7 @@ type LoadContext<Env, Cf extends CfProperties> = {
9
10
  type GetLoadContext<Env, Cf extends CfProperties> = (args: {
10
11
  request: Request;
11
12
  context: LoadContext<Env, Cf>;
12
- }) => AppLoadContext | Promise<AppLoadContext>;
13
+ }) => UNSAFE_MiddlewareEnabled extends true ? MaybePromise<unstable_InitialContext> : MaybePromise<AppLoadContext>;
13
14
  /**
14
15
  * Vite plugin that provides [Node proxies to local workerd
15
16
  * bindings](https://developers.cloudflare.com/workers/wrangler/api/#getplatformproxy)