rsbuild-plugin-react-router 0.4.1 → 0.6.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.
Files changed (126) hide show
  1. package/README.md +72 -240
  2. package/dist/{451.js → 511.js} +461 -331
  3. package/dist/build-output-transforms.d.ts +32 -7
  4. package/dist/classic-mode.d.ts +56 -0
  5. package/dist/config-imports.d.ts +8 -2
  6. package/dist/constants.d.ts +3 -0
  7. package/dist/dev-background-resources.d.ts +3 -3
  8. package/dist/dev-generation.d.ts +2 -3
  9. package/dist/dev-hmr.d.ts +8 -2
  10. package/dist/dev-runtime-controller.d.ts +6 -1
  11. package/dist/dev-source-maps.d.ts +4 -0
  12. package/dist/effect-runtime.d.ts +17 -5
  13. package/dist/entry-paths.d.ts +16 -0
  14. package/dist/environment-output.d.ts +6 -0
  15. package/dist/export-utils.d.ts +2 -1
  16. package/dist/federation.d.ts +2 -0
  17. package/dist/index.cjs +3675 -2107
  18. package/dist/index.d.ts +3 -1
  19. package/dist/index.js +3614 -2214
  20. package/dist/lazy-compilation-prewarm.d.ts +8 -5
  21. package/dist/manifest.d.ts +16 -4
  22. package/dist/mode-plan.d.ts +82 -0
  23. package/dist/modify-browser-manifest.d.ts +8 -4
  24. package/dist/performance.d.ts +4 -1
  25. package/dist/plugin-utils.d.ts +27 -1
  26. package/dist/prerender-build.d.ts +5 -5
  27. package/dist/prerender.d.ts +1 -5
  28. package/dist/react-router-config.d.ts +11 -3
  29. package/dist/route-artifacts.d.ts +4 -2
  30. package/dist/route-chunks.d.ts +2 -1
  31. package/dist/route-component-transform.d.ts +0 -2
  32. package/dist/route-export-pruning.d.ts +4 -1
  33. package/dist/route-imports.d.ts +18 -0
  34. package/dist/route-module-transform-loader.d.ts +14 -0
  35. package/dist/route-module-transform-loader.js +44 -0
  36. package/dist/route-module-transform-rules.d.ts +14 -0
  37. package/dist/route-transform-tasks.d.ts +6 -0
  38. package/dist/route-watch.d.ts +11 -6
  39. package/dist/rsc-dev-server.d.ts +26 -0
  40. package/dist/rsc-prerender.d.ts +54 -0
  41. package/dist/rsc-route-config.d.ts +6 -0
  42. package/dist/rsc-route-exports.d.ts +15 -0
  43. package/dist/rsc-route-transform-loader.cjs +43 -0
  44. package/dist/rsc-route-transform-loader.d.ts +30 -0
  45. package/dist/rsc-route-transform-loader.js +16 -0
  46. package/dist/rsc-route-transform-registration.d.ts +12 -0
  47. package/dist/rsc-route-transforms.d.ts +21 -0
  48. package/dist/rsc-support.d.ts +23 -0
  49. package/dist/rsc-virtual-modules.d.ts +19 -0
  50. package/dist/server-build-plan.d.ts +2 -1
  51. package/dist/server-build-resolution.d.ts +1 -2
  52. package/dist/server-utils.d.ts +4 -5
  53. package/dist/ssr-asset-relocation.d.ts +98 -0
  54. package/dist/templates/entry.rsc.client.d.ts +1 -0
  55. package/dist/templates/entry.rsc.client.js +61 -0
  56. package/dist/templates/entry.rsc.d.ts +9 -0
  57. package/dist/templates/entry.rsc.js +38 -0
  58. package/dist/templates/entry.rsc.ssr.d.ts +4 -0
  59. package/dist/templates/entry.rsc.ssr.js +24 -0
  60. package/dist/typegen.d.ts +4 -2
  61. package/dist/types.d.ts +34 -6
  62. package/package.json +76 -22
  63. package/src/build-output-transforms.ts +181 -43
  64. package/src/classic-mode.ts +253 -0
  65. package/src/config-imports.ts +153 -6
  66. package/src/constants.ts +6 -2
  67. package/src/dev-background-resources.ts +46 -100
  68. package/src/dev-generation.ts +52 -33
  69. package/src/dev-hmr.ts +112 -80
  70. package/src/dev-runtime-artifacts.ts +11 -12
  71. package/src/dev-runtime-controller.ts +75 -85
  72. package/src/dev-runtime-session.ts +14 -18
  73. package/src/dev-server.ts +2 -0
  74. package/src/dev-source-maps.ts +257 -0
  75. package/src/effect-runtime.ts +105 -57
  76. package/src/entry-paths.ts +80 -0
  77. package/src/environment-output.ts +55 -0
  78. package/src/export-utils.ts +15 -11
  79. package/src/federation.ts +38 -0
  80. package/src/index.ts +666 -519
  81. package/src/lazy-compilation-prewarm.ts +20 -4
  82. package/src/manifest.ts +157 -82
  83. package/src/mode-plan.ts +367 -0
  84. package/src/modify-browser-manifest.ts +130 -124
  85. package/src/performance.ts +11 -2
  86. package/src/plugin-utils.ts +103 -39
  87. package/src/prerender-build.ts +82 -104
  88. package/src/prerender.ts +23 -24
  89. package/src/react-router-config.ts +72 -26
  90. package/src/route-artifacts.ts +96 -66
  91. package/src/route-chunks.ts +167 -51
  92. package/src/route-component-transform.ts +14 -21
  93. package/src/route-export-pruning.ts +4 -3
  94. package/src/route-imports.ts +100 -0
  95. package/src/route-module-transform-loader.ts +149 -0
  96. package/src/route-module-transform-rules.ts +115 -0
  97. package/src/route-transform-tasks.ts +44 -29
  98. package/src/route-watch.ts +166 -188
  99. package/src/rsc-dev-server.ts +112 -0
  100. package/src/rsc-prerender.ts +362 -0
  101. package/src/rsc-route-config.ts +175 -0
  102. package/src/rsc-route-exports.ts +67 -0
  103. package/src/rsc-route-transform-loader.ts +65 -0
  104. package/src/rsc-route-transform-registration.ts +145 -0
  105. package/src/rsc-route-transforms.ts +995 -0
  106. package/src/rsc-runtime.d.ts +143 -0
  107. package/src/rsc-support.ts +116 -0
  108. package/src/rsc-virtual-modules.ts +113 -0
  109. package/src/server-build-plan.ts +14 -3
  110. package/src/server-build-resolution.ts +37 -47
  111. package/src/server-utils.ts +21 -35
  112. package/src/ssr-asset-relocation.ts +183 -0
  113. package/src/ssr-externals.ts +8 -26
  114. package/src/templates/entry.rsc.client.tsx +168 -0
  115. package/src/templates/entry.rsc.ssr.tsx +45 -0
  116. package/src/templates/entry.rsc.tsx +80 -0
  117. package/src/typegen.ts +40 -23
  118. package/src/types.ts +43 -6
  119. package/src/warnings/warn-on-client-source-maps.ts +6 -10
  120. package/dist/parallel-route-transform-protocol.d.ts +0 -25
  121. package/dist/parallel-route-transform-worker.d.ts +0 -1
  122. package/dist/parallel-route-transform-worker.js +0 -38
  123. package/dist/parallel-route-transforms.d.ts +0 -29
  124. package/src/parallel-route-transform-protocol.ts +0 -35
  125. package/src/parallel-route-transform-worker.ts +0 -82
  126. package/src/parallel-route-transforms.ts +0 -458
@@ -6,13 +6,15 @@ import type { NormalizedConfig } from '@rsbuild/core';
6
6
  import type { RouteConfigEntry } from '@react-router/dev/routes';
7
7
  import * as Effect from 'effect/Effect';
8
8
  import { getCappedPluginConcurrency } from './concurrency.js';
9
- import { runPluginEffect, tryPluginPromise } from './effect-runtime.js';
9
+ import { normalizeEffectError, tryPluginPromise } from './effect-runtime.js';
10
+ import { getPackageVersion, parseVersionMajorMinor } from './plugin-utils.js';
11
+ import type { PrerenderConfigObject, PrerenderPathsConfig } from './types.js';
10
12
 
11
13
  export type BuildEndHook = {
12
14
  bivarianceHack(args: {
13
15
  buildManifest: ReactRouterBuildManifest | undefined;
14
16
  reactRouterConfig: ResolvedReactRouterConfig;
15
- viteConfig: NormalizedConfig;
17
+ rsbuildConfig: NormalizedConfig;
16
18
  }): void | Promise<void>;
17
19
  }['bivarianceHack'];
18
20
 
@@ -20,10 +22,15 @@ type SplitRouteModulesConfig = boolean | 'enforce';
20
22
 
21
23
  export type Config = Omit<
22
24
  ReactRouterConfig,
23
- 'buildEnd' | 'future' | 'splitRouteModules' | 'subResourceIntegrity'
25
+ | 'buildEnd'
26
+ | 'future'
27
+ | 'prerender'
28
+ | 'splitRouteModules'
29
+ | 'subResourceIntegrity'
24
30
  > & {
25
31
  buildEnd?: BuildEndHook;
26
32
  future?: Partial<FutureConfig>;
33
+ prerender?: PrerenderConfig;
27
34
  splitRouteModules?: SplitRouteModulesConfig;
28
35
  subResourceIntegrity?: boolean;
29
36
  };
@@ -37,6 +44,8 @@ type FutureConfig = {
37
44
  v8_viteEnvironmentApi: boolean;
38
45
  };
39
46
 
47
+ type PrerenderConfig = PrerenderPathsConfig | PrerenderConfigObject | undefined;
48
+
40
49
  type RouteManifestEntry = {
41
50
  id: string;
42
51
  parentId?: string;
@@ -50,10 +59,45 @@ type RouteManifest = Record<string, RouteManifestEntry>;
50
59
 
51
60
  type ResolveReactRouterConfigResult = {
52
61
  resolved: ResolvedReactRouterConfig;
62
+ userAndPresetConfig: Config;
53
63
  presets: NonNullable<Config['presets']>;
54
64
  hasConfiguredServerModuleFormat: boolean;
55
65
  };
56
66
 
67
+ export const getDefaultTrailingSlashAwareDataRequests = (
68
+ reactRouterVersion: string | undefined = getPackageVersion('react-router')
69
+ ): boolean => (parseVersionMajorMinor(reactRouterVersion)?.major ?? 0) >= 8;
70
+
71
+ export const resolveRouteDiscoveryConfig = ({
72
+ ssr,
73
+ userRouteDiscovery,
74
+ }: {
75
+ ssr: boolean;
76
+ userRouteDiscovery: Config['routeDiscovery'];
77
+ }): Config['routeDiscovery'] => {
78
+ if (!userRouteDiscovery) {
79
+ return ssr
80
+ ? ({ mode: 'lazy', manifestPath: '/__manifest' } as const)
81
+ : ({ mode: 'initial' } as const);
82
+ }
83
+ if (userRouteDiscovery.mode === 'initial') {
84
+ return userRouteDiscovery;
85
+ }
86
+
87
+ if (!ssr) {
88
+ throw new Error(
89
+ 'The `routeDiscovery.mode` config cannot be set to "lazy" when setting `ssr:false`'
90
+ );
91
+ }
92
+ const manifestPath = userRouteDiscovery.manifestPath;
93
+ if (manifestPath && !manifestPath.startsWith('/')) {
94
+ throw new Error(
95
+ 'The `routeDiscovery.manifestPath` config must be a root-relative pathname beginning with a slash (i.e., "/__manifest")'
96
+ );
97
+ }
98
+ return userRouteDiscovery;
99
+ };
100
+
57
101
  export type ResolvedReactRouterConfig = Readonly<{
58
102
  appDirectory: string;
59
103
  basename: string;
@@ -73,6 +117,16 @@ export type ResolvedReactRouterConfig = Readonly<{
73
117
  unstable_routeConfig: RouteConfigEntry[];
74
118
  }>;
75
119
 
120
+ const createDefaultFutureConfig = (): FutureConfig => ({
121
+ unstable_optimizeDeps: false,
122
+ unstable_subResourceIntegrity: false,
123
+ unstable_trailingSlashAwareDataRequests:
124
+ getDefaultTrailingSlashAwareDataRequests(),
125
+ v8_middleware: false,
126
+ v8_splitRouteModules: false,
127
+ v8_viteEnvironmentApi: false,
128
+ });
129
+
76
130
  const DEFAULT_CONFIG = {
77
131
  appDirectory: 'app',
78
132
  basename: '/',
@@ -82,14 +136,7 @@ const DEFAULT_CONFIG = {
82
136
  splitRouteModules: true,
83
137
  subResourceIntegrity: false,
84
138
  ssr: true,
85
- future: {
86
- unstable_optimizeDeps: false,
87
- unstable_subResourceIntegrity: false,
88
- unstable_trailingSlashAwareDataRequests: false,
89
- v8_middleware: false,
90
- v8_splitRouteModules: false,
91
- v8_viteEnvironmentApi: false,
92
- } satisfies FutureConfig,
139
+ future: createDefaultFutureConfig(),
93
140
  routeDiscovery: undefined,
94
141
  prerender: undefined,
95
142
  serverBundles: undefined,
@@ -111,15 +158,17 @@ const mergeReactRouterConfig = (...configs: Config[]): Config => {
111
158
  buildEnd: async (
112
159
  ...args: Parameters<NonNullable<Config['buildEnd']>>
113
160
  ) => {
114
- await runPluginEffect(
115
- Effect.all(
116
- [
117
- tryPluginPromise(() => configA.buildEnd?.(...args)),
118
- tryPluginPromise(() => configB.buildEnd?.(...args)),
119
- ],
120
- { discard: true }
121
- )
122
- );
161
+ let failure: Error | undefined;
162
+ for (const buildEnd of [configA.buildEnd, configB.buildEnd]) {
163
+ try {
164
+ await buildEnd?.(...args);
165
+ } catch (cause) {
166
+ failure ??= normalizeEffectError(cause);
167
+ }
168
+ }
169
+ if (failure) {
170
+ throw failure;
171
+ }
123
172
  },
124
173
  }
125
174
  : {}),
@@ -181,7 +230,8 @@ export const resolveReactRouterConfigEffect = (
181
230
  reactRouterUserConfig;
182
231
  const presetConfig = yield* tryPluginPromise(() =>
183
232
  preset.reactRouterConfig?.({
184
- reactRouterUserConfig: reactRouterUserConfigForPreset,
233
+ reactRouterUserConfig:
234
+ reactRouterUserConfigForPreset as ReactRouterConfig,
185
235
  })
186
236
  );
187
237
  if (!presetConfig) return null;
@@ -233,13 +283,9 @@ export const resolveReactRouterConfigEffect = (
233
283
 
234
284
  return {
235
285
  resolved,
286
+ userAndPresetConfig: userAndPresetConfigs,
236
287
  presets: reactRouterUserConfig.presets ?? [],
237
288
  hasConfiguredServerModuleFormat:
238
289
  userAndPresetConfigs.serverModuleFormat !== undefined,
239
290
  };
240
291
  });
241
-
242
- export const resolveReactRouterConfig = (
243
- reactRouterUserConfig: Config
244
- ): Promise<ResolveReactRouterConfigResult> =>
245
- runPluginEffect(resolveReactRouterConfigEffect(reactRouterUserConfig));
@@ -1,5 +1,4 @@
1
1
  import { basename } from 'pathe';
2
-
3
2
  import {
4
3
  CLIENT_EXPORTS,
5
4
  CLIENT_ROUTE_EXPORTS_SET,
@@ -12,6 +11,7 @@ import {
12
11
  detectRouteChunksIfEnabled,
13
12
  emptyRouteChunkSnippet,
14
13
  getRouteChunkIfEnabled,
14
+ getRouteChunkModuleId,
15
15
  getRouteChunkNameFromModuleId,
16
16
  shouldAnalyzeRouteChunks,
17
17
  validateRouteChunks,
@@ -50,9 +50,8 @@ type RouteChunkArtifact = {
50
50
  map: null;
51
51
  };
52
52
 
53
- // Exactly the route-manifest flags the client HMR runtime can patch in place
54
- // without a full reload. Array order defines the bit layout shared by the
55
- // encoder below and the decoder emitted in `generateDevHmrRuntimeModule`.
53
+ // Shared with the dev manifest differ: exactly the route flags the client HMR
54
+ // runtime can patch in place without a full reload.
56
55
  export const HMR_PATCHABLE_ROUTE_FLAGS = [
57
56
  'hasAction',
58
57
  'hasClientAction',
@@ -62,88 +61,104 @@ export const HMR_PATCHABLE_ROUTE_FLAGS = [
62
61
  'hasLoader',
63
62
  ] as const;
64
63
 
65
- const HMR_FLAG_EXPORT_NAME: Record<
64
+ type RouteHmrMetadata = Record<
66
65
  (typeof HMR_PATCHABLE_ROUTE_FLAGS)[number],
67
- string
68
- > = {
69
- hasAction: SERVER_EXPORTS.action,
70
- hasClientAction: CLIENT_EXPORTS.clientAction,
71
- hasClientLoader: CLIENT_EXPORTS.clientLoader,
72
- hasClientMiddleware: CLIENT_EXPORTS.clientMiddleware,
73
- hasErrorBoundary: CLIENT_EXPORTS.ErrorBoundary,
74
- hasLoader: SERVER_EXPORTS.loader,
75
- };
66
+ boolean
67
+ >;
76
68
 
77
- export const buildRouteHmrFlags = (exportNames: readonly string[]): number => {
69
+ export const buildRouteHmrMetadata = (
70
+ exportNames: readonly string[]
71
+ ): RouteHmrMetadata => {
78
72
  const exports = new Set(exportNames);
79
- let flags = 0;
80
- HMR_PATCHABLE_ROUTE_FLAGS.forEach((flag, index) => {
81
- if (exports.has(HMR_FLAG_EXPORT_NAME[flag])) flags |= 1 << index;
82
- });
83
- return flags;
73
+ return {
74
+ hasAction: exports.has(SERVER_EXPORTS.action),
75
+ hasClientAction: exports.has(CLIENT_EXPORTS.clientAction),
76
+ hasClientLoader: exports.has(CLIENT_EXPORTS.clientLoader),
77
+ hasClientMiddleware: exports.has(CLIENT_EXPORTS.clientMiddleware),
78
+ hasErrorBoundary: exports.has(CLIENT_EXPORTS.ErrorBoundary),
79
+ hasLoader: exports.has(SERVER_EXPORTS.loader),
80
+ };
84
81
  };
85
82
 
86
83
  /**
87
84
  * Development-only HMR glue for a web route client entry.
88
85
  *
89
86
  * The route client entry is the webpack entry for a route, so it must
90
- * self-accept hot updates to stop them from bubbling into a full reload. It
91
- * also accepts updates of the underlying route module and forwards fresh
92
- * exports plus route metadata (loader/action flags derived from the current
93
- * export names) to the shared HMR runtime, which applies the React Router
94
- * route-module update contract and revalidates loader data.
87
+ * self-accept hot updates to stop them from bubbling into a full reload. The
88
+ * route entry itself must re-run on updates so route metadata (loader/action
89
+ * flags derived from current export names) does not get stuck in an old accept
90
+ * callback while the underlying route module changes.
95
91
  */
96
92
  const buildRouteClientEntryHmrCode = ({
97
93
  routeId,
98
94
  target,
99
- acceptTarget,
100
- flags,
95
+ metadata,
101
96
  }: {
102
97
  routeId: string;
103
98
  target: string;
104
- acceptTarget: string;
105
- flags: number;
99
+ metadata: RouteHmrMetadata;
106
100
  }): string => {
107
101
  const targetJson = JSON.stringify(target);
108
- const acceptTargetJson = JSON.stringify(acceptTarget);
109
102
  return `
110
- import * as __rrm from ${targetJson};
103
+ import * as __reactRouterRouteModule from ${targetJson};
111
104
  import {
112
- registerReactRouterRouteExports as __rrr,
113
- scheduleReactRouterRouteUpdate as __rru,
105
+ registerReactRouterRouteExports as __reactRouterRegisterRouteExports,
106
+ scheduleReactRouterRouteUpdate as __reactRouterScheduleRouteUpdate,
114
107
  } from "virtual/react-router/hmr-runtime";
115
108
 
116
- const __rrid = ${JSON.stringify(routeId)};
117
- const __rrf = ${flags};
118
- const __rrg = () => __rrm;
119
- const __rru0 = () => {
120
- __rrr(__rrid, __rrm);
121
- __rru(__rrid, __rrf, __rrg);
122
- };
109
+ const __reactRouterRouteId = ${JSON.stringify(routeId)};
110
+ const __reactRouterRouteMetadata = ${JSON.stringify(metadata)};
111
+ const __reactRouterGetRouteModule = () => __reactRouterRouteModule;
123
112
 
124
- __rrr(__rrid, __rrm);
113
+ __reactRouterRegisterRouteExports(
114
+ __reactRouterRouteId,
115
+ __reactRouterRouteModule
116
+ );
125
117
 
126
118
  if (import.meta.webpackHot) {
127
- const __rrh = import.meta.webpackHot;
128
- __rrh.accept(${acceptTargetJson}, __rru0);
129
- __rrh.accept();
130
- __rrh.dispose(data => { data.__rr = true; });
131
- if (__rrh.data && __rrh.data.__rr) __rru0();
119
+ import.meta.webpackHot.accept();
120
+ import.meta.webpackHot.dispose(data => {
121
+ data.__reactRouterRouteShim = true;
122
+ });
123
+ if (
124
+ import.meta.webpackHot.data &&
125
+ import.meta.webpackHot.data.__reactRouterRouteShim
126
+ ) {
127
+ __reactRouterScheduleRouteUpdate(
128
+ __reactRouterRouteId,
129
+ __reactRouterRouteMetadata,
130
+ __reactRouterGetRouteModule
131
+ );
132
+ }
132
133
  }
133
134
  `;
134
135
  };
135
136
 
136
- // The accept target is spelled relative (`./name?react-router-route`) while
137
- // the import above uses the absolute resource path; both resolve to the same
138
- // module because the client entry replaces the route file in place, so its
139
- // resolution context is the route's own directory.
140
- const createRouteHmrAcceptTarget = (resourcePath: string): string => {
141
- return `./${basename(resourcePath)}?react-router-route`;
137
+ const shouldReexportFromRouteEntry = ({
138
+ chunkedExportSet,
139
+ exportName,
140
+ isServer,
141
+ }: {
142
+ chunkedExportSet?: ReadonlySet<string>;
143
+ exportName: string;
144
+ isServer: boolean;
145
+ }): boolean => {
146
+ if (chunkedExportSet?.has(exportName)) {
147
+ return false;
148
+ }
149
+ if (isServer) {
150
+ return (
151
+ CLIENT_ROUTE_EXPORTS_SET.has(exportName) ||
152
+ SERVER_ONLY_ROUTE_EXPORTS_SET.has(exportName)
153
+ );
154
+ }
155
+ return CLIENT_ROUTE_EXPORTS_SET.has(exportName);
142
156
  };
143
157
 
144
158
  export const buildRouteClientEntryCode = ({
145
159
  exportNames,
146
160
  chunkedExports,
161
+ sharedChunkedExports = [],
147
162
  isServer,
148
163
  resourcePath,
149
164
  routeId,
@@ -151,26 +166,40 @@ export const buildRouteClientEntryCode = ({
151
166
  }: {
152
167
  exportNames: readonly string[];
153
168
  chunkedExports: readonly string[];
169
+ sharedChunkedExports?: readonly string[];
154
170
  isServer: boolean;
155
171
  resourcePath: string;
156
172
  routeId?: string;
157
173
  devHmr?: boolean;
158
174
  }): string => {
159
175
  const chunkedExportSet =
160
- chunkedExports.length > 0 ? new Set<string>(chunkedExports) : undefined;
176
+ chunkedExports.length > 0 || sharedChunkedExports.length > 0
177
+ ? new Set<string>([...chunkedExports, ...sharedChunkedExports])
178
+ : undefined;
179
+ const routeRequestPath = `./${basename(resourcePath)}`;
180
+ const target = isServer
181
+ ? routeRequestPath
182
+ : chunkedExports.length > 0
183
+ ? getRouteChunkModuleId(routeRequestPath, 'main')
184
+ : `${routeRequestPath}?react-router-route`;
161
185
  const reexports = exportNames
162
- .filter(exp => {
163
- if (chunkedExportSet?.has(exp)) {
164
- return false;
165
- }
166
- return (
167
- CLIENT_ROUTE_EXPORTS_SET.has(exp) ||
168
- (isServer && SERVER_ONLY_ROUTE_EXPORTS_SET.has(exp))
169
- );
170
- })
186
+ .filter(exportName =>
187
+ shouldReexportFromRouteEntry({ chunkedExportSet, exportName, isServer })
188
+ )
171
189
  .sort();
172
- const target = `${resourcePath}?react-router-route`;
173
- const reexportCode = `export { ${reexports.join(', ')} } from ${JSON.stringify(target)};`;
190
+ const reexportCode = [
191
+ reexports.length > 0
192
+ ? `export { ${reexports.join(', ')} } from ${JSON.stringify(target)};`
193
+ : null,
194
+ ...sharedChunkedExports.map(
195
+ exportName =>
196
+ `export { ${exportName} } from ${JSON.stringify(
197
+ getRouteChunkModuleId(routeRequestPath, exportName)
198
+ )};`
199
+ ),
200
+ ]
201
+ .filter(Boolean)
202
+ .join('\n');
174
203
  if (!devHmr || isServer || routeId === undefined) {
175
204
  return reexportCode;
176
205
  }
@@ -179,8 +208,7 @@ export const buildRouteClientEntryCode = ({
179
208
  buildRouteClientEntryHmrCode({
180
209
  routeId,
181
210
  target,
182
- acceptTarget: createRouteHmrAcceptTarget(resourcePath),
183
- flags: buildRouteHmrFlags(exportNames),
211
+ metadata: buildRouteHmrMetadata(exportNames),
184
212
  })
185
213
  );
186
214
  };
@@ -211,10 +239,12 @@ export const createRouteClientEntryArtifact = async ({
211
239
  const exportNames =
212
240
  routeChunkInfo?.exportNames ?? (await getExportNames(code, resourcePath));
213
241
  const chunkedExports = routeChunkInfo?.chunkedExports ?? [];
242
+ const sharedChunkedExports = routeChunkInfo?.sharedChunkedExports ?? [];
214
243
  return {
215
244
  code: buildRouteClientEntryCode({
216
245
  exportNames,
217
246
  chunkedExports,
247
+ sharedChunkedExports,
218
248
  isServer,
219
249
  resourcePath,
220
250
  routeId,