rsbuild-plugin-react-router 0.5.0 → 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.
- package/README.md +58 -208
- package/dist/511.js +370 -331
- package/dist/build-output-transforms.d.ts +30 -6
- package/dist/classic-mode.d.ts +56 -0
- package/dist/config-imports.d.ts +8 -2
- package/dist/constants.d.ts +3 -0
- package/dist/dev-background-resources.d.ts +3 -1
- package/dist/dev-generation.d.ts +2 -3
- package/dist/dev-hmr.d.ts +8 -2
- package/dist/dev-runtime-controller.d.ts +6 -1
- package/dist/dev-source-maps.d.ts +4 -0
- package/dist/effect-runtime.d.ts +17 -5
- package/dist/entry-paths.d.ts +16 -0
- package/dist/environment-output.d.ts +6 -0
- package/dist/export-utils.d.ts +2 -1
- package/dist/index.cjs +3957 -2208
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3470 -1793
- package/dist/lazy-compilation-prewarm.d.ts +8 -5
- package/dist/manifest.d.ts +16 -4
- package/dist/mode-plan.d.ts +82 -0
- package/dist/modify-browser-manifest.d.ts +8 -4
- package/dist/plugin-utils.d.ts +27 -1
- package/dist/prerender-build.d.ts +5 -5
- package/dist/prerender.d.ts +1 -5
- package/dist/react-router-config.d.ts +11 -3
- package/dist/route-artifacts.d.ts +4 -2
- package/dist/route-chunks.d.ts +2 -1
- package/dist/route-component-transform.d.ts +0 -2
- package/dist/route-export-pruning.d.ts +4 -1
- package/dist/route-imports.d.ts +18 -0
- package/dist/route-transform-tasks.d.ts +5 -0
- package/dist/route-watch.d.ts +11 -6
- package/dist/rsc-dev-server.d.ts +26 -0
- package/dist/rsc-prerender.d.ts +54 -0
- package/dist/rsc-route-config.d.ts +6 -0
- package/dist/rsc-route-exports.d.ts +15 -0
- package/dist/rsc-route-transform-loader.cjs +43 -0
- package/dist/rsc-route-transform-loader.d.ts +30 -0
- package/dist/rsc-route-transform-loader.js +16 -0
- package/dist/rsc-route-transform-registration.d.ts +12 -0
- package/dist/rsc-route-transforms.d.ts +21 -0
- package/dist/rsc-support.d.ts +23 -0
- package/dist/rsc-virtual-modules.d.ts +19 -0
- package/dist/server-build-plan.d.ts +2 -1
- package/dist/server-build-resolution.d.ts +1 -2
- package/dist/server-utils.d.ts +4 -5
- package/dist/ssr-asset-relocation.d.ts +98 -0
- package/dist/templates/entry.rsc.client.d.ts +1 -0
- package/dist/templates/entry.rsc.client.js +61 -0
- package/dist/templates/entry.rsc.d.ts +9 -0
- package/dist/templates/entry.rsc.js +38 -0
- package/dist/templates/entry.rsc.ssr.d.ts +4 -0
- package/dist/templates/entry.rsc.ssr.js +24 -0
- package/dist/typegen.d.ts +4 -2
- package/dist/types.d.ts +30 -1
- package/package.json +69 -14
- package/src/build-output-transforms.ts +155 -21
- package/src/classic-mode.ts +253 -0
- package/src/config-imports.ts +153 -6
- package/src/constants.ts +6 -2
- package/src/dev-background-resources.ts +46 -85
- package/src/dev-generation.ts +52 -33
- package/src/dev-hmr.ts +112 -80
- package/src/dev-runtime-artifacts.ts +11 -12
- package/src/dev-runtime-controller.ts +75 -85
- package/src/dev-runtime-session.ts +14 -18
- package/src/dev-server.ts +2 -0
- package/src/dev-source-maps.ts +257 -0
- package/src/effect-runtime.ts +105 -57
- package/src/entry-paths.ts +80 -0
- package/src/environment-output.ts +55 -0
- package/src/export-utils.ts +15 -11
- package/src/index.ts +661 -496
- package/src/lazy-compilation-prewarm.ts +20 -4
- package/src/manifest.ts +157 -82
- package/src/mode-plan.ts +367 -0
- package/src/modify-browser-manifest.ts +130 -124
- package/src/plugin-utils.ts +103 -39
- package/src/prerender-build.ts +82 -104
- package/src/prerender.ts +23 -24
- package/src/react-router-config.ts +72 -26
- package/src/route-artifacts.ts +96 -66
- package/src/route-chunks.ts +167 -51
- package/src/route-component-transform.ts +14 -21
- package/src/route-export-pruning.ts +4 -3
- package/src/route-imports.ts +100 -0
- package/src/route-transform-tasks.ts +39 -25
- package/src/route-watch.ts +166 -188
- package/src/rsc-dev-server.ts +112 -0
- package/src/rsc-prerender.ts +362 -0
- package/src/rsc-route-config.ts +175 -0
- package/src/rsc-route-exports.ts +67 -0
- package/src/rsc-route-transform-loader.ts +65 -0
- package/src/rsc-route-transform-registration.ts +145 -0
- package/src/rsc-route-transforms.ts +995 -0
- package/src/rsc-runtime.d.ts +143 -0
- package/src/rsc-support.ts +116 -0
- package/src/rsc-virtual-modules.ts +113 -0
- package/src/server-build-plan.ts +14 -3
- package/src/server-build-resolution.ts +37 -47
- package/src/server-utils.ts +21 -35
- package/src/ssr-asset-relocation.ts +183 -0
- package/src/ssr-externals.ts +8 -26
- package/src/templates/entry.rsc.client.tsx +168 -0
- package/src/templates/entry.rsc.ssr.tsx +45 -0
- package/src/templates/entry.rsc.tsx +80 -0
- package/src/typegen.ts +40 -23
- package/src/types.ts +39 -1
- package/src/warnings/warn-on-client-source-maps.ts +6 -10
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import * as Effect from 'effect/Effect';
|
|
2
|
+
import type * as Scope from 'effect/Scope';
|
|
2
3
|
import type { ReactRouterManifestForDev } from './manifest.js';
|
|
3
4
|
import type { RouteManifestItem } from './types.js';
|
|
4
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
createDelayedPluginTask,
|
|
7
|
+
type PluginEffectRuntime,
|
|
8
|
+
tryPluginPromise,
|
|
9
|
+
} from './effect-runtime.js';
|
|
5
10
|
|
|
6
11
|
const DEFAULT_LAZY_COMPILATION_TRIGGER_PREFIX = '/_rspack/lazy/trigger';
|
|
7
12
|
const DEFAULT_PREWARM_DELAY_MS = 0;
|
|
@@ -9,17 +14,17 @@ const DEFAULT_ROUTE_PREWARM_LIMIT = 8;
|
|
|
9
14
|
const PREWARM_FETCH_CONCURRENCY = 8;
|
|
10
15
|
const PREWARM_TRIGGER_CANDIDATES = 4;
|
|
11
16
|
|
|
12
|
-
type LazyCompilationPrewarmConfig = {
|
|
17
|
+
export type LazyCompilationPrewarmConfig = {
|
|
13
18
|
entry: boolean;
|
|
14
19
|
routeLimit: number;
|
|
15
20
|
delayMs: number;
|
|
16
21
|
};
|
|
17
22
|
|
|
18
|
-
type LazyCompilationPrewarmController = {
|
|
23
|
+
export type LazyCompilationPrewarmController = {
|
|
19
24
|
setServerOrigin(origin: string): void;
|
|
20
25
|
setManifest(manifest: ReactRouterManifestForDev | null): void;
|
|
21
26
|
schedule(): void;
|
|
22
|
-
cancelEffect(): Effect.Effect<void
|
|
27
|
+
cancelEffect(): Effect.Effect<void>;
|
|
23
28
|
};
|
|
24
29
|
|
|
25
30
|
export type RspackLazyCompilationTriggerClient = {
|
|
@@ -221,9 +226,11 @@ const prewarmLazyCompilation = ({
|
|
|
221
226
|
});
|
|
222
227
|
|
|
223
228
|
export const createLazyCompilationPrewarmController = ({
|
|
229
|
+
runtime,
|
|
224
230
|
config,
|
|
225
231
|
onError,
|
|
226
232
|
}: {
|
|
233
|
+
runtime: PluginEffectRuntime;
|
|
227
234
|
config: LazyCompilationPrewarmConfig;
|
|
228
235
|
onError: (error: Error) => void;
|
|
229
236
|
}): LazyCompilationPrewarmController => {
|
|
@@ -231,6 +238,7 @@ export const createLazyCompilationPrewarmController = ({
|
|
|
231
238
|
let manifest: ReactRouterManifestForDev | null = null;
|
|
232
239
|
let lastPrewarmAssetsKey: string | undefined;
|
|
233
240
|
const task = createDelayedPluginTask({
|
|
241
|
+
runtime,
|
|
234
242
|
delayMs: config.delayMs,
|
|
235
243
|
run: () =>
|
|
236
244
|
Effect.gen(function* () {
|
|
@@ -277,3 +285,11 @@ export const createLazyCompilationPrewarmController = ({
|
|
|
277
285
|
},
|
|
278
286
|
};
|
|
279
287
|
};
|
|
288
|
+
|
|
289
|
+
export const acquireLazyCompilationPrewarm = (
|
|
290
|
+
options: Parameters<typeof createLazyCompilationPrewarmController>[0]
|
|
291
|
+
): Effect.Effect<LazyCompilationPrewarmController, never, Scope.Scope> =>
|
|
292
|
+
Effect.acquireRelease(
|
|
293
|
+
Effect.sync(() => createLazyCompilationPrewarmController(options)),
|
|
294
|
+
controller => controller.cancelEffect()
|
|
295
|
+
);
|
package/src/manifest.ts
CHANGED
|
@@ -3,7 +3,11 @@ import { dirname, isAbsolute, relative, resolve } from 'pathe';
|
|
|
3
3
|
import * as Effect from 'effect/Effect';
|
|
4
4
|
import type { Route, PluginOptions, RouteManifestItem } from './types.js';
|
|
5
5
|
import { combineURLs, createRouteId } from './plugin-utils.js';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
CLIENT_EXPORTS,
|
|
8
|
+
DEFAULT_JS_DIST_PATH,
|
|
9
|
+
SERVER_EXPORTS,
|
|
10
|
+
} from './constants.js';
|
|
7
11
|
import {
|
|
8
12
|
buildManifestChunkValidity,
|
|
9
13
|
createEmptyRouteChunkByExportName,
|
|
@@ -13,8 +17,12 @@ import {
|
|
|
13
17
|
validateRouteChunks,
|
|
14
18
|
type RouteChunkCache,
|
|
15
19
|
type RouteChunkConfig,
|
|
20
|
+
type RouteChunkExportName,
|
|
16
21
|
} from './route-chunks.js';
|
|
17
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
getRouteModuleAnalysis,
|
|
24
|
+
type RouteModuleAnalysis,
|
|
25
|
+
} from './export-utils.js';
|
|
18
26
|
import { getCappedPluginConcurrency } from './concurrency.js';
|
|
19
27
|
import { runPluginEffect, tryPluginPromise } from './effect-runtime.js';
|
|
20
28
|
|
|
@@ -87,13 +95,38 @@ export function configRoutesToRouteManifestEntries(
|
|
|
87
95
|
return routeManifestEntries;
|
|
88
96
|
}
|
|
89
97
|
|
|
90
|
-
type RouteChunkManifestOptions = {
|
|
98
|
+
export type RouteChunkManifestOptions = {
|
|
91
99
|
splitRouteModules?: boolean | 'enforce';
|
|
92
100
|
rootRouteFile?: string;
|
|
93
101
|
isBuild?: boolean;
|
|
94
102
|
cache?: RouteChunkCache;
|
|
95
103
|
};
|
|
96
104
|
|
|
105
|
+
export type RouteModuleAnalysisProvider = (
|
|
106
|
+
routeFilePath: string,
|
|
107
|
+
route: Route
|
|
108
|
+
) => Promise<RouteModuleAnalysis | undefined>;
|
|
109
|
+
|
|
110
|
+
export type ReactRouterManifestOptions = RouteChunkManifestOptions & {
|
|
111
|
+
routeModuleAnalysis?: RouteModuleAnalysisProvider;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export const createReactRouterManifestOptions = ({
|
|
115
|
+
routeChunks,
|
|
116
|
+
routeModuleAnalysis,
|
|
117
|
+
}: {
|
|
118
|
+
routeChunks?: RouteChunkManifestOptions;
|
|
119
|
+
routeModuleAnalysis?: RouteModuleAnalysisProvider;
|
|
120
|
+
}): ReactRouterManifestOptions | undefined => {
|
|
121
|
+
if (!routeChunks && !routeModuleAnalysis) {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
...routeChunks,
|
|
126
|
+
...(routeModuleAnalysis ? { routeModuleAnalysis } : {}),
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
|
|
97
130
|
export type ReactRouterManifestForDev = {
|
|
98
131
|
version: string;
|
|
99
132
|
url: string;
|
|
@@ -122,8 +155,10 @@ type ReactRouterManifestStatsEntrypoint = {
|
|
|
122
155
|
getFiles?: () => Iterable<string>;
|
|
123
156
|
};
|
|
124
157
|
|
|
125
|
-
type ReactRouterManifestStatsLookup<T> = Iterable<
|
|
126
|
-
|
|
158
|
+
type ReactRouterManifestStatsLookup<T> = Iterable<
|
|
159
|
+
[string, T | null | undefined]
|
|
160
|
+
> & {
|
|
161
|
+
get?: (name: string) => T | null | undefined;
|
|
127
162
|
};
|
|
128
163
|
|
|
129
164
|
type ReactRouterManifestStatsCompilation = {
|
|
@@ -153,6 +188,9 @@ const collectManifestFilesByName = <T>(
|
|
|
153
188
|
const filesByName: Record<string, string[]> = {};
|
|
154
189
|
if (!names) {
|
|
155
190
|
for (const [name, item] of items) {
|
|
191
|
+
if (item == null) {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
156
194
|
filesByName[name] = getFiles(name, item);
|
|
157
195
|
}
|
|
158
196
|
return filesByName;
|
|
@@ -162,7 +200,7 @@ const collectManifestFilesByName = <T>(
|
|
|
162
200
|
if (typeof items.get === 'function') {
|
|
163
201
|
for (const name of names) {
|
|
164
202
|
const item = items.get(name);
|
|
165
|
-
if (
|
|
203
|
+
if (item == null) {
|
|
166
204
|
continue;
|
|
167
205
|
}
|
|
168
206
|
filesByName[name] = getFiles(name, item);
|
|
@@ -178,6 +216,9 @@ const collectManifestFilesByName = <T>(
|
|
|
178
216
|
if (!missingNames.has(name)) {
|
|
179
217
|
continue;
|
|
180
218
|
}
|
|
219
|
+
if (item == null) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
181
222
|
filesByName[name] = getFiles(name, item);
|
|
182
223
|
missingNames.delete(name);
|
|
183
224
|
if (missingNames.size === 0) {
|
|
@@ -236,11 +277,12 @@ type RouteManifestAnalysis = {
|
|
|
236
277
|
> | null;
|
|
237
278
|
};
|
|
238
279
|
|
|
239
|
-
const DEFAULT_MANIFEST_DIR =
|
|
280
|
+
const DEFAULT_MANIFEST_DIR = DEFAULT_JS_DIST_PATH;
|
|
240
281
|
const CSS_IMPORT_RE = /\.(?:css|less|sass|scss)(?:\?[^'"`]+)?['"`]/;
|
|
241
282
|
|
|
242
283
|
const createChunkAssetResolver = (
|
|
243
|
-
clientStats: ReactRouterManifestStats | undefined
|
|
284
|
+
clientStats: ReactRouterManifestStats | undefined,
|
|
285
|
+
includeEntrypointJs: boolean
|
|
244
286
|
): ((chunkName: string) => ChunkAssets) => {
|
|
245
287
|
const chunkAssetsByName = new Map<string, ChunkAssets>();
|
|
246
288
|
|
|
@@ -259,24 +301,26 @@ const createChunkAssetResolver = (
|
|
|
259
301
|
}
|
|
260
302
|
|
|
261
303
|
const cssAssets = new Set<string>();
|
|
262
|
-
const jsAssets
|
|
304
|
+
const jsAssets = new Set<string>();
|
|
263
305
|
for (const asset of assets) {
|
|
264
306
|
if (asset.endsWith('.css')) {
|
|
265
307
|
cssAssets.add(asset);
|
|
266
308
|
} else if (asset.endsWith('.js')) {
|
|
267
|
-
jsAssets.
|
|
309
|
+
jsAssets.add(asset);
|
|
268
310
|
}
|
|
269
311
|
}
|
|
270
312
|
for (const asset of clientStats?.entrypointFilesByName?.[chunkName] ?? []) {
|
|
271
313
|
if (asset.endsWith('.css')) {
|
|
272
314
|
cssAssets.add(asset);
|
|
315
|
+
} else if (includeEntrypointJs && asset.endsWith('.js')) {
|
|
316
|
+
jsAssets.add(asset);
|
|
273
317
|
}
|
|
274
318
|
}
|
|
275
|
-
if (jsAssets.
|
|
276
|
-
jsAssets.
|
|
319
|
+
if (jsAssets.size === 0) {
|
|
320
|
+
jsAssets.add(`${DEFAULT_MANIFEST_DIR}/${chunkName}.js`);
|
|
277
321
|
}
|
|
278
322
|
|
|
279
|
-
const result = { js: jsAssets, css: [...cssAssets] };
|
|
323
|
+
const result = { js: [...jsAssets], css: [...cssAssets] };
|
|
280
324
|
chunkAssetsByName.set(chunkName, result);
|
|
281
325
|
return result;
|
|
282
326
|
};
|
|
@@ -289,6 +333,8 @@ const analyzeRouteForManifestEffect = ({
|
|
|
289
333
|
routeChunkConfig,
|
|
290
334
|
routeEntryName,
|
|
291
335
|
routeFilePath,
|
|
336
|
+
route,
|
|
337
|
+
routeModuleAnalysis,
|
|
292
338
|
}: {
|
|
293
339
|
discoveredCssAssets: string[];
|
|
294
340
|
isBuild: boolean;
|
|
@@ -296,10 +342,13 @@ const analyzeRouteForManifestEffect = ({
|
|
|
296
342
|
routeChunkConfig: RouteChunkConfig | null;
|
|
297
343
|
routeEntryName: string;
|
|
298
344
|
routeFilePath: string;
|
|
345
|
+
route: Route;
|
|
346
|
+
routeModuleAnalysis?: RouteModuleAnalysisProvider;
|
|
299
347
|
}): Effect.Effect<RouteManifestAnalysis, Error, never> =>
|
|
300
348
|
tryPluginPromise(async () => {
|
|
301
349
|
const { code, exports: exportNames } =
|
|
302
|
-
await
|
|
350
|
+
(await routeModuleAnalysis?.(routeFilePath, route)) ??
|
|
351
|
+
(await getRouteModuleAnalysis(routeFilePath));
|
|
303
352
|
const cssAssets =
|
|
304
353
|
!isBuild && discoveredCssAssets.length === 0 && CSS_IMPORT_RE.test(code)
|
|
305
354
|
? [
|
|
@@ -398,33 +447,94 @@ export const getReactRouterManifestChunkNames = (
|
|
|
398
447
|
return chunkNames;
|
|
399
448
|
};
|
|
400
449
|
|
|
450
|
+
const createRouteManifestItem = ({
|
|
451
|
+
route,
|
|
452
|
+
assetPrefix,
|
|
453
|
+
jsAssets,
|
|
454
|
+
routeAnalysis,
|
|
455
|
+
getModulePathForChunk,
|
|
456
|
+
getCssAssetsForChunk,
|
|
457
|
+
}: {
|
|
458
|
+
route: Route;
|
|
459
|
+
assetPrefix: string;
|
|
460
|
+
jsAssets: string[];
|
|
461
|
+
routeAnalysis: RouteManifestAnalysis;
|
|
462
|
+
getModulePathForChunk: (chunkName: string) => string | undefined;
|
|
463
|
+
getCssAssetsForChunk: (chunkName: string) => string[];
|
|
464
|
+
}): RouteManifestItem => {
|
|
465
|
+
const routeChunkMap = routeAnalysis.hasRouteChunkByExportName;
|
|
466
|
+
const chunkModulePath = (exportName: RouteChunkExportName) =>
|
|
467
|
+
routeChunkMap?.[exportName]
|
|
468
|
+
? getModulePathForChunk(getRouteChunkEntryName(route.id, exportName))
|
|
469
|
+
: undefined;
|
|
470
|
+
const cssAssets = [
|
|
471
|
+
...routeAnalysis.cssAssets,
|
|
472
|
+
...routeChunkExportNames.flatMap(exportName =>
|
|
473
|
+
routeChunkMap?.[exportName]
|
|
474
|
+
? getCssAssetsForChunk(getRouteChunkEntryName(route.id, exportName))
|
|
475
|
+
: []
|
|
476
|
+
),
|
|
477
|
+
];
|
|
478
|
+
|
|
479
|
+
return {
|
|
480
|
+
id: route.id,
|
|
481
|
+
parentId: route.parentId,
|
|
482
|
+
path: route.path,
|
|
483
|
+
index: route.index,
|
|
484
|
+
caseSensitive: route.caseSensitive,
|
|
485
|
+
module: combineURLs(assetPrefix, jsAssets[0] || ''),
|
|
486
|
+
clientActionModule: chunkModulePath('clientAction'),
|
|
487
|
+
clientLoaderModule: chunkModulePath('clientLoader'),
|
|
488
|
+
clientMiddlewareModule: chunkModulePath('clientMiddleware'),
|
|
489
|
+
hydrateFallbackModule: chunkModulePath('HydrateFallback'),
|
|
490
|
+
hasAction: routeAnalysis.exports.has(SERVER_EXPORTS.action),
|
|
491
|
+
hasLoader: routeAnalysis.exports.has(SERVER_EXPORTS.loader),
|
|
492
|
+
hasClientAction: routeAnalysis.exports.has(CLIENT_EXPORTS.clientAction),
|
|
493
|
+
hasClientLoader: routeAnalysis.exports.has(CLIENT_EXPORTS.clientLoader),
|
|
494
|
+
hasClientMiddleware: routeAnalysis.exports.has(
|
|
495
|
+
CLIENT_EXPORTS.clientMiddleware
|
|
496
|
+
),
|
|
497
|
+
hasDefaultExport: routeAnalysis.exports.has('default'),
|
|
498
|
+
hasErrorBoundary: routeAnalysis.exports.has(CLIENT_EXPORTS.ErrorBoundary),
|
|
499
|
+
// `module` is `jsAssets[0]`; exclude it from `imports` so the browser
|
|
500
|
+
// manifest does not list the route's own module twice (upstream excludes
|
|
501
|
+
// the entry chunk's own file from its imports list). Otherwise prefetch
|
|
502
|
+
// link computations produce duplicate modulepreload hrefs.
|
|
503
|
+
imports: jsAssets.slice(1).map(asset => combineURLs(assetPrefix, asset)),
|
|
504
|
+
css: Array.from(new Set(cssAssets)).map(asset =>
|
|
505
|
+
combineURLs(assetPrefix, asset)
|
|
506
|
+
),
|
|
507
|
+
};
|
|
508
|
+
};
|
|
509
|
+
|
|
401
510
|
function generateReactRouterManifestForDevEffect(
|
|
402
511
|
routes: Record<string, Route>,
|
|
403
|
-
_options: PluginOptions,
|
|
404
512
|
clientStats: ReactRouterManifestStats | undefined,
|
|
405
513
|
context: string,
|
|
406
514
|
assetPrefix: string,
|
|
407
|
-
|
|
515
|
+
manifestOptions?: ReactRouterManifestOptions
|
|
408
516
|
): Effect.Effect<ReactRouterManifestGenerationResult, Error, never> {
|
|
409
517
|
return Effect.gen(function* () {
|
|
410
518
|
const result: Record<string, RouteManifestItem> = {};
|
|
411
|
-
const splitRouteModules =
|
|
519
|
+
const splitRouteModules = manifestOptions?.splitRouteModules ?? false;
|
|
412
520
|
const enforceSplitRouteModules = splitRouteModules === 'enforce';
|
|
413
|
-
const isBuild =
|
|
521
|
+
const isBuild = manifestOptions?.isBuild ?? false;
|
|
414
522
|
const routeChunkConfig: RouteChunkConfig | null =
|
|
415
|
-
splitRouteModules &&
|
|
523
|
+
splitRouteModules && manifestOptions?.rootRouteFile
|
|
416
524
|
? {
|
|
417
525
|
splitRouteModules,
|
|
418
526
|
appDirectory: context,
|
|
419
|
-
rootRouteFile:
|
|
527
|
+
rootRouteFile: manifestOptions.rootRouteFile,
|
|
420
528
|
}
|
|
421
529
|
: null;
|
|
422
530
|
|
|
423
|
-
const getAssetsForChunk = createChunkAssetResolver(clientStats);
|
|
531
|
+
const getAssetsForChunk = createChunkAssetResolver(clientStats, isBuild);
|
|
424
532
|
const getModulePathForChunk = (chunkName: string): string | undefined => {
|
|
425
533
|
const { js: jsAssets } = getAssetsForChunk(chunkName);
|
|
426
534
|
return jsAssets[0] ? combineURLs(assetPrefix, jsAssets[0]) : undefined;
|
|
427
535
|
};
|
|
536
|
+
const getCssAssetsForChunk = (chunkName: string): string[] =>
|
|
537
|
+
getAssetsForChunk(chunkName).css;
|
|
428
538
|
|
|
429
539
|
const manifestEntries = yield* Effect.forEach(
|
|
430
540
|
Object.entries(routes),
|
|
@@ -437,78 +547,36 @@ function generateReactRouterManifestForDevEffect(
|
|
|
437
547
|
const routeAnalysis = yield* analyzeRouteForManifestEffect({
|
|
438
548
|
discoveredCssAssets,
|
|
439
549
|
isBuild,
|
|
440
|
-
routeChunkCache:
|
|
550
|
+
routeChunkCache: manifestOptions?.cache,
|
|
441
551
|
routeChunkConfig,
|
|
442
552
|
routeEntryName,
|
|
443
553
|
routeFilePath,
|
|
554
|
+
route,
|
|
555
|
+
routeModuleAnalysis: manifestOptions?.routeModuleAnalysis,
|
|
444
556
|
});
|
|
445
557
|
|
|
446
|
-
const hasClientAction = routeAnalysis.exports.has(
|
|
447
|
-
CLIENT_EXPORTS.clientAction
|
|
448
|
-
);
|
|
449
|
-
const hasClientLoader = routeAnalysis.exports.has(
|
|
450
|
-
CLIENT_EXPORTS.clientLoader
|
|
451
|
-
);
|
|
452
|
-
const hasClientMiddleware = routeAnalysis.exports.has(
|
|
453
|
-
CLIENT_EXPORTS.clientMiddleware
|
|
454
|
-
);
|
|
455
|
-
const hasDefaultExport = routeAnalysis.exports.has('default');
|
|
456
|
-
const routeChunkMap = routeAnalysis.hasRouteChunkByExportName;
|
|
457
|
-
|
|
458
558
|
if (isBuild && enforceSplitRouteModules && routeChunkConfig) {
|
|
459
559
|
validateRouteChunks({
|
|
460
560
|
config: routeChunkConfig,
|
|
461
561
|
id: routeFilePath,
|
|
462
562
|
valid: buildManifestChunkValidity(
|
|
463
563
|
routeAnalysis.exports,
|
|
464
|
-
|
|
564
|
+
routeAnalysis.hasRouteChunkByExportName ??
|
|
565
|
+
createEmptyRouteChunkByExportName()
|
|
465
566
|
),
|
|
466
567
|
});
|
|
467
568
|
}
|
|
468
569
|
|
|
469
570
|
return [
|
|
470
571
|
key,
|
|
471
|
-
{
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
? getModulePathForChunk(
|
|
480
|
-
getRouteChunkEntryName(route.id, 'clientAction')
|
|
481
|
-
)
|
|
482
|
-
: undefined,
|
|
483
|
-
clientLoaderModule: routeChunkMap?.clientLoader
|
|
484
|
-
? getModulePathForChunk(
|
|
485
|
-
getRouteChunkEntryName(route.id, 'clientLoader')
|
|
486
|
-
)
|
|
487
|
-
: undefined,
|
|
488
|
-
clientMiddlewareModule: routeChunkMap?.clientMiddleware
|
|
489
|
-
? getModulePathForChunk(
|
|
490
|
-
getRouteChunkEntryName(route.id, 'clientMiddleware')
|
|
491
|
-
)
|
|
492
|
-
: undefined,
|
|
493
|
-
hydrateFallbackModule: routeChunkMap?.HydrateFallback
|
|
494
|
-
? getModulePathForChunk(
|
|
495
|
-
getRouteChunkEntryName(route.id, 'HydrateFallback')
|
|
496
|
-
)
|
|
497
|
-
: undefined,
|
|
498
|
-
hasAction: routeAnalysis.exports.has(SERVER_EXPORTS.action),
|
|
499
|
-
hasLoader: routeAnalysis.exports.has(SERVER_EXPORTS.loader),
|
|
500
|
-
hasClientAction,
|
|
501
|
-
hasClientLoader,
|
|
502
|
-
hasClientMiddleware,
|
|
503
|
-
hasDefaultExport,
|
|
504
|
-
hasErrorBoundary: routeAnalysis.exports.has(
|
|
505
|
-
CLIENT_EXPORTS.ErrorBoundary
|
|
506
|
-
),
|
|
507
|
-
imports: jsAssets.map(asset => combineURLs(assetPrefix, asset)),
|
|
508
|
-
css: routeAnalysis.cssAssets.map(asset =>
|
|
509
|
-
combineURLs(assetPrefix, asset)
|
|
510
|
-
),
|
|
511
|
-
},
|
|
572
|
+
createRouteManifestItem({
|
|
573
|
+
route,
|
|
574
|
+
assetPrefix,
|
|
575
|
+
jsAssets,
|
|
576
|
+
routeAnalysis,
|
|
577
|
+
getModulePathForChunk,
|
|
578
|
+
getCssAssetsForChunk,
|
|
579
|
+
}),
|
|
512
580
|
routeAnalysis.routeModuleExports,
|
|
513
581
|
] as const;
|
|
514
582
|
}),
|
|
@@ -536,7 +604,12 @@ function generateReactRouterManifestForDevEffect(
|
|
|
536
604
|
const fingerprintedValues = {
|
|
537
605
|
entry: {
|
|
538
606
|
module: combineURLs(assetPrefix, entryJsAssets[0] || ''),
|
|
539
|
-
|
|
607
|
+
// Exclude the entry's own module (`entryJsAssets[0]`) from imports so it
|
|
608
|
+
// is not listed twice, matching upstream where `imports` holds only the
|
|
609
|
+
// chunk's dependency imports.
|
|
610
|
+
imports: entryJsAssets
|
|
611
|
+
.slice(1)
|
|
612
|
+
.map(asset => combineURLs(assetPrefix, asset)),
|
|
540
613
|
css: entryCssAssets.map(asset => combineURLs(assetPrefix, asset)),
|
|
541
614
|
},
|
|
542
615
|
routes: result,
|
|
@@ -550,7 +623,10 @@ function generateReactRouterManifestForDevEffect(
|
|
|
550
623
|
|
|
551
624
|
const manifest = {
|
|
552
625
|
version,
|
|
553
|
-
url: combineURLs(
|
|
626
|
+
url: combineURLs(
|
|
627
|
+
assetPrefix,
|
|
628
|
+
isBuild ? manifestPath : `${manifestPath}?v=${version}`
|
|
629
|
+
),
|
|
554
630
|
hmr: undefined,
|
|
555
631
|
entry: fingerprintedValues.entry,
|
|
556
632
|
sri: undefined,
|
|
@@ -566,20 +642,19 @@ function generateReactRouterManifestForDevEffect(
|
|
|
566
642
|
|
|
567
643
|
export async function generateReactRouterManifestForDev(
|
|
568
644
|
routes: Record<string, Route>,
|
|
569
|
-
|
|
645
|
+
_options: PluginOptions,
|
|
570
646
|
clientStats: ReactRouterManifestStats | undefined,
|
|
571
647
|
context: string,
|
|
572
648
|
assetPrefix = '/',
|
|
573
|
-
|
|
649
|
+
manifestOptions?: ReactRouterManifestOptions
|
|
574
650
|
): Promise<ReactRouterManifestGenerationResult> {
|
|
575
651
|
return runPluginEffect(
|
|
576
652
|
generateReactRouterManifestForDevEffect(
|
|
577
653
|
routes,
|
|
578
|
-
options,
|
|
579
654
|
clientStats,
|
|
580
655
|
context,
|
|
581
656
|
assetPrefix,
|
|
582
|
-
|
|
657
|
+
manifestOptions
|
|
583
658
|
)
|
|
584
659
|
);
|
|
585
660
|
}
|