rsbuild-plugin-react-router 0.6.3 → 0.6.4

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/511.js CHANGED
@@ -679,7 +679,7 @@ let mightContainRouteChunkExportName = (source)=>routeChunkExportNames.some((exp
679
679
  invalidChunks.map((name)=>`- ${name}`).join('\n'),
680
680
  `${plural ? 'These exports' : 'This export'} could not be split into ${plural ? 'their own chunks' : 'its own chunk'} because ${plural ? 'they share' : 'it shares'} code with other exports. You should extract any shared code into its own module and then import it within the route module.`
681
681
  ].join('\n\n'));
682
- }, getRouteEntryBaseName = (route, appDirectory)=>normalizeRelativeFilePath(route.file, appDirectory).replace(/^[A-Za-z]:/, '').split('/').filter((segment)=>'' !== segment && '.' !== segment).map((segment)=>'..' === segment ? '__' : segment).join('/').replace(/\.[^/.]+$/, ''), getRouteChunkEntryName = (route, chunkName, appDirectory)=>`${getRouteEntryBaseName(route, appDirectory)}-${routeChunkEntrySuffix[chunkName]}`, setBoundedCacheEntry = (cache, key, value, maxEntries)=>{
682
+ }, getRouteEntryBaseName = (route, appDirectory)=>createRouteId(normalizeRelativeFilePath(route.file, appDirectory).replace(/^[A-Za-z]:/, '').split('/').filter((segment)=>'' !== segment && '.' !== segment).map((segment)=>'..' === segment ? '__' : segment).join('/')), getRouteChunkEntryName = (routeEntryBaseName, chunkName)=>`${routeEntryBaseName}-${routeChunkEntrySuffix[chunkName]}`, setBoundedCacheEntry = (cache, key, value, maxEntries)=>{
683
683
  if (maxEntries <= 0) return void cache.clear();
684
684
  if (!cache.has(key) && cache.size >= maxEntries) {
685
685
  let oldestEntry = cache.keys().next();
package/dist/index.cjs CHANGED
@@ -11665,7 +11665,7 @@ const external_react_router_namespaceObject = require("react-router"), normalize
11665
11665
  invalidChunks.map((name)=>`- ${name}`).join('\n'),
11666
11666
  `${plural ? 'These exports' : 'This export'} could not be split into ${plural ? 'their own chunks' : 'its own chunk'} because ${plural ? 'they share' : 'it shares'} code with other exports. You should extract any shared code into its own module and then import it within the route module.`
11667
11667
  ].join('\n\n'));
11668
- }, getRouteEntryBaseName = (route, appDirectory)=>toSafeEntryPath(normalizeRelativeFilePath(route.file, appDirectory)).replace(/\.[^/.]+$/, ''), getRouteChunkEntryName = (route, chunkName, appDirectory)=>`${getRouteEntryBaseName(route, appDirectory)}-${routeChunkEntrySuffix[chunkName]}`, setBoundedCacheEntry = (cache1, key, value, maxEntries)=>{
11668
+ }, getRouteEntryBaseName = (route, appDirectory)=>createRouteId(toSafeEntryPath(normalizeRelativeFilePath(route.file, appDirectory))), getRouteChunkEntryName = (routeEntryBaseName, chunkName)=>`${routeEntryBaseName}-${routeChunkEntrySuffix[chunkName]}`, setBoundedCacheEntry = (cache1, key, value, maxEntries)=>{
11669
11669
  if (maxEntries <= 0) return void cache1.clear();
11670
11670
  if (!cache1.has(key) && cache1.size >= maxEntries) {
11671
11671
  let oldestEntry = cache1.keys().next();
@@ -11872,16 +11872,25 @@ const createReactRouterManifestOptions = ({ routeChunks, routeModuleAnalysis })=
11872
11872
  if (!isBuild) return 'static/js/virtual/react-router/browser-manifest.js';
11873
11873
  let dir = getManifestDirFromEntryAsset(entryModulePath);
11874
11874
  return `${dir}/manifest-${version}.js`;
11875
- }, getManifestVersion = (fingerprintedValues)=>(0, external_node_crypto_namespaceObject.createHash)('md5').update(JSON.stringify(fingerprintedValues)).digest('hex').slice(0, 8), getReactRouterManifestChunkNames = (routes, appDirectory, splitRouteModules = !1)=>{
11875
+ }, getReactRouterManifestChunkNames = (routes, appDirectory, splitRouteModules = !1)=>{
11876
11876
  let chunkNames = new Set([
11877
11877
  'entry.client'
11878
11878
  ]);
11879
- for (let route of Object.values(routes))if (chunkNames.add(getRouteEntryBaseName(route, appDirectory)), splitRouteModules && 'root' !== route.id) for (let exportName of routeChunkExportNames)chunkNames.add(getRouteChunkEntryName(route, exportName, appDirectory));
11879
+ for (let route of Object.values(routes)){
11880
+ let routeEntryName = getRouteEntryBaseName(route, appDirectory);
11881
+ if (chunkNames.add(routeEntryName), splitRouteModules && 'root' !== route.id) for (let exportName of routeChunkExportNames)chunkNames.add(getRouteChunkEntryName(routeEntryName, exportName));
11882
+ }
11880
11883
  return chunkNames;
11881
- }, createRouteManifestItem = ({ route, appDirectory, assetPrefix, jsAssets, routeAnalysis, getModulePathForChunk, getCssAssetsForChunk })=>{
11882
- let routeChunkMap = routeAnalysis.hasRouteChunkByExportName, chunkModulePath = (exportName)=>routeChunkMap?.[exportName] ? getModulePathForChunk(getRouteChunkEntryName(route, exportName, appDirectory)) : void 0, cssAssets = [
11884
+ }, createRouteManifestItem = ({ route, routeEntryName, assetPrefix, jsAssets, routeAnalysis, getModulePathForChunk, getCssAssetsForChunk })=>{
11885
+ let routeChunkMap = routeAnalysis.hasRouteChunkByExportName, chunkEntryName = (exportName)=>routeChunkMap?.[exportName] ? getRouteChunkEntryName(routeEntryName, exportName) : void 0, chunkModulePath = (exportName)=>{
11886
+ let name = chunkEntryName(exportName);
11887
+ return name ? getModulePathForChunk(name) : void 0;
11888
+ }, cssAssets = [
11883
11889
  ...routeAnalysis.cssAssets,
11884
- ...routeChunkExportNames.flatMap((exportName)=>routeChunkMap?.[exportName] ? getCssAssetsForChunk(getRouteChunkEntryName(route, exportName, appDirectory)) : [])
11890
+ ...routeChunkExportNames.flatMap((exportName)=>{
11891
+ let name = chunkEntryName(exportName);
11892
+ return name ? getCssAssetsForChunk(name) : [];
11893
+ })
11885
11894
  ];
11886
11895
  return {
11887
11896
  id: route.id,
@@ -11933,7 +11942,7 @@ function generateReactRouterManifestForDevEffect(routes, clientStats, context, a
11933
11942
  key,
11934
11943
  createRouteManifestItem({
11935
11944
  route,
11936
- appDirectory: context,
11945
+ routeEntryName,
11937
11946
  assetPrefix,
11938
11947
  jsAssets,
11939
11948
  routeAnalysis,
@@ -11953,7 +11962,7 @@ function generateReactRouterManifestForDevEffect(routes, clientStats, context, a
11953
11962
  css: entryCssAssets.map((asset)=>combineURLs(assetPrefix, asset))
11954
11963
  },
11955
11964
  routes: result
11956
- }, version = getManifestVersion(fingerprintedValues), manifestPath = getReactRouterManifestPath({
11965
+ }, version = (0, external_node_crypto_namespaceObject.createHash)('md5').update(JSON.stringify(fingerprintedValues)).digest('hex').slice(0, 8), manifestPath = getReactRouterManifestPath({
11957
11966
  version,
11958
11967
  isBuild,
11959
11968
  entryModulePath: entryJsAssets[0]
@@ -15477,9 +15486,10 @@ export {
15477
15486
  }, createClassicWebRouteEntries = ({ appDirectory, isBuild, routes, splitRouteModules })=>{
15478
15487
  let manifestChunkNames = new Set([
15479
15488
  'entry.client'
15480
- ]), webRouteEntries = Object.values(routes).reduce((acc, route)=>{
15481
- let entryName = getRouteEntryBaseName(route, appDirectory), routeFilePath = (0, external_pathe_namespaceObject.resolve)(appDirectory, route.file);
15482
- if (manifestChunkNames.add(entryName), acc[entryName] = {
15489
+ ]), routeFileByEntryName = new Map(), webRouteEntries = Object.values(routes).reduce((acc, route)=>{
15490
+ let entryName = getRouteEntryBaseName(route, appDirectory), routeFilePath = (0, external_pathe_namespaceObject.resolve)(appDirectory, route.file), existingRouteFile = routeFileByEntryName.get(entryName);
15491
+ if (void 0 !== existingRouteFile && existingRouteFile !== routeFilePath) throw Error(`[rsbuild-plugin-react-router] Route files ${JSON.stringify(existingRouteFile)} and ${JSON.stringify(routeFilePath)} both resolve to the entry name ${JSON.stringify(entryName)}. Rename one of them so their paths relative to the app directory differ.`);
15492
+ if (routeFileByEntryName.set(entryName, routeFilePath), manifestChunkNames.add(entryName), acc[entryName] = {
15483
15493
  import: `${routeFilePath}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
15484
15494
  html: !1
15485
15495
  }, isBuild && splitRouteModules && 'root' !== route.id) {
@@ -15492,7 +15502,7 @@ export {
15492
15502
  }
15493
15503
  for (let exportName of routeChunkExportNames){
15494
15504
  if (!source.includes(exportName)) continue;
15495
- let chunkEntryName = getRouteChunkEntryName(route, exportName, appDirectory);
15505
+ let chunkEntryName = getRouteChunkEntryName(entryName, exportName);
15496
15506
  manifestChunkNames.add(chunkEntryName), acc[chunkEntryName] = {
15497
15507
  import: getRouteChunkModuleId(routeFilePath, exportName),
15498
15508
  html: !1
@@ -15814,7 +15824,7 @@ export {
15814
15824
  throw Error(`Error loading ${displayPath}: ${error}`);
15815
15825
  }
15816
15826
  } else console.warn('No react-router.config found, using default configuration.');
15817
- let { resolved: resolvedConfig, userAndPresetConfig, presets: configPresets, hasConfiguredServerModuleFormat } = await effectRuntime.runPromise(resolveReactRouterConfigEffect(reactRouterUserConfig)), { appDirectory, basename, buildDirectory, future, allowedActionOrigins, routeDiscovery: userRouteDiscovery, ssr, prerender: prerenderConfig, serverBuildFile, serverBundles, serverModuleFormat, splitRouteModules, subResourceIntegrity, buildEnd } = resolvedConfig;
15827
+ let { resolved: resolvedConfig, presets: configPresets, hasConfiguredServerModuleFormat } = await effectRuntime.runPromise(resolveReactRouterConfigEffect(reactRouterUserConfig)), { appDirectory, basename, buildDirectory, future, allowedActionOrigins, routeDiscovery: userRouteDiscovery, ssr, prerender: prerenderConfig, serverBuildFile, serverBundles, serverModuleFormat, splitRouteModules, subResourceIntegrity, buildEnd } = resolvedConfig;
15818
15828
  await registerReactRouterTypegen(api, {
15819
15829
  runtime: effectRuntime,
15820
15830
  appDirectory
@@ -15910,10 +15920,7 @@ export {
15910
15920
  for (let preset of configPresets)await preset.reactRouterConfigResolved?.({
15911
15921
  reactRouterConfig: resolvedConfigForPreset
15912
15922
  });
15913
- let buildEndReactRouterConfig = {
15914
- ...resolvedConfigWithRoutes,
15915
- future: userAndPresetConfig.future ?? {}
15916
- }, isBuild = 'build' === api.context.action;
15923
+ let isBuild = 'build' === api.context.action;
15917
15924
  isBuild || api.onAfterEnvironmentCompile(({ environment, stats })=>{
15918
15925
  'node' === environment.name && stats && !stats.hasErrors() && registerDevServerSourceMaps(stats.compilation);
15919
15926
  });
@@ -16057,7 +16064,7 @@ export {
16057
16064
  routeChunkOptions: modePlan.routeChunkOptions,
16058
16065
  routeModuleAnalysis,
16059
16066
  buildManifest: modePlan.artifacts.buildManifest,
16060
- buildEndReactRouterConfig,
16067
+ buildEndReactRouterConfig: resolvedConfigWithRoutes,
16061
16068
  buildEnd
16062
16069
  })))) : api.onAfterBuild(({ environments })=>effectRuntime.runPromise(tryPluginPromise(()=>runReactRouterRscPrerenderBuild({
16063
16070
  api,
package/dist/index.js CHANGED
@@ -7463,10 +7463,16 @@ async function generateReactRouterManifestForDev(routes, _options, clientStats,
7463
7463
  valid: buildManifestChunkValidity(routeAnalysis.exports, routeAnalysis.hasRouteChunkByExportName ?? createEmptyRouteChunkByExportName())
7464
7464
  }), [
7465
7465
  key,
7466
- (({ route, appDirectory, assetPrefix, jsAssets, routeAnalysis, getModulePathForChunk, getCssAssetsForChunk })=>{
7467
- let routeChunkMap = routeAnalysis.hasRouteChunkByExportName, chunkModulePath = (exportName)=>routeChunkMap?.[exportName] ? getModulePathForChunk(getRouteChunkEntryName(route, exportName, appDirectory)) : void 0, cssAssets = [
7466
+ (({ route, routeEntryName, assetPrefix, jsAssets, routeAnalysis, getModulePathForChunk, getCssAssetsForChunk })=>{
7467
+ let routeChunkMap = routeAnalysis.hasRouteChunkByExportName, chunkEntryName = (exportName)=>routeChunkMap?.[exportName] ? getRouteChunkEntryName(routeEntryName, exportName) : void 0, chunkModulePath = (exportName)=>{
7468
+ let name = chunkEntryName(exportName);
7469
+ return name ? getModulePathForChunk(name) : void 0;
7470
+ }, cssAssets = [
7468
7471
  ...routeAnalysis.cssAssets,
7469
- ...routeChunkExportNames.flatMap((exportName)=>routeChunkMap?.[exportName] ? getCssAssetsForChunk(getRouteChunkEntryName(route, exportName, appDirectory)) : [])
7472
+ ...routeChunkExportNames.flatMap((exportName)=>{
7473
+ let name = chunkEntryName(exportName);
7474
+ return name ? getCssAssetsForChunk(name) : [];
7475
+ })
7470
7476
  ];
7471
7477
  return {
7472
7478
  id: route.id,
@@ -7491,7 +7497,7 @@ async function generateReactRouterManifestForDev(routes, _options, clientStats,
7491
7497
  };
7492
7498
  })({
7493
7499
  route,
7494
- appDirectory: context,
7500
+ routeEntryName,
7495
7501
  assetPrefix: assetPrefix,
7496
7502
  jsAssets,
7497
7503
  routeAnalysis,
@@ -9742,9 +9748,10 @@ export {
9742
9748
  let reactRouterPath, reactRouterDomPath, { manifestChunkNames, webRouteEntries } = (({ appDirectory, isBuild, routes, splitRouteModules })=>{
9743
9749
  let manifestChunkNames = new Set([
9744
9750
  'entry.client'
9745
- ]), webRouteEntries = Object.values(routes).reduce((acc, route)=>{
9746
- let entryName = getRouteEntryBaseName(route, appDirectory), routeFilePath = external_pathe_resolve(appDirectory, route.file);
9747
- if (manifestChunkNames.add(entryName), acc[entryName] = {
9751
+ ]), routeFileByEntryName = new Map(), webRouteEntries = Object.values(routes).reduce((acc, route)=>{
9752
+ let entryName = getRouteEntryBaseName(route, appDirectory), routeFilePath = external_pathe_resolve(appDirectory, route.file), existingRouteFile = routeFileByEntryName.get(entryName);
9753
+ if (void 0 !== existingRouteFile && existingRouteFile !== routeFilePath) throw Error(`[rsbuild-plugin-react-router] Route files ${JSON.stringify(existingRouteFile)} and ${JSON.stringify(routeFilePath)} both resolve to the entry name ${JSON.stringify(entryName)}. Rename one of them so their paths relative to the app directory differ.`);
9754
+ if (routeFileByEntryName.set(entryName, routeFilePath), manifestChunkNames.add(entryName), acc[entryName] = {
9748
9755
  import: `${routeFilePath}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
9749
9756
  html: !1
9750
9757
  }, isBuild && splitRouteModules && 'root' !== route.id) {
@@ -9757,7 +9764,7 @@ export {
9757
9764
  }
9758
9765
  for (let exportName of routeChunkExportNames){
9759
9766
  if (!source.includes(exportName)) continue;
9760
- let chunkEntryName = getRouteChunkEntryName(route, exportName, appDirectory);
9767
+ let chunkEntryName = getRouteChunkEntryName(entryName, exportName);
9761
9768
  manifestChunkNames.add(chunkEntryName), acc[chunkEntryName] = {
9762
9769
  import: getRouteChunkModuleId(routeFilePath, exportName),
9763
9770
  html: !1
@@ -10111,7 +10118,7 @@ export {
10111
10118
  throw Error(`Error loading ${displayPath}: ${error}`);
10112
10119
  }
10113
10120
  } else console.warn('No react-router.config found, using default configuration.');
10114
- let { resolved: resolvedConfig, userAndPresetConfig, presets: configPresets, hasConfiguredServerModuleFormat } = await effectRuntime.runPromise((reactRouterUserConfig = reactRouterUserConfig1, core_gen(function*() {
10121
+ let { resolved: resolvedConfig, presets: configPresets, hasConfiguredServerModuleFormat } = await effectRuntime.runPromise((reactRouterUserConfig = reactRouterUserConfig1, core_gen(function*() {
10115
10122
  let userAndPresetConfigs = ((...configs)=>configs.reduce((configA, configB)=>{
10116
10123
  let mergeRequired = (key)=>void 0 !== configA[key] && void 0 !== configB[key];
10117
10124
  return {
@@ -10393,10 +10400,7 @@ export {
10393
10400
  for (let preset of configPresets)await preset.reactRouterConfigResolved?.({
10394
10401
  reactRouterConfig: resolvedConfigForPreset
10395
10402
  });
10396
- let buildEndReactRouterConfig = {
10397
- ...resolvedConfigWithRoutes,
10398
- future: userAndPresetConfig.future ?? {}
10399
- }, isBuild = 'build' === api.context.action;
10403
+ let isBuild = 'build' === api.context.action;
10400
10404
  isBuild || api.onAfterEnvironmentCompile(({ environment, stats })=>{
10401
10405
  'node' === environment.name && stats && !stats.hasErrors() && ((compilation)=>{
10402
10406
  let outputPath = compilation.outputOptions.path;
@@ -10910,7 +10914,7 @@ if (typeof window !== 'undefined' && import.meta.webpackHot) {
10910
10914
  routeChunkOptions: modePlan.routeChunkOptions,
10911
10915
  routeModuleAnalysis,
10912
10916
  buildManifest: modePlan.artifacts.buildManifest,
10913
- buildEndReactRouterConfig,
10917
+ buildEndReactRouterConfig: resolvedConfigWithRoutes,
10914
10918
  buildEnd
10915
10919
  })))) : api.onAfterBuild(({ environments })=>effectRuntime.runPromise(tryPluginPromise(()=>runReactRouterRscPrerenderBuild({
10916
10920
  api,
@@ -11254,7 +11258,10 @@ if (typeof window !== 'undefined' && import.meta.webpackHot) {
11254
11258
  let chunkNames = new Set([
11255
11259
  'entry.client'
11256
11260
  ]);
11257
- for (let route of Object.values(routes))if (chunkNames.add(getRouteEntryBaseName(route, appDirectory)), splitRouteModules && 'root' !== route.id) for (let exportName of routeChunkExportNames)chunkNames.add(getRouteChunkEntryName(route, exportName, appDirectory));
11261
+ for (let route of Object.values(routes)){
11262
+ let routeEntryName = getRouteEntryBaseName(route, appDirectory);
11263
+ if (chunkNames.add(routeEntryName), splitRouteModules && 'root' !== route.id) for (let exportName of routeChunkExportNames)chunkNames.add(getRouteChunkEntryName(routeEntryName, exportName));
11264
+ }
11258
11265
  return chunkNames;
11259
11266
  })(routes, appDirectory, routeChunkOptions?.splitRouteModules), isBuild = !!routeChunkOptions?.isBuild, finalizeSri = !!(isBuild && (options?.subResourceIntegrity ?? options?.future?.unstable_subResourceIntegrity)), buildAndEmitManifest = async ({ assets, sources, compilation }, { withSri })=>{
11260
11267
  let currentAssetPrefix = getAssetPrefix(), stats = createReactRouterManifestStats(compilation, manifestChunkNames), { manifest, moduleExportsByRouteId } = await generateReactRouterManifestForDev(routes, pluginOptions, stats, appDirectory, currentAssetPrefix, createReactRouterManifestOptions({
@@ -40,7 +40,5 @@ export declare const validateRouteChunks: (args: {
40
40
  export declare const getRouteEntryBaseName: (route: {
41
41
  file: string;
42
42
  }, appDirectory: string) => string;
43
- export declare const getRouteChunkEntryName: (route: {
44
- file: string;
45
- }, chunkName: RouteChunkExportName, appDirectory: string) => string;
43
+ export declare const getRouteChunkEntryName: (routeEntryBaseName: string, chunkName: RouteChunkExportName) => string;
46
44
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rsbuild-plugin-react-router",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "description": "React Router plugin for Rsbuild",
5
5
  "repository": {
6
6
  "type": "git",
@@ -143,10 +143,26 @@ export const createClassicWebRouteEntries = ({
143
143
  webRouteEntries: Record<string, RsbuildEntryDescription>;
144
144
  } => {
145
145
  const manifestChunkNames = new Set<string>(['entry.client']);
146
+ // Entry names are sanitized paths, so two distinct route files could in
147
+ // principle map to one name (for example `../shared/x.tsx` and
148
+ // `__/shared/x.tsx`). Refuse that instead of letting one route silently
149
+ // serve the other's module. Routes that share a file intentionally share
150
+ // an entry.
151
+ const routeFileByEntryName = new Map<string, string>();
146
152
  const webRouteEntries = Object.values(routes).reduce(
147
153
  (acc, route) => {
148
154
  const entryName = getRouteEntryBaseName(route, appDirectory);
149
155
  const routeFilePath = resolve(appDirectory, route.file);
156
+ const existingRouteFile = routeFileByEntryName.get(entryName);
157
+ if (
158
+ existingRouteFile !== undefined &&
159
+ existingRouteFile !== routeFilePath
160
+ ) {
161
+ throw new Error(
162
+ `[rsbuild-plugin-react-router] Route files ${JSON.stringify(existingRouteFile)} and ${JSON.stringify(routeFilePath)} both resolve to the entry name ${JSON.stringify(entryName)}. Rename one of them so their paths relative to the app directory differ.`
163
+ );
164
+ }
165
+ routeFileByEntryName.set(entryName, routeFilePath);
150
166
  manifestChunkNames.add(entryName);
151
167
  acc[entryName] = {
152
168
  import: `${routeFilePath}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
@@ -167,11 +183,7 @@ export const createClassicWebRouteEntries = ({
167
183
  if (!source.includes(exportName)) {
168
184
  continue;
169
185
  }
170
- const chunkEntryName = getRouteChunkEntryName(
171
- route,
172
- exportName,
173
- appDirectory
174
- );
186
+ const chunkEntryName = getRouteChunkEntryName(entryName, exportName);
175
187
  manifestChunkNames.add(chunkEntryName);
176
188
  acc[chunkEntryName] = {
177
189
  import: getRouteChunkModuleId(routeFilePath, exportName),
package/src/index.ts CHANGED
@@ -263,7 +263,6 @@ export const pluginReactRouter = (
263
263
 
264
264
  const {
265
265
  resolved: resolvedConfig,
266
- userAndPresetConfig,
267
266
  presets: configPresets,
268
267
  hasConfiguredServerModuleFormat,
269
268
  } = await effectRuntime.runPromise(
@@ -472,10 +471,7 @@ export const pluginReactRouter = (
472
471
  resolvedConfigForPreset as ReactRouterPresetResolvedConfig,
473
472
  });
474
473
  }
475
- const buildEndReactRouterConfig: ResolvedReactRouterConfig = {
476
- ...resolvedConfigWithRoutes,
477
- future: userAndPresetConfig.future ?? {},
478
- } as ResolvedReactRouterConfig;
474
+ const buildEndReactRouterConfig = resolvedConfigWithRoutes;
479
475
 
480
476
  const isBuild = api.context.action === 'build';
481
477
  if (!isBuild) {
package/src/manifest.ts CHANGED
@@ -413,26 +413,6 @@ export const getReactRouterManifestPath = ({
413
413
  return `${dir}/manifest-${version}.js`;
414
414
  };
415
415
 
416
- // The version is derived from the manifest content in every mode. React
417
- // Router's stale-client detection compares the version the browser loaded with
418
- // the one the server build was pinned to, and answers a mismatch with a
419
- // document reload. In development the browser manifest asset is served from
420
- // the latest web compilation while the server build stays pinned to the
421
- // compilation it was committed with, so a random per-compilation version made
422
- // the two disagree whenever a web compilation completed without changing the
423
- // manifest (for example the hot data revalidation recompile that follows a
424
- // server change), reloading the document for no reason. Equal content now
425
- // yields an equal version, and a real manifest change still busts the browser
426
- // cache through the `?v=` query on the development manifest URL.
427
- const getManifestVersion = (fingerprintedValues: {
428
- entry: unknown;
429
- routes: unknown;
430
- }): string =>
431
- createHash('md5')
432
- .update(JSON.stringify(fingerprintedValues))
433
- .digest('hex')
434
- .slice(0, 8);
435
-
436
416
  export const getReactRouterManifestChunkNames = (
437
417
  routes: Record<string, Route>,
438
418
  appDirectory: string,
@@ -440,12 +420,13 @@ export const getReactRouterManifestChunkNames = (
440
420
  ): Set<string> => {
441
421
  const chunkNames = new Set<string>(['entry.client']);
442
422
  for (const route of Object.values(routes)) {
443
- chunkNames.add(getRouteEntryBaseName(route, appDirectory));
423
+ const routeEntryName = getRouteEntryBaseName(route, appDirectory);
424
+ chunkNames.add(routeEntryName);
444
425
  if (!splitRouteModules || route.id === 'root') {
445
426
  continue;
446
427
  }
447
428
  for (const exportName of routeChunkExportNames) {
448
- chunkNames.add(getRouteChunkEntryName(route, exportName, appDirectory));
429
+ chunkNames.add(getRouteChunkEntryName(routeEntryName, exportName));
449
430
  }
450
431
  }
451
432
  return chunkNames;
@@ -453,7 +434,7 @@ export const getReactRouterManifestChunkNames = (
453
434
 
454
435
  const createRouteManifestItem = ({
455
436
  route,
456
- appDirectory,
437
+ routeEntryName,
457
438
  assetPrefix,
458
439
  jsAssets,
459
440
  routeAnalysis,
@@ -461,7 +442,7 @@ const createRouteManifestItem = ({
461
442
  getCssAssetsForChunk,
462
443
  }: {
463
444
  route: Route;
464
- appDirectory: string;
445
+ routeEntryName: string;
465
446
  assetPrefix: string;
466
447
  jsAssets: string[];
467
448
  routeAnalysis: RouteManifestAnalysis;
@@ -469,21 +450,20 @@ const createRouteManifestItem = ({
469
450
  getCssAssetsForChunk: (chunkName: string) => string[];
470
451
  }): RouteManifestItem => {
471
452
  const routeChunkMap = routeAnalysis.hasRouteChunkByExportName;
472
- const chunkModulePath = (exportName: RouteChunkExportName) =>
453
+ const chunkEntryName = (exportName: RouteChunkExportName) =>
473
454
  routeChunkMap?.[exportName]
474
- ? getModulePathForChunk(
475
- getRouteChunkEntryName(route, exportName, appDirectory)
476
- )
455
+ ? getRouteChunkEntryName(routeEntryName, exportName)
477
456
  : undefined;
457
+ const chunkModulePath = (exportName: RouteChunkExportName) => {
458
+ const name = chunkEntryName(exportName);
459
+ return name ? getModulePathForChunk(name) : undefined;
460
+ };
478
461
  const cssAssets = [
479
462
  ...routeAnalysis.cssAssets,
480
- ...routeChunkExportNames.flatMap(exportName =>
481
- routeChunkMap?.[exportName]
482
- ? getCssAssetsForChunk(
483
- getRouteChunkEntryName(route, exportName, appDirectory)
484
- )
485
- : []
486
- ),
463
+ ...routeChunkExportNames.flatMap(exportName => {
464
+ const name = chunkEntryName(exportName);
465
+ return name ? getCssAssetsForChunk(name) : [];
466
+ }),
487
467
  ];
488
468
 
489
469
  return {
@@ -581,7 +561,7 @@ function generateReactRouterManifestForDevEffect(
581
561
  key,
582
562
  createRouteManifestItem({
583
563
  route,
584
- appDirectory: context,
564
+ routeEntryName,
585
565
  assetPrefix,
586
566
  jsAssets,
587
567
  routeAnalysis,
@@ -625,7 +605,14 @@ function generateReactRouterManifestForDevEffect(
625
605
  },
626
606
  routes: result,
627
607
  };
628
- const version = getManifestVersion(fingerprintedValues);
608
+ // Content-derived in development too. React Router's stale-client check
609
+ // compares the browser's manifest version with the pinned server build's,
610
+ // and a random per-compilation version made unchanged manifests differ
611
+ // whenever a web compilation completed without a new server pin.
612
+ const version = createHash('md5')
613
+ .update(JSON.stringify(fingerprintedValues))
614
+ .digest('hex')
615
+ .slice(0, 8);
629
616
  const manifestPath = getReactRouterManifestPath({
630
617
  version,
631
618
  isBuild,
@@ -7,6 +7,7 @@ import { print } from 'yuku-codegen';
7
7
  import { walk } from 'yuku-parser';
8
8
  import { dirname, normalize, relative, resolve } from 'pathe';
9
9
  import { SERVER_ONLY_ROUTE_EXPORTS_SET } from './constants.js';
10
+ import { createRouteId } from './plugin-utils.js';
10
11
 
11
12
  type AnyNode = Record<string, any>;
12
13
 
@@ -984,16 +985,11 @@ export const getRouteEntryBaseName = (
984
985
  route: { file: string },
985
986
  appDirectory: string
986
987
  ): string =>
987
- toSafeEntryPath(normalizeRelativeFilePath(route.file, appDirectory)).replace(
988
- /\.[^/.]+$/,
989
- ''
988
+ createRouteId(
989
+ toSafeEntryPath(normalizeRelativeFilePath(route.file, appDirectory))
990
990
  );
991
991
 
992
992
  export const getRouteChunkEntryName = (
993
- route: { file: string },
994
- chunkName: RouteChunkExportName,
995
- appDirectory: string
996
- ): string =>
997
- `${getRouteEntryBaseName(route, appDirectory)}-${
998
- routeChunkEntrySuffix[chunkName]
999
- }`;
993
+ routeEntryBaseName: string,
994
+ chunkName: RouteChunkExportName
995
+ ): string => `${routeEntryBaseName}-${routeChunkEntrySuffix[chunkName]}`;