rsbuild-plugin-react-router 0.1.1 → 0.3.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 +185 -204
- package/dist/451.js +1087 -0
- package/dist/bounded-cache.d.ts +1 -0
- package/dist/build-manifest.d.ts +1 -1
- package/dist/build-output-transforms.d.ts +30 -0
- package/dist/concurrency.d.ts +2 -0
- package/dist/config-imports.d.ts +3 -0
- package/dist/constants.d.ts +3 -0
- package/dist/dev-generation.d.ts +25 -0
- package/dist/dev-runtime-artifacts.d.ts +39 -0
- package/dist/dev-runtime-compilation.d.ts +32 -0
- package/dist/dev-runtime-controller.d.ts +14 -0
- package/dist/dev-runtime-session.d.ts +34 -0
- package/dist/dev-server.d.ts +11 -2
- package/dist/export-utils.d.ts +15 -7
- package/dist/index.cjs +3085 -1272
- package/dist/index.d.ts +4 -1
- package/dist/index.js +2039 -1299
- package/dist/lazy-compilation.d.ts +5 -0
- package/dist/manifest.d.ts +32 -9
- package/dist/modify-browser-manifest.d.ts +30 -13
- package/dist/parallel-route-transform-protocol.d.ts +25 -0
- package/dist/parallel-route-transform-worker.d.ts +1 -0
- package/dist/parallel-route-transform-worker.js +38 -0
- package/dist/parallel-route-transforms.d.ts +14 -0
- package/dist/performance.d.ts +26 -0
- package/dist/plugin-utils.d.ts +2 -12
- package/dist/prerender-build.d.ts +32 -0
- package/dist/prerender.d.ts +28 -2
- package/dist/react-router-config.d.ts +8 -1
- package/dist/route-artifacts.d.ts +33 -0
- package/dist/route-ast.d.ts +21 -0
- package/dist/route-chunks.d.ts +9 -1
- package/dist/route-component-transform.d.ts +5 -0
- package/dist/route-export-pruning.d.ts +6 -0
- package/dist/route-export-resolution.d.ts +5 -0
- package/dist/route-transform-tasks.d.ts +47 -0
- package/dist/route-watch.d.ts +27 -0
- package/dist/server-build-plan.d.ts +22 -0
- package/dist/server-utils.d.ts +3 -2
- package/dist/templates/entry.client.js +3 -3
- package/dist/templates/entry.server.cjs +11 -8
- package/dist/templates/entry.server.js +5 -5
- package/dist/typegen.d.ts +2 -0
- package/dist/types.d.ts +30 -12
- package/dist/virtual-modules.d.ts +2 -0
- package/dist/warnings/warn-on-client-source-maps.d.ts +1 -0
- package/dist/yuku.d.ts +15 -0
- package/package.json +26 -22
- package/src/bounded-cache.ts +18 -0
- package/src/build-manifest.ts +168 -0
- package/src/build-output-transforms.ts +273 -0
- package/src/concurrency.ts +34 -0
- package/src/config-imports.ts +45 -0
- package/src/constants.ts +91 -0
- package/src/dev-generation.ts +700 -0
- package/src/dev-runtime-artifacts.ts +207 -0
- package/src/dev-runtime-compilation.ts +92 -0
- package/src/dev-runtime-controller.ts +462 -0
- package/src/dev-runtime-session.ts +184 -0
- package/src/dev-server.ts +58 -0
- package/src/export-utils.ts +219 -0
- package/src/index.ts +1025 -0
- package/src/lazy-compilation.ts +94 -0
- package/src/manifest.ts +480 -0
- package/src/modify-browser-manifest.ts +245 -0
- package/src/parallel-route-transform-protocol.ts +35 -0
- package/src/parallel-route-transform-worker.ts +82 -0
- package/src/parallel-route-transforms.ts +332 -0
- package/src/performance.ts +254 -0
- package/src/plugin-utils.ts +82 -0
- package/src/prerender-build.ts +623 -0
- package/src/prerender.ts +367 -0
- package/src/react-router-config.ts +220 -0
- package/src/route-artifacts.ts +155 -0
- package/src/route-ast.ts +163 -0
- package/src/route-chunks.ts +857 -0
- package/src/route-component-transform.ts +314 -0
- package/src/route-config.ts +106 -0
- package/src/route-export-pruning.ts +668 -0
- package/src/route-export-resolution.ts +329 -0
- package/src/route-transform-tasks.ts +249 -0
- package/src/route-watch.ts +322 -0
- package/src/server-build-plan.ts +91 -0
- package/src/server-utils.ts +210 -0
- package/src/ssr-externals.ts +59 -0
- package/src/templates/context.ts +12 -0
- package/src/templates/entry.client.tsx +12 -0
- package/src/templates/entry.server.tsx +76 -0
- package/src/typegen.ts +49 -0
- package/src/types.ts +82 -0
- package/src/validation/validate-plugin-order.ts +76 -0
- package/src/virtual-modules.ts +30 -0
- package/src/warnings/warn-on-client-source-maps.ts +96 -0
- package/src/yuku.ts +67 -0
- package/dist/906.js +0 -1
- package/dist/946.js +0 -1
- package/dist/babel.d.ts +0 -8
- package/dist/rslib-runtime.js +0 -23
package/dist/index.js
CHANGED
|
@@ -1,68 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
import { fileURLToPath as __rspack_fileURLToPath, pathToFileURL } from "node:url";
|
|
3
|
-
import { dirname as __rspack_dirname, sep } from "node:path";
|
|
4
|
-
import * as __rspack_external__babel_types_69e65b52 from "@babel/types";
|
|
5
|
-
import { __webpack_require__ } from "./rslib-runtime.js";
|
|
6
|
-
import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
7
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
8
|
-
import { createRequire } from "node:module";
|
|
1
|
+
import { existsSync, readFileSync, realpathSync, watch } from "node:fs";
|
|
9
2
|
import fs_extra from "fs-extra";
|
|
3
|
+
import { rspack } from "@rsbuild/core";
|
|
10
4
|
import { createJiti } from "jiti";
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import { deadCodeElimination, findReferencedIdentifiers } from "babel-dead-code-elimination";
|
|
5
|
+
import { dirname, isAbsolute, relative, resolve as external_pathe_resolve } from "pathe";
|
|
6
|
+
import { createRequestHandler as external_react_router_createRequestHandler, matchRoutes } from "react-router";
|
|
7
|
+
import { access, mkdir, readdir, writeFile } from "node:fs/promises";
|
|
8
|
+
import { pathToFileURL, fileURLToPath as __rspack_fileURLToPath } from "node:url";
|
|
16
9
|
import { createHash } from "node:crypto";
|
|
17
|
-
import {
|
|
18
|
-
import
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var traverse_default = __webpack_require__.n(traverse_namespaceObject);
|
|
24
|
-
let traverse = traverse_default().default ?? traverse_default(), generate = generator_default().default ?? generator_default(), PLUGIN_NAME = 'rsbuild:react-router', JS_EXTENSIONS = [
|
|
25
|
-
'.tsx',
|
|
26
|
-
'.ts',
|
|
27
|
-
'.jsx',
|
|
28
|
-
'.js',
|
|
29
|
-
'.mjs',
|
|
30
|
-
'.mts'
|
|
31
|
-
], JS_LOADERS = {
|
|
32
|
-
'.ts': 'ts',
|
|
33
|
-
'.tsx': 'tsx',
|
|
34
|
-
'.js': 'js',
|
|
35
|
-
'.jsx': 'jsx',
|
|
36
|
-
'.mjs': 'js',
|
|
37
|
-
'.mts': 'ts'
|
|
38
|
-
}, BUILD_CLIENT_ROUTE_QUERY_STRING = '?__react-router-build-client-route', SERVER_ONLY_ROUTE_EXPORTS = [
|
|
39
|
-
'loader',
|
|
40
|
-
'action',
|
|
41
|
-
'middleware',
|
|
42
|
-
'headers'
|
|
43
|
-
], CLIENT_ROUTE_EXPORTS = [
|
|
44
|
-
'clientAction',
|
|
45
|
-
'clientLoader',
|
|
46
|
-
'clientMiddleware',
|
|
47
|
-
'handle',
|
|
48
|
-
'meta',
|
|
49
|
-
'links',
|
|
50
|
-
'shouldRevalidate',
|
|
51
|
-
'default',
|
|
52
|
-
'ErrorBoundary',
|
|
53
|
-
'HydrateFallback',
|
|
54
|
-
'Layout'
|
|
55
|
-
], NAMED_COMPONENT_EXPORTS = [
|
|
56
|
-
'HydrateFallback',
|
|
57
|
-
'ErrorBoundary'
|
|
58
|
-
];
|
|
10
|
+
import { availableParallelism, cpus } from "node:os";
|
|
11
|
+
import jsesc from "jsesc";
|
|
12
|
+
import { Worker } from "node:worker_threads";
|
|
13
|
+
import { createRequire } from "node:module";
|
|
14
|
+
import { isAbsolute as external_node_path_isAbsolute, relative as external_node_path_relative, sep, dirname as __rspack_dirname } from "node:path";
|
|
15
|
+
import { createRouteId, SERVER_EXPORTS, combineURLs, JS_EXTENSIONS, executeRouteTransformTask, setBoundedCacheEntry, PLUGIN_NAME, generateWithProps, getRouteModuleAnalysis, createEmptyRouteChunkByExportName, findEntryFile, routeChunkExportNames, validateRouteChunks, CLIENT_EXPORTS, buildManifestChunkValidity, BUILD_CLIENT_ROUTE_QUERY_STRING, getRouteChunkEntryName, getRouteChunkModuleId, normalizeAssetPrefix, detectRouteChunksIfEnabled, createBundlerRouteExportResolver } from "./451.js";
|
|
59
16
|
function generateServerBuild(routes, options) {
|
|
60
17
|
let manifestId;
|
|
61
18
|
return manifestId = options.serverManifestId ?? 'virtual/react-router/server-manifest', `
|
|
62
19
|
import * as entryServer from ${JSON.stringify(options.entryServerPath)};
|
|
63
20
|
${Object.keys(routes).map((key, index)=>{
|
|
64
21
|
let route = routes[key];
|
|
65
|
-
return `import * as route${index} from ${JSON.stringify(`${
|
|
22
|
+
return `import * as route${index} from ${JSON.stringify(`${external_pathe_resolve(options.appDirectory, route.file)}?react-router-route`)};`;
|
|
66
23
|
}).join('\n')}
|
|
67
24
|
|
|
68
25
|
export { default as assets } from ${JSON.stringify(manifestId)};
|
|
@@ -103,7 +60,14 @@ let RESOLVABLE_BUILD_EXPORTS = new Set([
|
|
|
103
60
|
'routeDiscovery',
|
|
104
61
|
'routes',
|
|
105
62
|
'ssr'
|
|
106
|
-
])
|
|
63
|
+
]);
|
|
64
|
+
function isRecord(value) {
|
|
65
|
+
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
66
|
+
}
|
|
67
|
+
function isPromiseLike(value) {
|
|
68
|
+
return isRecord(value) && 'function' == typeof value.then;
|
|
69
|
+
}
|
|
70
|
+
async function resolveBuildExports(build) {
|
|
107
71
|
let resolved = {
|
|
108
72
|
...build
|
|
109
73
|
};
|
|
@@ -118,30 +82,56 @@ let RESOLVABLE_BUILD_EXPORTS = new Set([
|
|
|
118
82
|
isPromiseLike(value) && (resolved[key] = await value);
|
|
119
83
|
}
|
|
120
84
|
return resolved;
|
|
121
|
-
};
|
|
122
|
-
function invalidDestructureError(name) {
|
|
123
|
-
return Error(`Cannot remove destructured export "${name}"`);
|
|
124
|
-
}
|
|
125
|
-
function toFunctionExpression(decl) {
|
|
126
|
-
return __rspack_external__babel_types_69e65b52.functionExpression(decl.id, decl.params, decl.body, decl.generator, decl.async);
|
|
127
85
|
}
|
|
128
|
-
function
|
|
129
|
-
|
|
86
|
+
async function resolveServerBuildCandidate(candidate) {
|
|
87
|
+
var value;
|
|
88
|
+
if (!isRecord(candidate)) return;
|
|
89
|
+
let resolved = await resolveBuildExports(candidate);
|
|
90
|
+
return isRecord(resolved) && isRecord(resolved.entry) && isRecord(resolved.entry.module) && 'function' == typeof resolved.entry.module.default && isRecord(resolved.routes) && isRecord(resolved.assets) && 'string' == typeof resolved.assetsBuildDirectory && (void 0 === resolved.basename || 'string' == typeof resolved.basename) && isRecord(resolved.future) && 'boolean' == typeof resolved.isSpaMode && Array.isArray(resolved.prerender) && 'string' == typeof resolved.publicPath && isRecord(value = resolved.routeDiscovery) && ('initial' === value.mode || 'lazy' === value.mode && (void 0 === value.manifestPath || 'string' == typeof value.manifestPath)) && 'boolean' == typeof resolved.ssr ? resolved : void 0;
|
|
130
91
|
}
|
|
131
|
-
function
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
for (let
|
|
136
|
-
let
|
|
137
|
-
if (
|
|
92
|
+
async function resolveServerBuildModule(buildModule, source) {
|
|
93
|
+
let moduleValue = await buildModule, candidates = [
|
|
94
|
+
()=>moduleValue
|
|
95
|
+
];
|
|
96
|
+
for (let getCandidate of (isRecord(moduleValue) && ('default' in moduleValue && candidates.push(()=>moduleValue.default), 'module.exports' in moduleValue && candidates.push(()=>moduleValue['module.exports'])), candidates)){
|
|
97
|
+
let candidate = await getCandidate(), serverBuild = await resolveServerBuildCandidate(candidate);
|
|
98
|
+
if (serverBuild) return serverBuild;
|
|
138
99
|
}
|
|
139
|
-
|
|
100
|
+
throw Error(`[rsbuild-plugin-react-router] ${source} did not contain a valid React Router ServerBuild.`);
|
|
140
101
|
}
|
|
141
|
-
function
|
|
142
|
-
return
|
|
102
|
+
function resolveReactRouterServerBuild(buildModule) {
|
|
103
|
+
return resolveServerBuildModule(buildModule, 'Imported module');
|
|
143
104
|
}
|
|
144
|
-
let normalizePath = (value)=>value.replace(/\/\/+/g, '/').replace(/(.+)\/$/, '$1'),
|
|
105
|
+
let normalizePath = (value)=>value.replace(/\/\/+/g, '/').replace(/(.+)\/$/, '$1'), groupRoutesByParentId = (manifest)=>{
|
|
106
|
+
let grouped = {};
|
|
107
|
+
return Object.values(manifest).forEach((route)=>{
|
|
108
|
+
if (!route) return;
|
|
109
|
+
let parentId = route.parentId || '';
|
|
110
|
+
grouped[parentId] ??= [], grouped[parentId].push(route);
|
|
111
|
+
}), grouped;
|
|
112
|
+
}, createPrerenderRoutes = (manifest, parentId = '', grouped = groupRoutesByParentId(manifest))=>(grouped[parentId] || []).map((route)=>{
|
|
113
|
+
let common = {
|
|
114
|
+
id: route.id,
|
|
115
|
+
path: route.path
|
|
116
|
+
};
|
|
117
|
+
return route.index ? {
|
|
118
|
+
index: !0,
|
|
119
|
+
...common
|
|
120
|
+
} : {
|
|
121
|
+
...common,
|
|
122
|
+
children: createPrerenderRoutes(manifest, route.id, grouped)
|
|
123
|
+
};
|
|
124
|
+
}), normalizePrerenderMatchPath = (path)=>`/${path}/`.replace(/^\/\/+/, '/'), withBuildRequest = async (input, init, handle)=>{
|
|
125
|
+
let controller = new AbortController();
|
|
126
|
+
try {
|
|
127
|
+
return await handle(new Request(input, {
|
|
128
|
+
...init,
|
|
129
|
+
signal: controller.signal
|
|
130
|
+
}));
|
|
131
|
+
} finally{
|
|
132
|
+
controller.abort();
|
|
133
|
+
}
|
|
134
|
+
}, resolvePrerenderPaths = async (prerender, ssr, routes, options = {})=>{
|
|
145
135
|
let pathsConfig, paths, paramRoutes, recurse;
|
|
146
136
|
if (null == prerender || !1 === prerender || !1 === (pathsConfig = 'object' == typeof prerender && null !== prerender && 'paths' in prerender ? prerender?.paths : prerender)) return [];
|
|
147
137
|
let { paths: paths1, paramRoutes: paramRoutes1 } = (paths = [
|
|
@@ -182,12 +172,392 @@ let normalizePath = (value)=>value.replace(/\/\/+/g, '/').replace(/(.+)\/$/, '$1
|
|
|
182
172
|
return !0 === resolved ? paths1 : !1 === resolved || null == resolved ? [] : resolved;
|
|
183
173
|
}
|
|
184
174
|
return pathsConfig ?? [];
|
|
185
|
-
},
|
|
175
|
+
}, getPrerenderConfigObject = (prerender)=>'object' != typeof prerender || null === prerender || Array.isArray(prerender) ? null : prerender, getPrerenderConcurrencyConfig = (config)=>config?.concurrency !== void 0 ? {
|
|
176
|
+
key: 'prerender.concurrency',
|
|
177
|
+
value: config.concurrency
|
|
178
|
+
} : config?.unstable_concurrency !== void 0 ? {
|
|
179
|
+
key: 'prerender.unstable_concurrency',
|
|
180
|
+
value: config.unstable_concurrency
|
|
181
|
+
} : void 0, getAvailableCpuCount = ()=>'function' == typeof availableParallelism ? availableParallelism() : cpus().length, getDefaultConcurrency = (cpuCount = getAvailableCpuCount())=>Math.max(0, Math.floor(cpuCount) - 2), mapWithConcurrency = async (items, concurrency, worker)=>{
|
|
182
|
+
let results = Array(items.length), nextIndex = 0, workerCount = Math.max(1, Math.min(concurrency, items.length));
|
|
183
|
+
return await Promise.all(Array.from({
|
|
184
|
+
length: workerCount
|
|
185
|
+
}, async ()=>{
|
|
186
|
+
for(;;){
|
|
187
|
+
let index = nextIndex++;
|
|
188
|
+
if (index >= items.length) return;
|
|
189
|
+
results[index] = await worker(items[index], index);
|
|
190
|
+
}
|
|
191
|
+
})), results;
|
|
192
|
+
}, ROUTE_ANALYSIS_CONCURRENCY = Math.max(1, Math.min(16, getDefaultConcurrency() || 1));
|
|
193
|
+
function configRoutesToRouteManifestEntries(appDirectory, routes, rootId = 'root') {
|
|
194
|
+
let routeManifestEntries = [], routeIds = new Set();
|
|
195
|
+
for (let route of routes)!function walk(route, parentId) {
|
|
196
|
+
let id = route.id || createRouteId(route.file), manifestItem = {
|
|
197
|
+
id,
|
|
198
|
+
parentId,
|
|
199
|
+
file: isAbsolute(route.file) ? relative(appDirectory, route.file) : route.file,
|
|
200
|
+
path: route.path,
|
|
201
|
+
index: route.index,
|
|
202
|
+
caseSensitive: route.caseSensitive
|
|
203
|
+
};
|
|
204
|
+
if (routeIds.has(id)) throw Error(`Unable to define routes with duplicate route id: "${id}"`);
|
|
205
|
+
if (routeIds.add(id), routeManifestEntries.push([
|
|
206
|
+
id,
|
|
207
|
+
manifestItem
|
|
208
|
+
]), route.children) for (let child of route.children)walk(child, id);
|
|
209
|
+
}(route, rootId);
|
|
210
|
+
return routeManifestEntries;
|
|
211
|
+
}
|
|
212
|
+
let orderChunkFiles = (chunkName, files)=>{
|
|
213
|
+
let ownChunkAsset = `${chunkName}.js`, ownFileIndex = files.findIndex((file)=>file.endsWith(ownChunkAsset));
|
|
214
|
+
return ownFileIndex <= 0 ? files : [
|
|
215
|
+
files[ownFileIndex],
|
|
216
|
+
...files.slice(0, ownFileIndex),
|
|
217
|
+
...files.slice(ownFileIndex + 1)
|
|
218
|
+
];
|
|
219
|
+
}, createReactRouterManifestStats = (compilation, chunkNames)=>{
|
|
220
|
+
if (!compilation) return;
|
|
221
|
+
let assetsByChunkName = {}, entrypointFilesByName = {}, namedChunks = compilation.namedChunks, entrypoints = compilation.entrypoints;
|
|
222
|
+
if (chunkNames && 'function' == typeof namedChunks.get) for (let chunkName of chunkNames){
|
|
223
|
+
let chunk = namedChunks.get(chunkName);
|
|
224
|
+
if (!chunk) continue;
|
|
225
|
+
let files = Array.from(chunk.files ?? []);
|
|
226
|
+
assetsByChunkName[chunkName] = orderChunkFiles(chunkName, files);
|
|
227
|
+
}
|
|
228
|
+
else for (let [chunkName, chunk] of namedChunks){
|
|
229
|
+
if (chunkNames && !chunkNames.has(chunkName)) continue;
|
|
230
|
+
let files = Array.from(chunk.files ?? []);
|
|
231
|
+
assetsByChunkName[chunkName] = orderChunkFiles(chunkName, files);
|
|
232
|
+
}
|
|
233
|
+
if (entrypoints) if (chunkNames && 'function' == typeof entrypoints.get) for (let entrypointName of chunkNames){
|
|
234
|
+
let entrypoint = entrypoints.get(entrypointName);
|
|
235
|
+
entrypoint && (entrypointFilesByName[entrypointName] = Array.from(entrypoint.getFiles?.() ?? []));
|
|
236
|
+
}
|
|
237
|
+
else for (let [entrypointName, entrypoint] of entrypoints)(!chunkNames || chunkNames.has(entrypointName)) && (entrypointFilesByName[entrypointName] = Array.from(entrypoint.getFiles?.() ?? []));
|
|
238
|
+
return Object.keys(entrypointFilesByName).length > 0 ? {
|
|
239
|
+
assetsByChunkName,
|
|
240
|
+
entrypointFilesByName
|
|
241
|
+
} : {
|
|
242
|
+
assetsByChunkName
|
|
243
|
+
};
|
|
244
|
+
}, DEFAULT_MANIFEST_DIR = 'static/js', getReactRouterManifestPath = ({ version, isBuild, entryModulePath })=>{
|
|
245
|
+
if (!isBuild) return 'static/js/virtual/react-router/browser-manifest.js';
|
|
246
|
+
let dir = ((entryModulePath)=>{
|
|
247
|
+
if (!entryModulePath) return DEFAULT_MANIFEST_DIR;
|
|
248
|
+
let dir = dirname(entryModulePath);
|
|
249
|
+
return '.' === dir ? DEFAULT_MANIFEST_DIR : dir;
|
|
250
|
+
})(entryModulePath);
|
|
251
|
+
return `${dir}/manifest-${version}.js`;
|
|
252
|
+
}, getRouteEntryName = (route)=>{
|
|
253
|
+
let extensionIndex = route.file.lastIndexOf('.');
|
|
254
|
+
return extensionIndex >= 0 ? route.file.slice(0, extensionIndex) : route.file;
|
|
255
|
+
};
|
|
256
|
+
async function generateReactRouterManifestForDev(routes, _options, clientStats, context, assetPrefix = '/', routeChunkOptions) {
|
|
257
|
+
let result = {}, splitRouteModules = routeChunkOptions?.splitRouteModules ?? !1, enforceSplitRouteModules = 'enforce' === splitRouteModules, isBuild = routeChunkOptions?.isBuild ?? !1, routeChunkConfig = splitRouteModules && routeChunkOptions?.rootRouteFile ? {
|
|
258
|
+
splitRouteModules,
|
|
259
|
+
appDirectory: context,
|
|
260
|
+
rootRouteFile: routeChunkOptions.rootRouteFile
|
|
261
|
+
} : null, getAssetsForChunk = (chunkName)=>{
|
|
262
|
+
let assets = clientStats?.assetsByChunkName?.[chunkName];
|
|
263
|
+
if (!assets) return [
|
|
264
|
+
`${DEFAULT_MANIFEST_DIR}/${chunkName}.js`
|
|
265
|
+
];
|
|
266
|
+
let entrypointCssAssets = clientStats?.entrypointFilesByName?.[chunkName]?.filter((asset)=>asset.endsWith('.css')) ?? [], cssAssets = [
|
|
267
|
+
...assets.filter((asset)=>asset.endsWith('.css')),
|
|
268
|
+
...entrypointCssAssets
|
|
269
|
+
].filter((asset, index, all)=>all.indexOf(asset) === index), nonCssAssets = assets.filter((asset)=>!asset.endsWith('.css'));
|
|
270
|
+
return nonCssAssets.some((asset)=>asset.endsWith('.js')) ? [
|
|
271
|
+
...nonCssAssets,
|
|
272
|
+
...cssAssets
|
|
273
|
+
] : [
|
|
274
|
+
`${DEFAULT_MANIFEST_DIR}/${chunkName}.js`,
|
|
275
|
+
...nonCssAssets,
|
|
276
|
+
...cssAssets
|
|
277
|
+
];
|
|
278
|
+
}, getModulePathForChunk = (chunkName)=>{
|
|
279
|
+
let jsAssets = getAssetsForChunk(chunkName).filter((asset)=>asset.endsWith('.js'));
|
|
280
|
+
return jsAssets[0] ? combineURLs(assetPrefix, jsAssets[0]) : void 0;
|
|
281
|
+
}, manifestEntries = await mapWithConcurrency(Object.entries(routes), ROUTE_ANALYSIS_CONCURRENCY, async ([key, route])=>{
|
|
282
|
+
let routeEntryName = getRouteEntryName(route), assets = getAssetsForChunk(routeEntryName), jsAssets = assets.filter((asset)=>asset.endsWith('.js')), cssAssets = assets.filter((asset)=>asset.endsWith('.css')), routeFilePath = external_pathe_resolve(context, route.file), exports = new Set(), routeModuleExports = [], hasRouteChunkByExportName = null;
|
|
283
|
+
try {
|
|
284
|
+
let { code, exports: exportNames } = await getRouteModuleAnalysis(routeFilePath);
|
|
285
|
+
if (!isBuild && 0 === cssAssets.length && /\.(?:css|less|sass|scss)(?:\?[^'"`]+)?['"`]/.test(code) && (cssAssets = [
|
|
286
|
+
`${DEFAULT_MANIFEST_DIR.replace('/js', '/css')}/${routeEntryName}.css`
|
|
287
|
+
]), routeModuleExports = exportNames, exports = new Set(exportNames), isBuild && routeChunkConfig) {
|
|
288
|
+
let { hasRouteChunkByExportName: chunkInfo } = await detectRouteChunksIfEnabled(routeChunkOptions?.cache, routeChunkConfig, routeFilePath, code);
|
|
289
|
+
hasRouteChunkByExportName = chunkInfo;
|
|
290
|
+
}
|
|
291
|
+
} catch (error) {
|
|
292
|
+
if (isBuild) throw error;
|
|
293
|
+
console.error(`Failed to analyze route file ${routeFilePath}:`, error);
|
|
294
|
+
}
|
|
295
|
+
let hasClientAction = exports.has(CLIENT_EXPORTS.clientAction), hasClientLoader = exports.has(CLIENT_EXPORTS.clientLoader), hasClientMiddleware = exports.has(CLIENT_EXPORTS.clientMiddleware), hasDefaultExport = exports.has('default'), routeChunkMap = hasRouteChunkByExportName;
|
|
296
|
+
return isBuild && enforceSplitRouteModules && routeChunkConfig && validateRouteChunks({
|
|
297
|
+
config: routeChunkConfig,
|
|
298
|
+
id: routeFilePath,
|
|
299
|
+
valid: buildManifestChunkValidity(exports, routeChunkMap ?? createEmptyRouteChunkByExportName())
|
|
300
|
+
}), [
|
|
301
|
+
key,
|
|
302
|
+
{
|
|
303
|
+
id: route.id,
|
|
304
|
+
parentId: route.parentId,
|
|
305
|
+
path: route.path,
|
|
306
|
+
index: route.index,
|
|
307
|
+
caseSensitive: route.caseSensitive,
|
|
308
|
+
module: combineURLs(assetPrefix, jsAssets[0] || ''),
|
|
309
|
+
clientActionModule: routeChunkMap?.clientAction ? getModulePathForChunk(getRouteChunkEntryName(route.id, 'clientAction')) : void 0,
|
|
310
|
+
clientLoaderModule: routeChunkMap?.clientLoader ? getModulePathForChunk(getRouteChunkEntryName(route.id, 'clientLoader')) : void 0,
|
|
311
|
+
clientMiddlewareModule: routeChunkMap?.clientMiddleware ? getModulePathForChunk(getRouteChunkEntryName(route.id, 'clientMiddleware')) : void 0,
|
|
312
|
+
hydrateFallbackModule: routeChunkMap?.HydrateFallback ? getModulePathForChunk(getRouteChunkEntryName(route.id, 'HydrateFallback')) : void 0,
|
|
313
|
+
hasAction: exports.has(SERVER_EXPORTS.action),
|
|
314
|
+
hasLoader: exports.has(SERVER_EXPORTS.loader),
|
|
315
|
+
hasClientAction,
|
|
316
|
+
hasClientLoader,
|
|
317
|
+
hasClientMiddleware,
|
|
318
|
+
hasDefaultExport,
|
|
319
|
+
hasErrorBoundary: exports.has(CLIENT_EXPORTS.ErrorBoundary),
|
|
320
|
+
imports: jsAssets.map((asset)=>combineURLs(assetPrefix, asset)),
|
|
321
|
+
css: cssAssets.map((asset)=>combineURLs(assetPrefix, asset))
|
|
322
|
+
},
|
|
323
|
+
routeModuleExports
|
|
324
|
+
];
|
|
325
|
+
}), routeModuleExportsByRouteId = {};
|
|
326
|
+
for (let [key, routeManifestItem, routeModuleExports] of manifestEntries)result[key] = routeManifestItem, routeModuleExportsByRouteId[key] = routeModuleExports;
|
|
327
|
+
let entryAssets = getAssetsForChunk('entry.client'), entryJsAssets = entryAssets.filter((asset)=>asset.endsWith('.js')), entryCssAssets = entryAssets.filter((asset)=>asset.endsWith('.css')), fingerprintedValues = {
|
|
328
|
+
entry: {
|
|
329
|
+
module: combineURLs(assetPrefix, entryJsAssets[0] || ''),
|
|
330
|
+
imports: entryJsAssets.map((asset)=>combineURLs(assetPrefix, asset)),
|
|
331
|
+
css: entryCssAssets.map((asset)=>combineURLs(assetPrefix, asset))
|
|
332
|
+
},
|
|
333
|
+
routes: result
|
|
334
|
+
}, version = isBuild ? createHash('md5').update(JSON.stringify(fingerprintedValues)).digest('hex').slice(0, 8) : String(Math.random()), manifestPath = getReactRouterManifestPath({
|
|
335
|
+
version,
|
|
336
|
+
isBuild,
|
|
337
|
+
entryModulePath: entryJsAssets[0]
|
|
338
|
+
});
|
|
339
|
+
return {
|
|
340
|
+
manifest: {
|
|
341
|
+
version,
|
|
342
|
+
url: combineURLs(assetPrefix, manifestPath),
|
|
343
|
+
hmr: void 0,
|
|
344
|
+
entry: fingerprintedValues.entry,
|
|
345
|
+
sri: void 0,
|
|
346
|
+
routes: result
|
|
347
|
+
},
|
|
348
|
+
moduleExportsByRouteId: routeModuleExportsByRouteId
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
async function getReactRouterManifestForDev(...args) {
|
|
352
|
+
return (await generateReactRouterManifestForDev(...args)).manifest;
|
|
353
|
+
}
|
|
354
|
+
let redirectStatusCodes = new Set([
|
|
355
|
+
301,
|
|
356
|
+
302,
|
|
357
|
+
303,
|
|
358
|
+
307,
|
|
359
|
+
308
|
|
360
|
+
]), getServerBuildPath = async ({ buildDirectory, serverBuildFile })=>{
|
|
361
|
+
let serverBuildDir = external_pathe_resolve(buildDirectory, 'server'), defaultServerBuildFile = 'static/js/app.js', configuredServerBuildFile = serverBuildFile || 'index.js', configuredServerBuildPath = external_pathe_resolve(serverBuildDir, configuredServerBuildFile), defaultServerBuildPath = external_pathe_resolve(serverBuildDir, defaultServerBuildFile);
|
|
362
|
+
return configuredServerBuildFile !== defaultServerBuildFile && existsSync(defaultServerBuildPath) && !existsSync(configuredServerBuildPath) && (await mkdir(dirname(configuredServerBuildPath), {
|
|
363
|
+
recursive: !0
|
|
364
|
+
}), await fs_extra.copy(defaultServerBuildPath, configuredServerBuildPath)), {
|
|
365
|
+
serverBuildDir,
|
|
366
|
+
serverBuildPath: existsSync(configuredServerBuildPath) ? configuredServerBuildPath : defaultServerBuildPath
|
|
367
|
+
};
|
|
368
|
+
}, prerenderData = async ({ handler, prerenderPath, onlyRoutes, clientBuildDir, basename, trailingSlashAwareDataRequests, api, requestInit })=>{
|
|
369
|
+
let dataRequestPath = trailingSlashAwareDataRequests ? prerenderPath.endsWith('/') ? `${prerenderPath}_.data` : `${prerenderPath}.data` : '/' === prerenderPath ? '/_root.data' : `${prerenderPath.replace(/\/$/, '')}.data`, normalizedPath = `${basename}${dataRequestPath}`.replace(/\/\/+/g, '/'), url = new URL(`http://localhost${normalizedPath}`);
|
|
370
|
+
return onlyRoutes?.length && url.searchParams.set('_routes', onlyRoutes.join(',')), withBuildRequest(url, requestInit, async (request)=>{
|
|
371
|
+
let response = await handler(request), data = await response.text();
|
|
372
|
+
if (200 !== response.status && 202 !== response.status) throw Error(`Prerender (data): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${prerenderPath}\` path.\n${normalizedPath}`);
|
|
373
|
+
let outputPath = external_pathe_resolve(clientBuildDir, ...normalizedPath.split('/'));
|
|
374
|
+
return await mkdir(dirname(outputPath), {
|
|
375
|
+
recursive: !0
|
|
376
|
+
}), await writeFile(outputPath, data), api.logger.info(`Prerender (data): ${prerenderPath} -> ${relative(process.cwd(), outputPath)}`), data;
|
|
377
|
+
});
|
|
378
|
+
}, prerenderRoute = async ({ handler, prerenderPath, clientBuildDir, basename, api, requestInit })=>{
|
|
379
|
+
let normalizedPath = `${basename}${prerenderPath}/`.replace(/\/\/+/g, '/');
|
|
380
|
+
await withBuildRequest(`http://localhost${normalizedPath}`, requestInit, async (request)=>{
|
|
381
|
+
let response = await handler(request), html = await response.text();
|
|
382
|
+
if (redirectStatusCodes.has(response.status)) {
|
|
383
|
+
let location = response.headers.get('Location'), delay = 2 * (302 === response.status);
|
|
384
|
+
html = `<!doctype html>
|
|
385
|
+
<head>
|
|
386
|
+
<title>Redirecting to: ${location}</title>
|
|
387
|
+
<meta http-equiv="refresh" content="${delay};url=${location}">
|
|
388
|
+
<meta name="robots" content="noindex">
|
|
389
|
+
</head>
|
|
390
|
+
<body>
|
|
391
|
+
\t<a href="${location}">
|
|
392
|
+
Redirecting from <code>${normalizedPath}</code> to <code>${location}</code>
|
|
393
|
+
</a>
|
|
394
|
+
</body>
|
|
395
|
+
</html>`;
|
|
396
|
+
} else if (200 !== response.status) throw Error(`Prerender (html): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${normalizedPath}\` path.\n` + html);
|
|
397
|
+
let outputPath = external_pathe_resolve(clientBuildDir, ...normalizedPath.split('/'), 'index.html');
|
|
398
|
+
await mkdir(dirname(outputPath), {
|
|
399
|
+
recursive: !0
|
|
400
|
+
}), await writeFile(outputPath, html), api.logger.info(`Prerender (html): ${prerenderPath} -> ${relative(process.cwd(), outputPath)}`);
|
|
401
|
+
});
|
|
402
|
+
}, prerenderResourceRoute = async ({ handler, prerenderPath, clientBuildDir, basename, api, requestInit })=>{
|
|
403
|
+
let normalizedPath = `${basename}${prerenderPath}/`.replace(/\/\/+/g, '/').replace(/\/$/g, '');
|
|
404
|
+
await withBuildRequest(`http://localhost${normalizedPath}`, requestInit, async (request)=>{
|
|
405
|
+
let response = await handler(request), content = Buffer.from(await response.arrayBuffer());
|
|
406
|
+
if (200 !== response.status) throw Error(`Prerender (resource): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${normalizedPath}\` path.\n` + content.toString('utf8'));
|
|
407
|
+
let outputPath = external_pathe_resolve(clientBuildDir, ...normalizedPath.split('/'));
|
|
408
|
+
await mkdir(dirname(outputPath), {
|
|
409
|
+
recursive: !0
|
|
410
|
+
}), await writeFile(outputPath, content), api.logger.info(`Prerender (resource): ${prerenderPath} -> ${relative(process.cwd(), outputPath)}`);
|
|
411
|
+
});
|
|
412
|
+
}, handleSpaMode = async ({ handler, build, clientBuildDir, basename, api })=>{
|
|
413
|
+
await withBuildRequest(`http://localhost${basename}`, {
|
|
414
|
+
headers: {
|
|
415
|
+
'X-React-Router-SPA-Mode': 'yes'
|
|
416
|
+
}
|
|
417
|
+
}, async (request)=>{
|
|
418
|
+
let response = await handler(request), html = await response.text(), isPrerenderSpaFallback = build.prerender?.includes('/'), filename = isPrerenderSpaFallback ? '__spa-fallback.html' : 'index.html';
|
|
419
|
+
if (200 !== response.status) {
|
|
420
|
+
if (isPrerenderSpaFallback) throw Error(`Prerender: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering your \`${filename}\` file.\n` + html);
|
|
421
|
+
throw Error(`SPA Mode: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering your \`${filename}\` file.\n` + html);
|
|
422
|
+
}
|
|
423
|
+
if (!html.includes('window.__reactRouterContext =') || !html.includes('window.__reactRouterRouteModules =')) throw Error("SPA Mode: Did you forget to include `<Scripts/>` in your root route? Your pre-rendered HTML cannot hydrate without `<Scripts />`.");
|
|
424
|
+
let outputPath = external_pathe_resolve(clientBuildDir, filename);
|
|
425
|
+
await writeFile(outputPath, html);
|
|
426
|
+
let prettyPath = relative(process.cwd(), outputPath);
|
|
427
|
+
build.prerender?.length ? api.logger.info(`Prerender (html): SPA Fallback -> ${prettyPath}`) : api.logger.info(`SPA Mode: Generated ${prettyPath}`);
|
|
428
|
+
});
|
|
429
|
+
}, runPrerenderPaths = async ({ build, requestHandler, clientBuildDir, options })=>{
|
|
430
|
+
let config, value, { api, basename, future, prerenderConfig, prerenderPaths } = options, buildRoutes = createPrerenderRoutes(build.routes), concurrency = (config = getPrerenderConfigObject(prerenderConfig), 'number' == typeof (value = getPrerenderConcurrencyConfig(config)?.value) && Number.isInteger(value) && value > 0 ? value : 1), pending = new Set(), enqueue = async (path)=>{
|
|
431
|
+
let data, matches = matchRoutes(buildRoutes, normalizePrerenderMatchPath(path));
|
|
432
|
+
if (!matches) return;
|
|
433
|
+
let leafRoute = matches[matches.length - 1]?.route, routeId = leafRoute?.id, manifestRoute = routeId ? build.routes?.[routeId]?.module : null;
|
|
434
|
+
!manifestRoute || manifestRoute.default || manifestRoute.ErrorBoundary ? (matches.some((match)=>{
|
|
435
|
+
let matchedRouteId = match.route.id;
|
|
436
|
+
return !!matchedRouteId && build.assets?.routes?.[matchedRouteId]?.hasLoader;
|
|
437
|
+
}) && (data = await prerenderData({
|
|
438
|
+
handler: requestHandler,
|
|
439
|
+
prerenderPath: path,
|
|
440
|
+
onlyRoutes: null,
|
|
441
|
+
clientBuildDir,
|
|
442
|
+
basename,
|
|
443
|
+
trailingSlashAwareDataRequests: future.unstable_trailingSlashAwareDataRequests,
|
|
444
|
+
api
|
|
445
|
+
})), await prerenderRoute({
|
|
446
|
+
handler: requestHandler,
|
|
447
|
+
prerenderPath: path,
|
|
448
|
+
clientBuildDir,
|
|
449
|
+
basename,
|
|
450
|
+
api,
|
|
451
|
+
requestInit: data ? {
|
|
452
|
+
headers: {
|
|
453
|
+
'X-React-Router-Prerender-Data': encodeURI(data)
|
|
454
|
+
}
|
|
455
|
+
} : void 0
|
|
456
|
+
})) : manifestRoute.loader && routeId ? (await prerenderData({
|
|
457
|
+
handler: requestHandler,
|
|
458
|
+
prerenderPath: path,
|
|
459
|
+
onlyRoutes: [
|
|
460
|
+
routeId
|
|
461
|
+
],
|
|
462
|
+
clientBuildDir,
|
|
463
|
+
basename,
|
|
464
|
+
trailingSlashAwareDataRequests: future.unstable_trailingSlashAwareDataRequests,
|
|
465
|
+
api
|
|
466
|
+
}), await prerenderResourceRoute({
|
|
467
|
+
handler: requestHandler,
|
|
468
|
+
prerenderPath: path,
|
|
469
|
+
clientBuildDir,
|
|
470
|
+
basename,
|
|
471
|
+
api
|
|
472
|
+
})) : api.logger.warn(`⚠️ Skipping prerendering for resource route without a loader: ${routeId}`);
|
|
473
|
+
};
|
|
474
|
+
for (let path of prerenderPaths){
|
|
475
|
+
let task = enqueue(path);
|
|
476
|
+
pending.add(task), task.finally(()=>pending.delete(task)), pending.size >= concurrency && await Promise.race(pending);
|
|
477
|
+
}
|
|
478
|
+
await Promise.all(pending);
|
|
479
|
+
}, runReactRouterPrerenderBuild = async (options)=>{
|
|
480
|
+
if (!options.hasWebEnvironment) return;
|
|
481
|
+
let { api, buildDirectory, serverBuildFile, ssr, isPrerenderEnabled, prerenderPaths, routes, latestBrowserManifest, latestBrowserManifestModuleExports, clientStats, pluginOptions, appDirectory, assetPrefix, routeChunkOptions, buildManifest, resolvedConfigWithRoutes, buildEnd, basename } = options, { serverBuildDir, serverBuildPath } = await getServerBuildPath({
|
|
482
|
+
buildDirectory,
|
|
483
|
+
serverBuildFile
|
|
484
|
+
}), clientBuildDir = external_pathe_resolve(buildDirectory, 'client');
|
|
485
|
+
if (!existsSync(serverBuildPath)) return void console.warn(`[${PLUGIN_NAME}] Server build not found at ${serverBuildPath}. Skipping prerendering.`);
|
|
486
|
+
if (await mkdir(clientBuildDir, {
|
|
487
|
+
recursive: !0
|
|
488
|
+
}), !ssr || isPrerenderEnabled) {
|
|
489
|
+
process.env.IS_RR_BUILD_REQUEST = 'yes';
|
|
490
|
+
let buildModule = await import(pathToFileURL(serverBuildPath).toString()), build = await resolveServerBuildModule(buildModule, `Server build ${JSON.stringify(serverBuildPath)}`), requestHandler = external_react_router_createRequestHandler(build, 'production');
|
|
491
|
+
if (isPrerenderEnabled) {
|
|
492
|
+
if (!ssr) {
|
|
493
|
+
let generated = latestBrowserManifest ? {
|
|
494
|
+
manifest: latestBrowserManifest,
|
|
495
|
+
moduleExportsByRouteId: latestBrowserManifestModuleExports
|
|
496
|
+
} : await generateReactRouterManifestForDev(routes, pluginOptions, clientStats, appDirectory, assetPrefix, routeChunkOptions);
|
|
497
|
+
(({ routes, manifestRoutes, routeExports, prerenderPaths, api })=>{
|
|
498
|
+
let errors = (({ routes, manifestRoutes, routeExports, prerenderPaths })=>{
|
|
499
|
+
if (0 === prerenderPaths.length) return [];
|
|
500
|
+
let prerenderRoutes = createPrerenderRoutes(routes), prerenderedRoutes = new Set();
|
|
501
|
+
for (let path of prerenderPaths){
|
|
502
|
+
let matches = matchRoutes(prerenderRoutes, normalizePrerenderMatchPath(path));
|
|
503
|
+
if (!matches) throw Error(`Unable to prerender path because it does not match any routes: ${path}`);
|
|
504
|
+
matches.forEach((match)=>prerenderedRoutes.add(match.route.id));
|
|
505
|
+
}
|
|
506
|
+
let errors = [];
|
|
507
|
+
for (let [routeId, route] of Object.entries(manifestRoutes)){
|
|
508
|
+
let exports = routeExports[routeId] ?? [], invalidApis = [];
|
|
509
|
+
if (exports.includes('headers') && invalidApis.push('headers'), exports.includes('action') && invalidApis.push('action'), invalidApis.length > 0 && errors.push(`Prerender: ${invalidApis.length} invalid route export(s) in \`${routeId}\` when pre-rendering with \`ssr:false\`: ${invalidApis.map((api)=>`\`${api}\``).join(', ')}. See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information.`), !prerenderedRoutes.has(routeId)) {
|
|
510
|
+
exports.includes('loader') && errors.push(`Prerender: 1 invalid route export in \`${routeId}\` when pre-rendering with \`ssr:false\`: \`loader\`. See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information.`);
|
|
511
|
+
let parentRoute = route.parentId && manifestRoutes[route.parentId] ? manifestRoutes[route.parentId] : null;
|
|
512
|
+
for(; parentRoute;)parentRoute.hasLoader && !parentRoute.hasClientLoader && errors.push(`Prerender: 1 invalid route export in \`${parentRoute.id}\` when pre-rendering with \`ssr:false\`: \`loader\`. See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information.`), parentRoute = parentRoute.parentId && manifestRoutes[parentRoute.parentId] ? manifestRoutes[parentRoute.parentId] : null;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return errors;
|
|
516
|
+
})({
|
|
517
|
+
routes,
|
|
518
|
+
manifestRoutes,
|
|
519
|
+
routeExports,
|
|
520
|
+
prerenderPaths
|
|
521
|
+
});
|
|
522
|
+
if (errors.length > 0) throw api.logger.error(errors.join('\n')), Error('Invalid route exports found when prerendering with `ssr:false`');
|
|
523
|
+
})({
|
|
524
|
+
routes,
|
|
525
|
+
manifestRoutes: generated.manifest.routes,
|
|
526
|
+
routeExports: generated.moduleExportsByRouteId,
|
|
527
|
+
prerenderPaths,
|
|
528
|
+
api
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
let routeTree = createPrerenderRoutes(routes);
|
|
532
|
+
for (let path of prerenderPaths)if (!matchRoutes(routeTree, normalizePrerenderMatchPath(path))) throw Error(`Unable to prerender path because it does not match any routes: ${path}`);
|
|
533
|
+
prerenderPaths.length > 0 && api.logger.info(`Prerender (html): ${prerenderPaths.length} path(s)...`), await runPrerenderPaths({
|
|
534
|
+
build,
|
|
535
|
+
requestHandler,
|
|
536
|
+
clientBuildDir,
|
|
537
|
+
options
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
ssr || await handleSpaMode({
|
|
541
|
+
handler: requestHandler,
|
|
542
|
+
build,
|
|
543
|
+
clientBuildDir,
|
|
544
|
+
basename,
|
|
545
|
+
api
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
ssr || (await fs_extra.remove(serverBuildDir), api.logger.info(`[${PLUGIN_NAME}] Removed server build (static deployment)`)), buildEnd && await buildEnd({
|
|
549
|
+
buildManifest,
|
|
550
|
+
reactRouterConfig: resolvedConfigWithRoutes,
|
|
551
|
+
viteConfig: api.getNormalizedConfig()
|
|
552
|
+
});
|
|
553
|
+
}, DEFAULT_CONFIG = {
|
|
186
554
|
appDirectory: 'app',
|
|
187
555
|
basename: '/',
|
|
188
556
|
buildDirectory: 'build',
|
|
189
557
|
serverBuildFile: 'index.js',
|
|
190
558
|
serverModuleFormat: 'esm',
|
|
559
|
+
splitRouteModules: !0,
|
|
560
|
+
subResourceIntegrity: !1,
|
|
191
561
|
ssr: !0,
|
|
192
562
|
future: {
|
|
193
563
|
unstable_optimizeDeps: !1,
|
|
@@ -204,6 +574,16 @@ let normalizePath = (value)=>value.replace(/\/\/+/g, '/').replace(/(.+)\/$/, '$1
|
|
|
204
574
|
allowedActionOrigins: !1,
|
|
205
575
|
routes: {},
|
|
206
576
|
unstable_routeConfig: []
|
|
577
|
+
}, normalizeSubResourceIntegrity = (config)=>{
|
|
578
|
+
let subResourceIntegrity = config.subResourceIntegrity ?? config.future?.unstable_subResourceIntegrity;
|
|
579
|
+
return void 0 === subResourceIntegrity ? config : {
|
|
580
|
+
...config,
|
|
581
|
+
subResourceIntegrity,
|
|
582
|
+
future: {
|
|
583
|
+
...config.future ?? {},
|
|
584
|
+
unstable_subResourceIntegrity: subResourceIntegrity
|
|
585
|
+
}
|
|
586
|
+
};
|
|
207
587
|
}, resolveReactRouterConfig = async (reactRouterUserConfig)=>{
|
|
208
588
|
let userAndPresetConfigs = ((...configs)=>configs.reduce((configA, configB)=>{
|
|
209
589
|
let mergeRequired = (key)=>void 0 !== configA[key] && void 0 !== configB[key];
|
|
@@ -240,481 +620,337 @@ let normalizePath = (value)=>value.replace(/\/\/+/g, '/').replace(/(.+)\/$/, '$1
|
|
|
240
620
|
if (!presetConfig) return null;
|
|
241
621
|
let { presets: _presets, ...rest } = presetConfig;
|
|
242
622
|
return rest;
|
|
243
|
-
}))).filter(Boolean), reactRouterUserConfig), resolvedFuture = {
|
|
623
|
+
}))).filter(Boolean).map(normalizeSubResourceIntegrity), normalizeSubResourceIntegrity(reactRouterUserConfig)), subResourceIntegrity = userAndPresetConfigs.subResourceIntegrity ?? userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? DEFAULT_CONFIG.subResourceIntegrity, resolvedFuture = {
|
|
244
624
|
...DEFAULT_CONFIG.future,
|
|
245
|
-
...userAndPresetConfigs.future ?? {}
|
|
246
|
-
|
|
625
|
+
...userAndPresetConfigs.future ?? {},
|
|
626
|
+
unstable_subResourceIntegrity: subResourceIntegrity
|
|
627
|
+
}, splitRouteModules = userAndPresetConfigs.splitRouteModules ?? userAndPresetConfigs.future?.v8_splitRouteModules ?? DEFAULT_CONFIG.splitRouteModules, resolved = {
|
|
247
628
|
...DEFAULT_CONFIG,
|
|
248
629
|
...userAndPresetConfigs,
|
|
249
630
|
future: resolvedFuture,
|
|
631
|
+
splitRouteModules,
|
|
632
|
+
subResourceIntegrity,
|
|
250
633
|
allowedActionOrigins: userAndPresetConfigs.allowedActionOrigins ?? DEFAULT_CONFIG.allowedActionOrigins,
|
|
251
634
|
routes: DEFAULT_CONFIG.routes,
|
|
252
|
-
unstable_routeConfig: DEFAULT_CONFIG.unstable_routeConfig
|
|
253
|
-
serverBundles: DEFAULT_CONFIG.serverBundles
|
|
635
|
+
unstable_routeConfig: DEFAULT_CONFIG.unstable_routeConfig
|
|
254
636
|
};
|
|
255
637
|
return resolved.ssr || (resolved = {
|
|
256
638
|
...resolved,
|
|
257
639
|
serverBundles: void 0
|
|
258
640
|
}), {
|
|
259
641
|
resolved,
|
|
260
|
-
presets: reactRouterUserConfig.presets ?? []
|
|
261
|
-
|
|
262
|
-
}, routeChunkExportNames = [
|
|
263
|
-
'clientAction',
|
|
264
|
-
'clientLoader',
|
|
265
|
-
'clientMiddleware',
|
|
266
|
-
'HydrateFallback'
|
|
267
|
-
];
|
|
268
|
-
[
|
|
269
|
-
...routeChunkExportNames
|
|
270
|
-
];
|
|
271
|
-
let routeChunkQueryStringPrefix = '?route-chunk=', routeChunkQueryStrings = {
|
|
272
|
-
main: `${routeChunkQueryStringPrefix}main`,
|
|
273
|
-
clientAction: `${routeChunkQueryStringPrefix}clientAction`,
|
|
274
|
-
clientLoader: `${routeChunkQueryStringPrefix}clientLoader`,
|
|
275
|
-
clientMiddleware: `${routeChunkQueryStringPrefix}clientMiddleware`,
|
|
276
|
-
HydrateFallback: `${routeChunkQueryStringPrefix}HydrateFallback`
|
|
277
|
-
}, routeChunkEntrySuffix = {
|
|
278
|
-
clientAction: 'client-action',
|
|
279
|
-
clientLoader: 'client-loader',
|
|
280
|
-
clientMiddleware: 'client-middleware',
|
|
281
|
-
HydrateFallback: 'hydrate-fallback'
|
|
282
|
-
}, invariant = (value, message)=>{
|
|
283
|
-
if (!value) throw Error(message);
|
|
284
|
-
}, getOrSetFromCache = (cache, key, version, getValue)=>{
|
|
285
|
-
if (!cache) return getValue();
|
|
286
|
-
let entry = cache.get(key);
|
|
287
|
-
if (entry?.version === version) return entry.value;
|
|
288
|
-
let value = getValue();
|
|
289
|
-
return cache.set(key, {
|
|
290
|
-
value,
|
|
291
|
-
version
|
|
292
|
-
}), value;
|
|
293
|
-
}, codeToAst = (code, cache, cacheKey)=>structuredClone(getOrSetFromCache(cache, `${cacheKey}::codeToAst`, code, ()=>parse(code, {
|
|
294
|
-
sourceType: 'module'
|
|
295
|
-
}))), isNodePathWithNode = (path)=>!(!path || 'object' != typeof path || Array.isArray(path)) && 'node' in path && !!path.node, assertNodePathIsVariableDeclarator = (path)=>{
|
|
296
|
-
invariant(path && !Array.isArray(path) && __rspack_external__babel_types_69e65b52.isVariableDeclarator(path.node), `Expected a VariableDeclarator path, but got ${Array.isArray(path) ? 'an array' : path?.node?.type}`);
|
|
297
|
-
}, assertNodePathIsPattern = (path)=>{
|
|
298
|
-
invariant(path && !Array.isArray(path) && __rspack_external__babel_types_69e65b52.isPattern(path.node), `Expected a Pattern path, but got ${Array.isArray(path) ? 'an array' : path?.node?.type}`);
|
|
299
|
-
}, getExportDependencies = (code, cache, cacheKey)=>getOrSetFromCache(cache, `${cacheKey}::getExportDependencies`, code, ()=>{
|
|
300
|
-
let exportDependencies = new Map();
|
|
301
|
-
function handleExport(exportName, exportPath, identifiersPath = exportPath) {
|
|
302
|
-
let identifiers = getDependentIdentifiersForPath(identifiersPath), topLevelStatements = new Set([
|
|
303
|
-
exportPath.node,
|
|
304
|
-
...getTopLevelStatementsForPaths(identifiers)
|
|
305
|
-
]), topLevelNonModuleStatements = new Set(Array.from(topLevelStatements).filter((statement)=>!__rspack_external__babel_types_69e65b52.isImportDeclaration(statement) && !__rspack_external__babel_types_69e65b52.isExportDeclaration(statement))), importedIdentifierNames = new Set();
|
|
306
|
-
for (let identifier of identifiers)__rspack_external__babel_types_69e65b52.isIdentifier(identifier.node) && identifier.parentPath?.parentPath?.isImportDeclaration() && importedIdentifierNames.add(identifier.node.name);
|
|
307
|
-
let exportedVariableDeclarators = new Set();
|
|
308
|
-
for (let identifier of identifiers){
|
|
309
|
-
if (identifier.parentPath?.isVariableDeclarator()) {
|
|
310
|
-
let parentPath = identifier.parentPath;
|
|
311
|
-
if (parentPath.parentPath?.parentPath?.isExportNamedDeclaration()) {
|
|
312
|
-
exportedVariableDeclarators.add(parentPath.node);
|
|
313
|
-
continue;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
if (identifier.findParent((path)=>!!(path.isPattern() && path.parentPath?.isVariableDeclarator() && path.parentPath.parentPath?.parentPath?.isExportNamedDeclaration()))) {
|
|
317
|
-
let currentPath = identifier;
|
|
318
|
-
for(; currentPath;){
|
|
319
|
-
if (currentPath.parentPath?.isVariableDeclarator() && 'id' === currentPath.parentKey) {
|
|
320
|
-
exportedVariableDeclarators.add(currentPath.parentPath.node);
|
|
321
|
-
break;
|
|
322
|
-
}
|
|
323
|
-
currentPath = currentPath.parentPath;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
exportDependencies.set(exportName, {
|
|
328
|
-
topLevelStatements,
|
|
329
|
-
topLevelNonModuleStatements,
|
|
330
|
-
importedIdentifierNames,
|
|
331
|
-
exportedVariableDeclarators
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
return traverse(codeToAst(code, cache, cacheKey), {
|
|
335
|
-
ExportDeclaration (exportPath) {
|
|
336
|
-
let { node } = exportPath;
|
|
337
|
-
if (__rspack_external__babel_types_69e65b52.isExportAllDeclaration(node)) return;
|
|
338
|
-
if (__rspack_external__babel_types_69e65b52.isExportDefaultDeclaration(node)) return void handleExport('default', exportPath);
|
|
339
|
-
let { declaration } = node;
|
|
340
|
-
if (__rspack_external__babel_types_69e65b52.isVariableDeclaration(declaration)) {
|
|
341
|
-
let { declarations } = declaration;
|
|
342
|
-
for(let i = 0; i < declarations.length; i++){
|
|
343
|
-
let declarator = declarations[i];
|
|
344
|
-
if (__rspack_external__babel_types_69e65b52.isIdentifier(declarator.id)) {
|
|
345
|
-
let declaratorPath = exportPath.get(`declaration.declarations.${i}`);
|
|
346
|
-
assertNodePathIsVariableDeclarator(declaratorPath), handleExport(declarator.id.name, exportPath, declaratorPath);
|
|
347
|
-
continue;
|
|
348
|
-
}
|
|
349
|
-
if (__rspack_external__babel_types_69e65b52.isPattern(declarator.id)) {
|
|
350
|
-
let exportedPatternPath = exportPath.get(`declaration.declarations.${i}.id`);
|
|
351
|
-
for (let identifier of (assertNodePathIsPattern(exportedPatternPath), getIdentifiersForPatternPath(exportedPatternPath)))__rspack_external__babel_types_69e65b52.isIdentifier(identifier.node) && handleExport(identifier.node.name, exportPath, identifier);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
if (__rspack_external__babel_types_69e65b52.isFunctionDeclaration(declaration) || __rspack_external__babel_types_69e65b52.isClassDeclaration(declaration)) {
|
|
357
|
-
invariant(declaration.id, 'Expected exported function or class declaration to have a name when not the default export'), handleExport(declaration.id.name, exportPath);
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
if (__rspack_external__babel_types_69e65b52.isExportNamedDeclaration(node)) {
|
|
361
|
-
for (let specifier of node.specifiers)if (__rspack_external__babel_types_69e65b52.isIdentifier(specifier.exported)) {
|
|
362
|
-
let name = specifier.exported.name, specifierPath = exportPath.get('specifiers').find((path)=>path.node === specifier);
|
|
363
|
-
invariant(specifierPath, `Expected to find specifier path for ${name}`), handleExport(name, exportPath, specifierPath);
|
|
364
|
-
}
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
throw Error('Unknown export node type');
|
|
368
|
-
}
|
|
369
|
-
}), exportDependencies;
|
|
370
|
-
}), getDependentIdentifiersForPath = (path, state)=>{
|
|
371
|
-
let { visited, identifiers } = state ?? {
|
|
372
|
-
visited: new Set(),
|
|
373
|
-
identifiers: new Set()
|
|
642
|
+
presets: reactRouterUserConfig.presets ?? [],
|
|
643
|
+
hasConfiguredServerModuleFormat: void 0 !== userAndPresetConfigs.serverModuleFormat
|
|
374
644
|
};
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
identifiers
|
|
405
|
-
}));
|
|
645
|
+
}, BROWSER_MANIFEST_ASSET = 'static/js/virtual/react-router/browser-manifest.js', ABSOLUTE_URL_RE = /^[a-zA-Z][a-zA-Z\d+\-.]*:/, addIntegrity = (sri, assetPrefix, assetName, integrity)=>{
|
|
646
|
+
'string' == typeof assetName && 'string' == typeof integrity && (sri[ABSOLUTE_URL_RE.test(assetName) || assetName.startsWith('//') || assetName.startsWith('/') ? assetName : combineURLs(assetPrefix, assetName)] = integrity);
|
|
647
|
+
};
|
|
648
|
+
function isSourceMapEnabled(value) {
|
|
649
|
+
return !0 === value || !1 !== value && null != value && ('string' == typeof value || 'object' == typeof value && !!value.js);
|
|
650
|
+
}
|
|
651
|
+
function getDevtoolFromRspackConfig(config) {
|
|
652
|
+
if (config && 'function' != typeof config && 'object' == typeof config) return config.devtool;
|
|
653
|
+
}
|
|
654
|
+
function _check_private_redeclaration(obj, privateCollection) {
|
|
655
|
+
if (privateCollection.has(obj)) throw TypeError("Cannot initialize the same private elements twice on an object");
|
|
656
|
+
}
|
|
657
|
+
function _class_extract_field_descriptor(receiver, privateMap, action) {
|
|
658
|
+
if (!privateMap.has(receiver)) throw TypeError("attempted to " + action + " private field on non-instance");
|
|
659
|
+
return privateMap.get(receiver);
|
|
660
|
+
}
|
|
661
|
+
function _class_private_field_get(receiver, privateMap) {
|
|
662
|
+
var descriptor = _class_extract_field_descriptor(receiver, privateMap, "get");
|
|
663
|
+
return descriptor.get ? descriptor.get.call(receiver) : descriptor.value;
|
|
664
|
+
}
|
|
665
|
+
function _class_private_field_init(obj, privateMap, value) {
|
|
666
|
+
_check_private_redeclaration(obj, privateMap), privateMap.set(obj, value);
|
|
667
|
+
}
|
|
668
|
+
function _class_private_field_set(receiver, privateMap, value) {
|
|
669
|
+
var descriptor = _class_extract_field_descriptor(receiver, privateMap, "set");
|
|
670
|
+
if (descriptor.set) descriptor.set.call(receiver, value);
|
|
671
|
+
else {
|
|
672
|
+
if (!descriptor.writable) throw TypeError("attempted to set read only private field");
|
|
673
|
+
descriptor.value = value;
|
|
406
674
|
}
|
|
407
|
-
return
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
675
|
+
return value;
|
|
676
|
+
}
|
|
677
|
+
function _class_private_method_get(receiver, privateSet, fn) {
|
|
678
|
+
if (!privateSet.has(receiver)) throw TypeError("attempted to get private field on non-instance");
|
|
679
|
+
return fn;
|
|
680
|
+
}
|
|
681
|
+
function _class_private_method_init(obj, privateSet) {
|
|
682
|
+
_check_private_redeclaration(obj, privateSet), privateSet.add(obj);
|
|
683
|
+
}
|
|
684
|
+
function _define_property(obj, key, value) {
|
|
685
|
+
return key in obj ? Object.defineProperty(obj, key, {
|
|
686
|
+
value: value,
|
|
687
|
+
enumerable: !0,
|
|
688
|
+
configurable: !0,
|
|
689
|
+
writable: !0
|
|
690
|
+
}) : obj[key] = value, obj;
|
|
691
|
+
}
|
|
692
|
+
class WorkerStartupError extends Error {
|
|
693
|
+
constructor(message){
|
|
694
|
+
super(message), this.name = 'WorkerStartupError';
|
|
416
695
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
} else if (__rspack_external__babel_types_69e65b52.isRestElement(property)) {
|
|
428
|
-
let argumentPath = currentPath.get(`properties.${i}.argument`);
|
|
429
|
-
isNodePathWithNode(argumentPath) && walk(argumentPath);
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
} else if (currentPath.isArrayPattern()) {
|
|
433
|
-
let { elements } = currentPath.node;
|
|
434
|
-
for(let i = 0; i < elements.length; i++)if (elements[i]) {
|
|
435
|
-
let elementPath = currentPath.get(`elements.${i}`);
|
|
436
|
-
isNodePathWithNode(elementPath) && walk(elementPath);
|
|
437
|
-
}
|
|
438
|
-
} else if (currentPath.isRestElement()) {
|
|
439
|
-
let argumentPath = currentPath.get('argument');
|
|
440
|
-
isNodePathWithNode(argumentPath) && walk(argumentPath);
|
|
441
|
-
}
|
|
442
|
-
}(patternPath), identifiers), getExportedName = (exported)=>__rspack_external__babel_types_69e65b52.isIdentifier(exported) ? exported.name : exported.value, setsIntersect = (set1, set2)=>{
|
|
443
|
-
let smallerSet = set1, largerSet = set2;
|
|
444
|
-
for (let element of (set1.size > set2.size && (smallerSet = set2, largerSet = set1), smallerSet))if (largerSet.has(element)) return !0;
|
|
445
|
-
return !1;
|
|
446
|
-
}, hasChunkableExport = (code, exportName, cache, cacheKey)=>getOrSetFromCache(cache, `${cacheKey}::hasChunkableExport::${exportName}`, code, ()=>{
|
|
447
|
-
let exportDependencies = getExportDependencies(code, cache, cacheKey), dependencies = exportDependencies.get(exportName);
|
|
448
|
-
if (!dependencies) return !1;
|
|
449
|
-
for (let [currentExportName, currentDependencies] of exportDependencies)if (currentExportName !== exportName && setsIntersect(currentDependencies.topLevelNonModuleStatements, dependencies.topLevelNonModuleStatements)) return !1;
|
|
450
|
-
if (dependencies.exportedVariableDeclarators.size > 1) return !1;
|
|
451
|
-
if (dependencies.exportedVariableDeclarators.size > 0) {
|
|
452
|
-
for (let [currentExportName, currentDependencies] of exportDependencies)if (currentExportName !== exportName && setsIntersect(currentDependencies.exportedVariableDeclarators, dependencies.exportedVariableDeclarators)) return !1;
|
|
696
|
+
}
|
|
697
|
+
var _closed = new WeakMap(), _closePromise = new WeakMap(), _workersDisabled = new WeakMap(), _nextId = new WeakMap(), _nextRouteModuleWorkerIndex = new WeakMap(), _nextSplitRouteAnalysisWorkerIndex = new WeakMap(), _splitRouteAnalysisWorkers = new WeakMap(), _workers = new WeakMap(), _disableWorkers = new WeakSet(), _createWorkerState = new WeakSet(), _runInWorker = new WeakSet(), _createWorkerRequestTask = new WeakSet(), _getWorkerIndex = new WeakSet();
|
|
698
|
+
class ParallelRouteTransformExecutor {
|
|
699
|
+
async run(task) {
|
|
700
|
+
if (_class_private_field_get(this, _closed) || 'clientOnlyStub' === task.kind && task.resolveExportAllModule) return executeRouteTransformTask(task, this.options);
|
|
701
|
+
try {
|
|
702
|
+
return await _class_private_method_get(this, _runInWorker, runInWorker).call(this, task);
|
|
703
|
+
} catch (error) {
|
|
704
|
+
if (error instanceof WorkerStartupError) return executeRouteTransformTask(task, this.options);
|
|
705
|
+
throw error;
|
|
453
706
|
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
707
|
+
}
|
|
708
|
+
close() {
|
|
709
|
+
if (_class_private_field_get(this, _closePromise)) return _class_private_field_get(this, _closePromise);
|
|
710
|
+
_class_private_field_set(this, _closed, !0);
|
|
711
|
+
let workers = _class_private_field_get(this, _workers);
|
|
712
|
+
return _class_private_field_set(this, _workers, []), _class_private_field_set(this, _closePromise, Promise.all(workers.map(async (state)=>{
|
|
713
|
+
for (let pending of state.pending.values())pending.reject(Error('Route transform worker closed.'));
|
|
714
|
+
state.pending.clear(), await state.worker.terminate();
|
|
715
|
+
})).then(()=>void 0)), _class_private_field_get(this, _closePromise);
|
|
716
|
+
}
|
|
717
|
+
constructor(workerCount, options, balanceRouteModuleTransforms){
|
|
718
|
+
_class_private_method_init(this, _disableWorkers), _class_private_method_init(this, _createWorkerState), _class_private_method_init(this, _runInWorker), _class_private_method_init(this, _createWorkerRequestTask), _class_private_method_init(this, _getWorkerIndex), _define_property(this, "options", void 0), _define_property(this, "balanceRouteModuleTransforms", void 0), _class_private_field_init(this, _closed, {
|
|
719
|
+
writable: !0,
|
|
720
|
+
value: void 0
|
|
721
|
+
}), _class_private_field_init(this, _closePromise, {
|
|
722
|
+
writable: !0,
|
|
723
|
+
value: void 0
|
|
724
|
+
}), _class_private_field_init(this, _workersDisabled, {
|
|
725
|
+
writable: !0,
|
|
726
|
+
value: void 0
|
|
727
|
+
}), _class_private_field_init(this, _nextId, {
|
|
728
|
+
writable: !0,
|
|
729
|
+
value: void 0
|
|
730
|
+
}), _class_private_field_init(this, _nextRouteModuleWorkerIndex, {
|
|
731
|
+
writable: !0,
|
|
732
|
+
value: void 0
|
|
733
|
+
}), _class_private_field_init(this, _nextSplitRouteAnalysisWorkerIndex, {
|
|
734
|
+
writable: !0,
|
|
735
|
+
value: void 0
|
|
736
|
+
}), _class_private_field_init(this, _splitRouteAnalysisWorkers, {
|
|
737
|
+
writable: !0,
|
|
738
|
+
value: void 0
|
|
739
|
+
}), _class_private_field_init(this, _workers, {
|
|
740
|
+
writable: !0,
|
|
741
|
+
value: void 0
|
|
742
|
+
}), this.options = options, this.balanceRouteModuleTransforms = balanceRouteModuleTransforms, _class_private_field_set(this, _closed, !1), _class_private_field_set(this, _workersDisabled, !1), _class_private_field_set(this, _nextId, 1), _class_private_field_set(this, _nextRouteModuleWorkerIndex, 0), _class_private_field_set(this, _nextSplitRouteAnalysisWorkerIndex, 0), _class_private_field_set(this, _splitRouteAnalysisWorkers, new Map()), _class_private_field_set(this, _workers, []);
|
|
743
|
+
try {
|
|
744
|
+
for(let index = 0; index < workerCount; index += 1)_class_private_field_get(this, _workers).push(_class_private_method_get(this, _createWorkerState, createWorkerState).call(this));
|
|
745
|
+
} catch (error) {
|
|
746
|
+
for (let state of _class_private_field_get(this, _workers))state.worker.terminate();
|
|
747
|
+
throw _class_private_field_set(this, _workers, []), error;
|
|
468
748
|
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
function disableWorkers(error) {
|
|
752
|
+
if (_class_private_field_get(this, _workersDisabled) || _class_private_field_get(this, _closed)) return;
|
|
753
|
+
_class_private_field_set(this, _workersDisabled, !0);
|
|
754
|
+
let workers = _class_private_field_get(this, _workers);
|
|
755
|
+
for (let state of (_class_private_field_set(this, _workers, []), workers)){
|
|
756
|
+
for (let pending of state.pending.values())pending.reject(error);
|
|
757
|
+
state.pending.clear(), state.worker.terminate();
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
function createWorkerState() {
|
|
761
|
+
let worker = new Worker(new URL('./parallel-route-transform-worker.js', import.meta.url)), state = {
|
|
762
|
+
worker,
|
|
763
|
+
pending: new Map(),
|
|
764
|
+
sourceCache: new Map()
|
|
469
765
|
};
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
return !0;
|
|
501
|
-
}), 0 === node.specifiers.length) ? null : node).map((node)=>{
|
|
502
|
-
if (!__rspack_external__babel_types_69e65b52.isExportDeclaration(node) || __rspack_external__babel_types_69e65b52.isExportAllDeclaration(node)) return node;
|
|
503
|
-
if (__rspack_external__babel_types_69e65b52.isExportDefaultDeclaration(node)) return isOmitted('default') ? null : node;
|
|
504
|
-
if (__rspack_external__babel_types_69e65b52.isVariableDeclaration(node.declaration)) return (node.declaration.declarations = node.declaration.declarations.filter((declarationNode)=>omittedExportedVariableDeclaratorsArray.every((declarator)=>!__rspack_external__babel_types_69e65b52.isNodesEquivalent(declarationNode, declarator))), 0 === node.declaration.declarations.length) ? null : node;
|
|
505
|
-
if (__rspack_external__babel_types_69e65b52.isFunctionDeclaration(node.declaration) || __rspack_external__babel_types_69e65b52.isClassDeclaration(node.declaration)) {
|
|
506
|
-
let declarationId = node.declaration.id;
|
|
507
|
-
return invariant(declarationId, 'Expected exported function or class declaration to have a name when not the default export'), isOmitted(declarationId.name) ? null : node;
|
|
766
|
+
return worker.on('message', (response)=>{
|
|
767
|
+
let pending = state.pending.get(response.id);
|
|
768
|
+
if (pending) if (state.pending.delete(response.id), response.ok) pending.resolve(response.result);
|
|
769
|
+
else {
|
|
770
|
+
var error;
|
|
771
|
+
let result;
|
|
772
|
+
pending.reject(((result = Error((error = response.error).message)).name = error.name ?? 'Error', error.stack && (result.stack = error.stack), result));
|
|
773
|
+
}
|
|
774
|
+
}), worker.on('error', (error)=>{
|
|
775
|
+
let startupError = new WorkerStartupError(error.message);
|
|
776
|
+
startupError.stack = error.stack, _class_private_method_get(this, _disableWorkers, disableWorkers).call(this, startupError);
|
|
777
|
+
}), worker.on('exit', (code)=>{
|
|
778
|
+
if (_class_private_field_get(this, _closed) || _class_private_field_get(this, _workersDisabled)) return;
|
|
779
|
+
let startupError = new WorkerStartupError(`Route transform worker exited with code ${code}.`);
|
|
780
|
+
_class_private_method_get(this, _disableWorkers, disableWorkers).call(this, startupError);
|
|
781
|
+
}), state;
|
|
782
|
+
}
|
|
783
|
+
function runInWorker(task) {
|
|
784
|
+
let workerIndex = _class_private_method_get(this, _getWorkerIndex, getWorkerIndex).call(this, task), state = _class_private_field_get(this, _workers)[workerIndex];
|
|
785
|
+
if (!state) return executeRouteTransformTask(task, this.options);
|
|
786
|
+
let id = function(receiver, privateMap) {
|
|
787
|
+
var descriptor = _class_extract_field_descriptor(receiver, privateMap, "update");
|
|
788
|
+
if (descriptor.set) {
|
|
789
|
+
if (!descriptor.get) throw TypeError("attempted to read set only private field");
|
|
790
|
+
return "__destrWrapper" in descriptor || (descriptor.__destrWrapper = {
|
|
791
|
+
set value (v){
|
|
792
|
+
descriptor.set.call(receiver, v);
|
|
793
|
+
},
|
|
794
|
+
get value () {
|
|
795
|
+
return descriptor.get.call(receiver);
|
|
508
796
|
}
|
|
509
|
-
|
|
510
|
-
throw Error('Unknown node type');
|
|
511
|
-
}).filter(Boolean), 0 !== ast.program.body.length) return generate(ast, generateOptions).code;
|
|
512
|
-
}))(code, routeChunkExportNames, {}, cache, cacheKey) : ((code, exportName, generateOptions = {}, cache, cacheKey)=>getOrSetFromCache(cache, `${cacheKey}::getChunkedExport::${exportName}::${JSON.stringify(generateOptions)}`, code, ()=>{
|
|
513
|
-
if (!hasChunkableExport(code, exportName, cache, cacheKey)) return;
|
|
514
|
-
let dependencies = getExportDependencies(code, cache, cacheKey).get(exportName);
|
|
515
|
-
invariant(dependencies, 'Expected export to have dependencies');
|
|
516
|
-
let topLevelStatementsArray = Array.from(dependencies.topLevelStatements), exportedVariableDeclaratorsArray = Array.from(dependencies.exportedVariableDeclarators), ast = codeToAst(code, cache, cacheKey);
|
|
517
|
-
return ast.program.body = ast.program.body.filter((node)=>topLevelStatementsArray.some((statement)=>__rspack_external__babel_types_69e65b52.isNodesEquivalent(node, statement))).map((node)=>__rspack_external__babel_types_69e65b52.isImportDeclaration(node) ? 0 === dependencies.importedIdentifierNames.size ? null : (node.specifiers = node.specifiers.filter((specifier)=>dependencies.importedIdentifierNames.has(specifier.local.name)), invariant(node.specifiers.length > 0, 'Expected import statement to have used specifiers'), node) : node).map((node)=>{
|
|
518
|
-
if (!__rspack_external__babel_types_69e65b52.isExportDeclaration(node)) return node;
|
|
519
|
-
if (__rspack_external__babel_types_69e65b52.isExportAllDeclaration(node)) return null;
|
|
520
|
-
if (__rspack_external__babel_types_69e65b52.isExportDefaultDeclaration(node)) return 'default' === exportName ? node : null;
|
|
521
|
-
let { declaration } = node;
|
|
522
|
-
if (__rspack_external__babel_types_69e65b52.isVariableDeclaration(declaration)) return (declaration.declarations = declaration.declarations.filter((declarationNode)=>exportedVariableDeclaratorsArray.some((declarator)=>__rspack_external__babel_types_69e65b52.isNodesEquivalent(declarationNode, declarator))), 0 === declaration.declarations.length) ? null : node;
|
|
523
|
-
if (__rspack_external__babel_types_69e65b52.isFunctionDeclaration(node.declaration) || __rspack_external__babel_types_69e65b52.isClassDeclaration(node.declaration)) return node.declaration.id?.name === exportName ? node : null;
|
|
524
|
-
if (__rspack_external__babel_types_69e65b52.isExportNamedDeclaration(node)) return 0 === node.specifiers.length || (node.specifiers = node.specifiers.filter((specifier)=>getExportedName(specifier.exported) === exportName), 0 === node.specifiers.length) ? null : node;
|
|
525
|
-
throw Error('Unknown export node type');
|
|
526
|
-
}).filter(Boolean), generate(ast, generateOptions).code;
|
|
527
|
-
}))(code, chunkName, {}, cache, cacheKey)) ?? null;
|
|
528
|
-
}, validateRouteChunks = ({ config, id, valid })=>{
|
|
529
|
-
if (isRootRouteModuleId(config, id)) return;
|
|
530
|
-
let invalidChunks = Object.entries(valid).filter(([, isValid])=>!isValid).map(([chunkName])=>chunkName);
|
|
531
|
-
if (0 === invalidChunks.length) return;
|
|
532
|
-
let plural = invalidChunks.length > 1;
|
|
533
|
-
throw Error([
|
|
534
|
-
`Error splitting route module: ${normalizeRelativeFilePath(id, config.appDirectory)}`,
|
|
535
|
-
invalidChunks.map((name)=>`- ${name}`).join('\n'),
|
|
536
|
-
`${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.`
|
|
537
|
-
].join('\n\n'));
|
|
538
|
-
}, getRouteChunkEntryName = (routeId, chunkName)=>`${routeId}-${routeChunkEntrySuffix[chunkName]}`;
|
|
539
|
-
(A = ImportType || (ImportType = {}))[A.Static = 1] = "Static", A[A.Dynamic = 2] = "Dynamic", A[A.ImportMeta = 3] = "ImportMeta", A[A.StaticSourcePhase = 4] = "StaticSourcePhase", A[A.DynamicSourcePhase = 5] = "DynamicSourcePhase", A[A.StaticDeferPhase = 6] = "StaticDeferPhase", A[A.DynamicDeferPhase = 7] = "DynamicDeferPhase";
|
|
540
|
-
let lexer_A = 1 === new Uint8Array(new Uint16Array([
|
|
541
|
-
1
|
|
542
|
-
]).buffer)[0];
|
|
543
|
-
function lexer_parse(E, g = "@") {
|
|
544
|
-
if (!lexer_C) return lexer_init.then(()=>lexer_parse(E));
|
|
545
|
-
let I = E.length + 1, w = (lexer_C.__heap_base.value || lexer_C.__heap_base) + 4 * I - lexer_C.memory.buffer.byteLength;
|
|
546
|
-
w > 0 && lexer_C.memory.grow(Math.ceil(w / 65536));
|
|
547
|
-
let K = lexer_C.sa(I - 1);
|
|
548
|
-
if ((lexer_A ? function(A, Q) {
|
|
549
|
-
let B = A.length, C = 0;
|
|
550
|
-
for(; C < B;)Q[C] = A.charCodeAt(C++);
|
|
551
|
-
} : function(A, Q) {
|
|
552
|
-
let B = A.length, C = 0;
|
|
553
|
-
for(; C < B;){
|
|
554
|
-
let B = A.charCodeAt(C);
|
|
555
|
-
Q[C++] = (255 & B) << 8 | B >>> 8;
|
|
797
|
+
}), descriptor.__destrWrapper;
|
|
556
798
|
}
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
});
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
n: D,
|
|
565
|
-
t: B,
|
|
566
|
-
s: A,
|
|
567
|
-
e: Q,
|
|
568
|
-
ss: w,
|
|
569
|
-
se: K,
|
|
570
|
-
d: I,
|
|
571
|
-
a: g
|
|
799
|
+
if (!descriptor.writable) throw TypeError("attempted to set read only private field");
|
|
800
|
+
return descriptor;
|
|
801
|
+
}(this, _nextId).value++, sourceCacheKey = task.resourcePath, requestTask = _class_private_method_get(this, _createWorkerRequestTask, createWorkerRequestTask).call(this, state, task, sourceCacheKey);
|
|
802
|
+
return new Promise((resolve, reject)=>{
|
|
803
|
+
state.pending.set(id, {
|
|
804
|
+
resolve,
|
|
805
|
+
reject
|
|
572
806
|
});
|
|
807
|
+
try {
|
|
808
|
+
state.worker.postMessage({
|
|
809
|
+
id,
|
|
810
|
+
task: requestTask,
|
|
811
|
+
sourceCacheKey
|
|
812
|
+
});
|
|
813
|
+
} catch (error) {
|
|
814
|
+
state.pending.delete(id), state.sourceCache.delete(sourceCacheKey), reject(error instanceof Error ? error : Error(String(error)));
|
|
815
|
+
}
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
function createWorkerRequestTask(state, task, sourceCacheKey) {
|
|
819
|
+
if (state.sourceCache.get(sourceCacheKey) === task.code) {
|
|
820
|
+
let { code: _code, ...cachedTask } = task;
|
|
821
|
+
return cachedTask;
|
|
573
822
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
});
|
|
823
|
+
return setBoundedCacheEntry(state.sourceCache, sourceCacheKey, task.code, 2048), task;
|
|
824
|
+
}
|
|
825
|
+
function getWorkerIndex(task) {
|
|
826
|
+
let workerCount = Math.max(1, _class_private_field_get(this, _workers).length);
|
|
827
|
+
if (this.balanceRouteModuleTransforms && ('routeClientEntry' === task.kind || 'routeChunk' === task.kind || 'splitRouteExports' === task.kind)) {
|
|
828
|
+
let existingWorkerIndex = _class_private_field_get(this, _splitRouteAnalysisWorkers).get(task.resourcePath);
|
|
829
|
+
if (void 0 !== existingWorkerIndex) return existingWorkerIndex % workerCount;
|
|
830
|
+
let workerIndex = _class_private_field_get(this, _nextSplitRouteAnalysisWorkerIndex) % workerCount;
|
|
831
|
+
return _class_private_field_set(this, _nextSplitRouteAnalysisWorkerIndex, _class_private_field_get(this, _nextSplitRouteAnalysisWorkerIndex) + 1), _class_private_field_get(this, _splitRouteAnalysisWorkers).set(task.resourcePath, workerIndex), workerIndex;
|
|
584
832
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
} catch (A) {}
|
|
833
|
+
if (this.balanceRouteModuleTransforms && 'routeModule' === task.kind && !('web' === task.environmentName && !task.ssr && task.isSpaMode)) {
|
|
834
|
+
let workerIndex = _class_private_field_get(this, _nextRouteModuleWorkerIndex) % workerCount;
|
|
835
|
+
return _class_private_field_set(this, _nextRouteModuleWorkerIndex, _class_private_field_get(this, _nextRouteModuleWorkerIndex) + 1), workerIndex;
|
|
589
836
|
}
|
|
590
|
-
return
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
];
|
|
837
|
+
return ((value)=>{
|
|
838
|
+
let hash = 0;
|
|
839
|
+
for(let index = 0; index < value.length; index += 1)hash = 31 * hash + value.charCodeAt(index) >>> 0;
|
|
840
|
+
return hash;
|
|
841
|
+
})(task.resourcePath) % workerCount;
|
|
596
842
|
}
|
|
597
|
-
let lexer_init = WebAssembly.compile((A1 = "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GzYCHAtBAEEAKAKwCkECajYCsAoCQAJAAkACQEEAECkiAUHhAEYNACABQfcARg0BQQAoArAKIQEMAgtBACgCsAoiAUECakHACEEKEC8NAUEGIQIMAgtBACgCsAoiAS8BAkHpAEcNACABLwEEQfQARw0AQQQhAiABLwEGQegARg0BC0EAIAFBfmo2ArAKDwtBACABIAJBAXRqNgKwCgJAQQEQKUH7AEYNAEEAIAE2ArAKDwtBACgCsAoiACECA0BBACACQQJqNgKwCgJAAkACQEEBECkiAkEiRg0AIAJBJ0cNAUEnEBpBAEEAKAKwCkECajYCsApBARApIQIMAgtBIhAaQQBBACgCsApBAmo2ArAKQQEQKSECDAELIAIQLCECCwJAIAJBOkYNAEEAIAE2ArAKDwtBAEEAKAKwCkECajYCsAoCQEEBECkiAkEiRg0AIAJBJ0YNAEEAIAE2ArAKDwsgAhAaQQBBACgCsApBAmo2ArAKAkACQEEBECkiAkEsRg0AIAJB/QBGDQFBACABNgKwCg8LQQBBACgCsApBAmo2ArAKQQEQKUH9AEYNAEEAKAKwCiECDAELC0EAKALwCSIBIAA2AhAgAUEAKAKwCkECajYCDAttAQJ/AkACQANAAkAgAEH//wNxIgFBd2oiAkEXSw0AQQEgAnRBn4CABHENAgsgAUGgAUYNASAAIQIgARAoDQJBACECQQBBACgCsAoiAEECajYCsAogAC8BAiIADQAMAgsLIAAhAgsgAkH//wNxC6sBAQR/AkACQEEAKAKwCiICLwEAIgNB4QBGDQAgASEEIAAhBQwBC0EAIAJBBGo2ArAKQQEQKSECQQAoArAKIQUCQAJAIAJBIkYNACACQSdGDQAgAhAsGkEAKAKwCiEEDAELIAIQGkEAQQAoArAKQQJqIgQ2ArAKC0EBECkhA0EAKAKwCiECCwJAIAIgBUYNACAFIARBACAAIAAgAUYiAhtBACABIAIbEAILIAMLcgEEf0EAKAKwCiEAQQAoArQKIQECQAJAA0AgAEECaiECIAAgAU8NAQJAAkAgAi8BACIDQaR/ag4CAQQACyACIQAgA0F2ag4EAgEBAgELIABBBGohAAwACwtBACACNgKwChAlQQAPC0EAIAI2ArAKQd0AC0kBA39BACEDAkAgAkUNAAJAA0AgAC0AACIEIAEtAAAiBUcNASABQQFqIQEgAEEBaiEAIAJBf2oiAg0ADAILCyAEIAVrIQMLIAMLC+wBAgBBgAgLzgEAAHgAcABvAHIAdABtAHAAbwByAHQAZgBvAHIAZQB0AGEAbwB1AHIAYwBlAHIAbwBtAHUAbgBjAHQAaQBvAG4AcwBzAGUAcgB0AHYAbwB5AGkAZQBkAGUAbABlAGMAbwBuAHQAaQBuAGkAbgBzAHQAYQBuAHQAeQBiAHIAZQBhAHIAZQB0AHUAcgBkAGUAYgB1AGcAZwBlAGEAdwBhAGkAdABoAHIAdwBoAGkAbABlAGkAZgBjAGEAdABjAGYAaQBuAGEAbABsAGUAbABzAABB0AkLEAEAAAACAAAAAAQAAEA5AAA=", "u" > typeof Buffer ? Buffer.from(A1, "base64") : Uint8Array.from(atob(A1), (A)=>A.charCodeAt(0)))).then(WebAssembly.instantiate).then(({ exports: A })=>{
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
}, getExportNamesAndExportAll = async (code)=>{
|
|
609
|
-
await lexer_init;
|
|
610
|
-
let [imports, exportSpecifiers] = await lexer_parse(code), exportNames = new Set();
|
|
611
|
-
for (let specifier of exportSpecifiers)specifier.n && exportNames.add(specifier.n);
|
|
612
|
-
let exportAllModules = [];
|
|
613
|
-
for (let entry of imports){
|
|
614
|
-
if (!entry.n) continue;
|
|
615
|
-
let statement = code.slice(entry.ss, entry.se);
|
|
616
|
-
/^\s*export\s*\*\s*from\s*['"]/.test(statement) && exportAllModules.push(entry.n);
|
|
843
|
+
let defaultWatchDirectoryEntry = (directory, onChange, onError)=>{
|
|
844
|
+
let watcher = watch(directory, onChange);
|
|
845
|
+
return watcher.on('error', onError), watcher;
|
|
846
|
+
}, ensureDevRestartMarker = async (restartMarkerPath)=>{
|
|
847
|
+
await mkdir(dirname(restartMarkerPath), {
|
|
848
|
+
recursive: !0
|
|
849
|
+
});
|
|
850
|
+
try {
|
|
851
|
+
await access(restartMarkerPath);
|
|
852
|
+
} catch {
|
|
853
|
+
await writeFile(restartMarkerPath, 'react-router-route-watch');
|
|
617
854
|
}
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
return `${dir}/manifest-${version}.js`;
|
|
633
|
-
};
|
|
634
|
-
async function getReactRouterManifestForDev(routes, options, clientStats, context, assetPrefix = '/', routeChunkOptions) {
|
|
635
|
-
let result = {}, splitRouteModules = routeChunkOptions?.splitRouteModules ?? !1, enforceSplitRouteModules = 'enforce' === splitRouteModules, isBuild = routeChunkOptions?.isBuild ?? !1, routeChunkConfig = splitRouteModules && routeChunkOptions?.rootRouteFile ? {
|
|
636
|
-
splitRouteModules,
|
|
637
|
-
appDirectory: context,
|
|
638
|
-
rootRouteFile: routeChunkOptions.rootRouteFile
|
|
639
|
-
} : null, getAssetsForChunk = (chunkName)=>{
|
|
640
|
-
let assets = clientStats?.assetsByChunkName?.[chunkName];
|
|
641
|
-
return assets ? Array.isArray(assets) ? assets : [
|
|
642
|
-
assets
|
|
643
|
-
] : [];
|
|
644
|
-
}, getModulePathForChunk = (chunkName)=>{
|
|
645
|
-
let jsAssets = getAssetsForChunk(chunkName).filter((asset)=>asset.endsWith('.js'));
|
|
646
|
-
return jsAssets[0] ? combineURLs(assetPrefix, jsAssets[0]) : void 0;
|
|
855
|
+
}, readRouteDirectories = async (watchDirectory)=>{
|
|
856
|
+
let directories = new Set(), walkDirectory = async (directory)=>{
|
|
857
|
+
let entries;
|
|
858
|
+
try {
|
|
859
|
+
entries = await readdir(directory, {
|
|
860
|
+
withFileTypes: !0
|
|
861
|
+
});
|
|
862
|
+
} catch {
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
directories.add(directory), await Promise.all(entries.map(async (entry)=>{
|
|
866
|
+
let entryPath = external_pathe_resolve(directory, entry.name);
|
|
867
|
+
entry.isDirectory() && await walkDirectory(entryPath);
|
|
868
|
+
}));
|
|
647
869
|
};
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
870
|
+
return await walkDirectory(watchDirectory), directories;
|
|
871
|
+
}, createRouteTopologyWatcher = async ({ watchDirectory, getRouteTopology, initialRouteTopology, restartMarkerPath, onError, onRouteTopologyChange, watchDirectoryEntry: watchDirectoryOverride = defaultWatchDirectoryEntry })=>{
|
|
872
|
+
let discoveredState, rescanTimer, discoveredDirectories = await readRouteDirectories(watchDirectory);
|
|
873
|
+
try {
|
|
874
|
+
discoveredState = {
|
|
875
|
+
directories: discoveredDirectories,
|
|
876
|
+
routeTopology: await getRouteTopology()
|
|
654
877
|
};
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
878
|
+
} catch (error) {
|
|
879
|
+
if (!initialRouteTopology) throw error;
|
|
880
|
+
onError(error), discoveredState = {
|
|
881
|
+
directories: discoveredDirectories,
|
|
882
|
+
routeTopology: initialRouteTopology
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
let state = {
|
|
886
|
+
...discoveredState,
|
|
887
|
+
routeTopology: initialRouteTopology ?? discoveredState.routeTopology
|
|
888
|
+
}, closed = !1, rescanQueue = Promise.resolve(), directoryWatchers = new Map(), touchRestartMarker = async ()=>{
|
|
889
|
+
await mkdir(dirname(restartMarkerPath), {
|
|
890
|
+
recursive: !0
|
|
891
|
+
}), await writeFile(restartMarkerPath, String(Date.now()));
|
|
892
|
+
}, syncDirectoryWatchers = (nextDirectories)=>{
|
|
893
|
+
for (let [directory, watcher] of directoryWatchers)nextDirectories.has(directory) || (watcher.close(), directoryWatchers.delete(directory));
|
|
894
|
+
for (let directory of nextDirectories)if (!directoryWatchers.has(directory)) try {
|
|
895
|
+
let watcher;
|
|
896
|
+
watcher = watchDirectoryOverride(directory, scheduleRescan, (error)=>{
|
|
897
|
+
directoryWatchers.get(directory) === watcher && (watcher.close(), directoryWatchers.delete(directory)), onError(error);
|
|
898
|
+
}), directoryWatchers.set(directory, watcher);
|
|
661
899
|
} catch (error) {
|
|
662
|
-
|
|
900
|
+
onError(error);
|
|
663
901
|
}
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
902
|
+
}, applyNextState = async (nextState)=>{
|
|
903
|
+
if (!closed) {
|
|
904
|
+
if (syncDirectoryWatchers(nextState.directories), !((left, right)=>{
|
|
905
|
+
if (left.size !== right.size) return !1;
|
|
906
|
+
for (let value of left)if (!right.has(value)) return !1;
|
|
907
|
+
return !0;
|
|
908
|
+
})(state.routeTopology, nextState.routeTopology)) {
|
|
909
|
+
if (onRouteTopologyChange) {
|
|
910
|
+
state = nextState;
|
|
911
|
+
try {
|
|
912
|
+
Promise.resolve(onRouteTopologyChange()).catch(onError);
|
|
913
|
+
} catch (error) {
|
|
914
|
+
onError(error);
|
|
915
|
+
}
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
918
|
+
if (await touchRestartMarker(), closed) return;
|
|
919
|
+
state = nextState;
|
|
920
|
+
return;
|
|
673
921
|
}
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
922
|
+
state = nextState;
|
|
923
|
+
}
|
|
924
|
+
}, runRescan = async ()=>{
|
|
925
|
+
let nextDirectories;
|
|
926
|
+
if (!closed) try {
|
|
927
|
+
if (nextDirectories = await readRouteDirectories(watchDirectory), closed) return;
|
|
928
|
+
let nextState = {
|
|
929
|
+
directories: nextDirectories,
|
|
930
|
+
routeTopology: await getRouteTopology()
|
|
931
|
+
};
|
|
932
|
+
if (closed) return;
|
|
933
|
+
await applyNextState(nextState);
|
|
934
|
+
} catch (error) {
|
|
935
|
+
nextDirectories && !closed && syncDirectoryWatchers(nextDirectories), onError(error);
|
|
936
|
+
}
|
|
937
|
+
}, scheduleRescan = ()=>{
|
|
938
|
+
rescanTimer && clearTimeout(rescanTimer), rescanTimer = setTimeout(()=>{
|
|
939
|
+
rescanTimer = void 0, rescanQueue = rescanQueue.then(runRescan, runRescan);
|
|
940
|
+
}, 100);
|
|
941
|
+
};
|
|
942
|
+
try {
|
|
943
|
+
await applyNextState(discoveredState);
|
|
944
|
+
} catch (error) {
|
|
945
|
+
onError(error);
|
|
695
946
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
},
|
|
702
|
-
routes: result
|
|
703
|
-
}, version = isBuild ? createHash('md5').update(JSON.stringify(fingerprintedValues)).digest('hex').slice(0, 8) : String(Math.random()), manifestPath = getReactRouterManifestPath({
|
|
704
|
-
version,
|
|
705
|
-
isBuild,
|
|
706
|
-
entryModulePath: entryJsAssets[0]
|
|
707
|
-
});
|
|
708
|
-
return {
|
|
709
|
-
version,
|
|
710
|
-
url: combineURLs(assetPrefix, manifestPath),
|
|
711
|
-
hmr: void 0,
|
|
712
|
-
entry: fingerprintedValues.entry,
|
|
713
|
-
sri: void 0,
|
|
714
|
-
routes: result
|
|
947
|
+
return async ()=>{
|
|
948
|
+
if (closed) return void await rescanQueue;
|
|
949
|
+
for (let watcher of (closed = !0, rescanTimer && clearTimeout(rescanTimer), directoryWatchers.values()))watcher.close();
|
|
950
|
+
for (let watcher of (directoryWatchers.clear(), await rescanQueue, directoryWatchers.values()))watcher.close();
|
|
951
|
+
directoryWatchers.clear();
|
|
715
952
|
};
|
|
716
|
-
}
|
|
717
|
-
let isPlainObject = (value)=>'object' == typeof value && null !== value, validateEntry = (entry, path, issues)=>isPlainObject(entry) && 'then' in entry && 'catch' in entry ? (issues.push(`${path}\nInvalid type: Expected object but received a promise. Did you forget to await?`), !1) : isPlainObject(entry) ? ('string' != typeof entry.file && issues.push(`${path}.file\nInvalid type: Expected string.`), 'id' in entry && 'root' === entry.id && issues.push(`${path}.id\nA route cannot use the reserved id 'root'.`), 'path' in entry && void 0 !== entry.path && 'string' != typeof entry.path && issues.push(`${path}.path\nInvalid type: Expected string.`), 'index' in entry && void 0 !== entry.index && 'boolean' != typeof entry.index && issues.push(`${path}.index\nInvalid type: Expected boolean.`), 'caseSensitive' in entry && void 0 !== entry.caseSensitive && 'boolean' != typeof entry.caseSensitive && issues.push(`${path}.caseSensitive\nInvalid type: Expected boolean.`), 'children' in entry && void 0 !== entry.children && (Array.isArray(entry.children) ? entry.children.forEach((child, index)=>validateEntry(child, `${path}.children.${index}`, issues)) : issues.push(`${path}.children\nInvalid type: Expected array.`)), 0 === issues.length) : (issues.push(`${path}\nInvalid type: Expected object.`), !1), getRouteBranch = (routes, routeId)=>{
|
|
953
|
+
}, isPlainObject = (value)=>'object' == typeof value && null !== value, validateEntry = (entry, path, issues)=>isPlainObject(entry) && 'then' in entry && 'catch' in entry ? (issues.push(`${path}\nInvalid type: Expected object but received a promise. Did you forget to await?`), !1) : isPlainObject(entry) ? ('string' != typeof entry.file && issues.push(`${path}.file\nInvalid type: Expected string.`), 'id' in entry && 'root' === entry.id && issues.push(`${path}.id\nA route cannot use the reserved id 'root'.`), 'path' in entry && void 0 !== entry.path && 'string' != typeof entry.path && issues.push(`${path}.path\nInvalid type: Expected string.`), 'index' in entry && void 0 !== entry.index && 'boolean' != typeof entry.index && issues.push(`${path}.index\nInvalid type: Expected boolean.`), 'caseSensitive' in entry && void 0 !== entry.caseSensitive && 'boolean' != typeof entry.caseSensitive && issues.push(`${path}.caseSensitive\nInvalid type: Expected boolean.`), 'children' in entry && void 0 !== entry.children && (Array.isArray(entry.children) ? entry.children.forEach((child, index)=>validateEntry(child, `${path}.children.${index}`, issues)) : issues.push(`${path}.children\nInvalid type: Expected array.`)), 0 === issues.length) : (issues.push(`${path}\nInvalid type: Expected object.`), !1), getRouteBranch = (routes, routeId)=>{
|
|
718
954
|
let branch = [], current = routeId;
|
|
719
955
|
for(; current;){
|
|
720
956
|
let route = routes[current];
|
|
@@ -728,7 +964,7 @@ let isPlainObject = (value)=>'object' == typeof value && null !== value, validat
|
|
|
728
964
|
routes
|
|
729
965
|
};
|
|
730
966
|
let rootRelativeRoutes = Object.fromEntries(Object.entries(routes).map(([id, route])=>{
|
|
731
|
-
let filePath =
|
|
967
|
+
let filePath = external_pathe_resolve(appDirectory, route.file);
|
|
732
968
|
return [
|
|
733
969
|
id,
|
|
734
970
|
{
|
|
@@ -736,7 +972,7 @@ let isPlainObject = (value)=>'object' == typeof value && null !== value, validat
|
|
|
736
972
|
file: relative(rootDirectory, filePath).replace(/\\/g, '/')
|
|
737
973
|
}
|
|
738
974
|
];
|
|
739
|
-
})), serverBuildDirectory =
|
|
975
|
+
})), serverBuildDirectory = external_pathe_resolve(buildDirectory, 'server'), buildManifest = {
|
|
740
976
|
routes: rootRelativeRoutes,
|
|
741
977
|
serverBundles: {},
|
|
742
978
|
routeIdToServerBundleId: {}
|
|
@@ -759,7 +995,7 @@ let isPlainObject = (value)=>'object' == typeof value && null !== value, validat
|
|
|
759
995
|
return {
|
|
760
996
|
id: (route = {
|
|
761
997
|
...branchRoute,
|
|
762
|
-
file:
|
|
998
|
+
file: external_pathe_resolve(appDirectory, branchRoute.file)
|
|
763
999
|
}).id,
|
|
764
1000
|
path: route.path,
|
|
765
1001
|
file: route.file,
|
|
@@ -773,13 +1009,10 @@ let isPlainObject = (value)=>'object' == typeof value && null !== value, validat
|
|
|
773
1009
|
} else if (!/^[a-zA-Z0-9-_]+$/.test(serverBundleId)) throw Error('The "serverBundles" function must only return strings containing alphanumeric characters, hyphens and underscores.');
|
|
774
1010
|
buildManifest.routeIdToServerBundleId[route.id] = serverBundleId, buildManifest.serverBundles[serverBundleId] ??= {
|
|
775
1011
|
id: serverBundleId,
|
|
776
|
-
file: relative(rootDirectory,
|
|
1012
|
+
file: relative(rootDirectory, external_pathe_resolve(serverBuildDirectory, serverBundleId, serverBuildFile)).replace(/\\/g, '/')
|
|
777
1013
|
};
|
|
778
1014
|
})), buildManifest;
|
|
779
1015
|
};
|
|
780
|
-
function getDevtoolFromRspackConfig(config) {
|
|
781
|
-
if (config && 'function' != typeof config && 'object' == typeof config) return config.devtool;
|
|
782
|
-
}
|
|
783
1016
|
function pluginId(name) {
|
|
784
1017
|
return `rsbuild:${name}`;
|
|
785
1018
|
}
|
|
@@ -795,22 +1028,217 @@ let REACT_ROUTER_EXTERNALS = [
|
|
|
795
1028
|
'@react-router/express',
|
|
796
1029
|
'@react-router/node',
|
|
797
1030
|
'@react-router/serve'
|
|
798
|
-
], requireFromHere = createRequire(import.meta.url)
|
|
1031
|
+
], requireFromHere = createRequire(import.meta.url), roundMs = (value)=>Math.round(10 * value) / 10, VIRTUAL_MODULE_PREFIX = 'virtual/react-router/', isLatestStartedCompilation = (identity, start)=>!identity || start?.status === 'started' && start.identity === identity, hasPendingCompilation = (pair)=>pair.latestWebStart?.status === 'pending' || pair.latestNodeStart?.status === 'pending', snapshotDevChangedFiles = (compiler)=>compiler ? {
|
|
1032
|
+
known: void 0 !== compiler.modifiedFiles || void 0 !== compiler.removedFiles,
|
|
1033
|
+
files: new Set([
|
|
1034
|
+
...compiler.modifiedFiles ?? [],
|
|
1035
|
+
...compiler.removedFiles ?? []
|
|
1036
|
+
])
|
|
1037
|
+
} : {
|
|
1038
|
+
known: !1,
|
|
1039
|
+
files: new Set()
|
|
1040
|
+
}, snapshotDependencies = (compilation)=>({
|
|
1041
|
+
files: new Set([
|
|
1042
|
+
...compilation.fileDependencies,
|
|
1043
|
+
...compilation.buildDependencies ?? []
|
|
1044
|
+
]),
|
|
1045
|
+
contexts: new Set(compilation.contextDependencies),
|
|
1046
|
+
missing: new Set(compilation.missingDependencies)
|
|
1047
|
+
}), isWithinDirectory = (directory, file)=>{
|
|
1048
|
+
let relativePath = external_node_path_relative(directory, file);
|
|
1049
|
+
return '' === relativePath || !relativePath.startsWith('..') && !external_node_path_isAbsolute(relativePath);
|
|
1050
|
+
}, getEnvironmentStats = (stats, name)=>(Array.isArray(stats.stats) ? stats.stats : [
|
|
1051
|
+
stats
|
|
1052
|
+
]).find((child)=>{
|
|
1053
|
+
let compilation = child.compilation;
|
|
1054
|
+
return compilation.name === name || compilation.compiler?.name === name;
|
|
1055
|
+
}), evaluateServerBuild = async (server, entryName)=>resolveServerBuildModule(await server.environments.node.loadBundle(entryName), `Server entry ${JSON.stringify(entryName)}`), evaluateServerBuilds = async (server, entryNames)=>Object.fromEntries(await Promise.all(entryNames.map(async (entryName)=>[
|
|
1056
|
+
entryName,
|
|
1057
|
+
await evaluateServerBuild(server, entryName)
|
|
1058
|
+
]))), pinBuildToManifest = (entryName, build, manifest)=>{
|
|
1059
|
+
for (let [routeId, manifestRoute] of Object.entries(manifest.routes)){
|
|
1060
|
+
let routeModule = build.routes[routeId]?.module;
|
|
1061
|
+
if (!routeModule) throw Error(`[rsbuild-plugin-react-router] Server build ${JSON.stringify(entryName)} route ${JSON.stringify(routeId)} is missing from the evaluated server build.`);
|
|
1062
|
+
if (!!manifestRoute.hasLoader != ('function' == typeof routeModule.loader)) throw Error(`[rsbuild-plugin-react-router] Server build ${JSON.stringify(entryName)} route ${JSON.stringify(routeId)} loader export does not match its web manifest.`);
|
|
1063
|
+
if (!!manifestRoute.hasAction != ('function' == typeof routeModule.action)) throw Error(`[rsbuild-plugin-react-router] Server build ${JSON.stringify(entryName)} route ${JSON.stringify(routeId)} action export does not match its web manifest.`);
|
|
1064
|
+
}
|
|
1065
|
+
return {
|
|
1066
|
+
...build,
|
|
1067
|
+
assets: structuredClone(manifest)
|
|
1068
|
+
};
|
|
1069
|
+
}, collectManifestCssAssetOwnership = (manifest)=>{
|
|
1070
|
+
let ownership = new Set();
|
|
1071
|
+
for (let asset of manifest.entry?.css ?? [])ownership.add(`entry\0${asset}`);
|
|
1072
|
+
for (let [routeId, route] of Object.entries(manifest.routes ?? {}))for (let asset of route.css ?? [])ownership.add(`route\0${routeId}\0${asset}`);
|
|
1073
|
+
return ownership;
|
|
1074
|
+
}, hasRemovedCssAssetOwnership = (previous, next)=>{
|
|
1075
|
+
for (let [entryName, previousManifest] of Object.entries(previous)){
|
|
1076
|
+
let previousOwnership = collectManifestCssAssetOwnership(previousManifest);
|
|
1077
|
+
if (0 === previousOwnership.size) continue;
|
|
1078
|
+
let nextManifest = next[entryName];
|
|
1079
|
+
if (!nextManifest) return !0;
|
|
1080
|
+
let nextOwnership = collectManifestCssAssetOwnership(nextManifest);
|
|
1081
|
+
for (let owner of previousOwnership)if (!nextOwnership.has(owner)) return !0;
|
|
1082
|
+
}
|
|
1083
|
+
return !1;
|
|
1084
|
+
}, normalizeManifestForCssOwnershipCheck = (manifest)=>{
|
|
1085
|
+
let cssAssets = ((manifest)=>{
|
|
1086
|
+
let assets = new Set(manifest.entry?.css ?? []);
|
|
1087
|
+
for (let route of Object.values(manifest.routes ?? {}))for (let asset of route.css ?? [])assets.add(asset);
|
|
1088
|
+
return assets;
|
|
1089
|
+
})(manifest), nonCssImports = (imports = [])=>imports.filter((importPath)=>!cssAssets.has(importPath));
|
|
1090
|
+
return {
|
|
1091
|
+
entry: {
|
|
1092
|
+
imports: nonCssImports(manifest.entry?.imports),
|
|
1093
|
+
module: manifest.entry?.module
|
|
1094
|
+
},
|
|
1095
|
+
routes: Object.fromEntries(Object.entries(manifest.routes ?? {}).sort(([left], [right])=>left.localeCompare(right)).map(([routeId, route])=>[
|
|
1096
|
+
routeId,
|
|
1097
|
+
{
|
|
1098
|
+
caseSensitive: route.caseSensitive,
|
|
1099
|
+
clientActionModule: route.clientActionModule,
|
|
1100
|
+
clientLoaderModule: route.clientLoaderModule,
|
|
1101
|
+
clientMiddlewareModule: route.clientMiddlewareModule,
|
|
1102
|
+
errorBoundary: route.hasErrorBoundary,
|
|
1103
|
+
hasAction: route.hasAction,
|
|
1104
|
+
hasClientAction: route.hasClientAction,
|
|
1105
|
+
hasClientLoader: route.hasClientLoader,
|
|
1106
|
+
hasClientMiddleware: route.hasClientMiddleware,
|
|
1107
|
+
hasDefaultExport: route.hasDefaultExport,
|
|
1108
|
+
hasLoader: route.hasLoader,
|
|
1109
|
+
hydrateFallbackModule: route.hydrateFallbackModule,
|
|
1110
|
+
id: route.id,
|
|
1111
|
+
imports: nonCssImports(route.imports),
|
|
1112
|
+
index: route.index,
|
|
1113
|
+
module: route.module,
|
|
1114
|
+
parentId: route.parentId,
|
|
1115
|
+
path: route.path
|
|
1116
|
+
}
|
|
1117
|
+
]))
|
|
1118
|
+
};
|
|
1119
|
+
}, hasSameRouteMetadata = (previous, next)=>previous.caseSensitive === next.caseSensitive && previous.clientActionModule === next.clientActionModule && previous.clientLoaderModule === next.clientLoaderModule && previous.clientMiddlewareModule === next.clientMiddlewareModule && previous.hasErrorBoundary === next.hasErrorBoundary && previous.hasAction === next.hasAction && previous.hasClientAction === next.hasClientAction && previous.hasClientLoader === next.hasClientLoader && previous.hasClientMiddleware === next.hasClientMiddleware && previous.hasDefaultExport === next.hasDefaultExport && previous.hasLoader === next.hasLoader && previous.hydrateFallbackModule === next.hydrateFallbackModule && previous.id === next.id && previous.index === next.index && previous.parentId === next.parentId && previous.path === next.path, createDeferred = ()=>{
|
|
1120
|
+
let resolve, reject, promise = new Promise((resolvePromise, rejectPromise)=>{
|
|
1121
|
+
resolve = resolvePromise, reject = rejectPromise;
|
|
1122
|
+
});
|
|
1123
|
+
return promise.catch(()=>void 0), {
|
|
1124
|
+
promise,
|
|
1125
|
+
resolve,
|
|
1126
|
+
reject
|
|
1127
|
+
};
|
|
1128
|
+
}, DEV_RUNTIME_KEY = Symbol.for('rsbuild-plugin-react-router.dev-runtime.v1'), loadReactRouterServerBuild = (server, entryName)=>{
|
|
1129
|
+
let runtime = Reflect.get(server, DEV_RUNTIME_KEY);
|
|
1130
|
+
return runtime ? runtime.load(entryName) : Promise.reject(Error('[rsbuild-plugin-react-router] This Rsbuild development server is not registered with the React Router plugin. Add pluginReactRouter() before calling loadReactRouterServerBuild().'));
|
|
1131
|
+
}, config_imports_normalizePath = (filePath)=>external_pathe_resolve(filePath), isNodeModulePath = (filePath)=>filePath.split(/[\\/]/).includes('node_modules'), collectConfigImportWatchPaths = (configPath, moduleCache, previousCacheKeys)=>{
|
|
1132
|
+
let normalizedConfigPath = config_imports_normalizePath(configPath), watchPaths = new Set();
|
|
1133
|
+
for (let [cacheKey, module] of Object.entries(moduleCache)){
|
|
1134
|
+
if (previousCacheKeys.has(cacheKey)) continue;
|
|
1135
|
+
let importPath = config_imports_normalizePath(module?.filename ?? cacheKey);
|
|
1136
|
+
importPath === normalizedConfigPath || isNodeModulePath(importPath) || watchPaths.add(importPath);
|
|
1137
|
+
}
|
|
1138
|
+
return Array.from(watchPaths);
|
|
1139
|
+
};
|
|
799
1140
|
var src_dirname = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
|
|
800
|
-
let
|
|
801
|
-
301,
|
|
802
|
-
302,
|
|
803
|
-
303,
|
|
804
|
-
307,
|
|
805
|
-
308
|
|
806
|
-
]), pluginReactRouter = (options = {})=>({
|
|
1141
|
+
let cssUrlAssetExtensions = /\.(?:css|less|sass|scss|styl|stylus|pcss|postcss|sss)$/, urlAssetResourceQuery = /^(?=.*(?:\?|&)url(?:&|$))(?!.*(?:\?|&)(?:raw|inline)(?:&|$))/, pluginReactRouter = (options = {})=>({
|
|
807
1142
|
name: PLUGIN_NAME,
|
|
808
1143
|
async setup (api) {
|
|
809
|
-
let routeDiscovery, clientStats, pluginOptions = {
|
|
1144
|
+
let routeDiscovery, closeRouteTopologyWatcher, clientStats, typegenProcess, pluginOptions = {
|
|
810
1145
|
customServer: !1,
|
|
811
1146
|
serverOutput: 'module',
|
|
812
1147
|
...options
|
|
813
|
-
},
|
|
1148
|
+
}, logPerformance = !0 === pluginOptions.logPerformance, setupStartMs = logPerformance ? performance.now() : 0, performanceProfiler = (({ enabled, log })=>{
|
|
1149
|
+
let timingsByEnvironment = new Map(), recordDuration = (environment, operation, resource, startMs, endMs)=>{
|
|
1150
|
+
let timings, timing, duration = endMs - startMs, timing1 = ((timings = timingsByEnvironment.get(environment)) || (timings = new Map(), timingsByEnvironment.set(environment, timings)), (timing = timings.get(operation)) || (timing = {
|
|
1151
|
+
count: 0,
|
|
1152
|
+
totalMs: 0,
|
|
1153
|
+
maxMs: 0,
|
|
1154
|
+
slowest: [],
|
|
1155
|
+
intervals: []
|
|
1156
|
+
}, timings.set(operation, timing)), timing);
|
|
1157
|
+
timing1.count += 1, timing1.totalMs += duration, timing1.maxMs = Math.max(timing1.maxMs, duration), timing1.intervals.push({
|
|
1158
|
+
startMs,
|
|
1159
|
+
endMs
|
|
1160
|
+
}), ((slowest, entry)=>{
|
|
1161
|
+
if (5 === slowest.length && entry.durationMs <= slowest[slowest.length - 1].durationMs) return;
|
|
1162
|
+
let insertIndex = slowest.length;
|
|
1163
|
+
for(; insertIndex > 0 && entry.durationMs > slowest[insertIndex - 1].durationMs;)insertIndex -= 1;
|
|
1164
|
+
slowest.splice(insertIndex, 0, entry), slowest.length > 5 && slowest.pop();
|
|
1165
|
+
})(timing1.slowest, {
|
|
1166
|
+
durationMs: duration,
|
|
1167
|
+
resource
|
|
1168
|
+
});
|
|
1169
|
+
};
|
|
1170
|
+
return {
|
|
1171
|
+
record (environment, operation, resource, callback) {
|
|
1172
|
+
if (!enabled) try {
|
|
1173
|
+
return Promise.resolve(callback());
|
|
1174
|
+
} catch (error) {
|
|
1175
|
+
return Promise.reject(error);
|
|
1176
|
+
}
|
|
1177
|
+
let resolvedEnvironment = environment ?? 'unknown', start = performance.now();
|
|
1178
|
+
try {
|
|
1179
|
+
return callback().then((result)=>{
|
|
1180
|
+
let end = performance.now();
|
|
1181
|
+
return recordDuration(resolvedEnvironment, operation, resource, start, end), result;
|
|
1182
|
+
}, (error)=>{
|
|
1183
|
+
let end = performance.now();
|
|
1184
|
+
throw recordDuration(resolvedEnvironment, operation, resource, start, end), error;
|
|
1185
|
+
});
|
|
1186
|
+
} catch (error) {
|
|
1187
|
+
return recordDuration(resolvedEnvironment, operation, resource, start, performance.now()), Promise.reject(error);
|
|
1188
|
+
}
|
|
1189
|
+
},
|
|
1190
|
+
recordSync (environment, operation, resource, callback) {
|
|
1191
|
+
if (!enabled) return callback();
|
|
1192
|
+
let start = performance.now();
|
|
1193
|
+
try {
|
|
1194
|
+
return callback();
|
|
1195
|
+
} finally{
|
|
1196
|
+
recordDuration(environment ?? 'unknown', operation, resource, start, performance.now());
|
|
1197
|
+
}
|
|
1198
|
+
},
|
|
1199
|
+
flush (environment, details = {}) {
|
|
1200
|
+
if (!enabled) return;
|
|
1201
|
+
let resolvedEnvironment = environment ?? 'unknown', timings = timingsByEnvironment.get(resolvedEnvironment);
|
|
1202
|
+
if (!timings || 0 === timings.size) return;
|
|
1203
|
+
let operations = Object.fromEntries([
|
|
1204
|
+
...timings.entries()
|
|
1205
|
+
].map(([operation, timing])=>[
|
|
1206
|
+
operation,
|
|
1207
|
+
{
|
|
1208
|
+
count: timing.count,
|
|
1209
|
+
totalMs: roundMs(timing.totalMs),
|
|
1210
|
+
wallMs: ((intervals)=>{
|
|
1211
|
+
if (0 === intervals.length) return 0;
|
|
1212
|
+
let sortedIntervals = [
|
|
1213
|
+
...intervals
|
|
1214
|
+
].sort((a, b)=>a.startMs - b.startMs || a.endMs - b.endMs), mergedStart = sortedIntervals[0].startMs, mergedEnd = sortedIntervals[0].endMs, wallMs = 0;
|
|
1215
|
+
for (let interval of sortedIntervals.slice(1)){
|
|
1216
|
+
if (interval.startMs <= mergedEnd) {
|
|
1217
|
+
mergedEnd = Math.max(mergedEnd, interval.endMs);
|
|
1218
|
+
continue;
|
|
1219
|
+
}
|
|
1220
|
+
wallMs += mergedEnd - mergedStart, mergedStart = interval.startMs, mergedEnd = interval.endMs;
|
|
1221
|
+
}
|
|
1222
|
+
return roundMs(wallMs += mergedEnd - mergedStart);
|
|
1223
|
+
})(timing.intervals),
|
|
1224
|
+
maxMs: roundMs(timing.maxMs),
|
|
1225
|
+
slowest: timing.slowest.map((entry)=>({
|
|
1226
|
+
durationMs: roundMs(entry.durationMs),
|
|
1227
|
+
resource: entry.resource
|
|
1228
|
+
}))
|
|
1229
|
+
}
|
|
1230
|
+
])), report = {
|
|
1231
|
+
environment: resolvedEnvironment,
|
|
1232
|
+
...details,
|
|
1233
|
+
operations
|
|
1234
|
+
};
|
|
1235
|
+
log(`[react-router:performance] ${JSON.stringify(report)}`), timingsByEnvironment.delete(resolvedEnvironment);
|
|
1236
|
+
}
|
|
1237
|
+
};
|
|
1238
|
+
})({
|
|
1239
|
+
enabled: logPerformance,
|
|
1240
|
+
log: (message)=>api.logger.info(message)
|
|
1241
|
+
}), nodeExternals = Array.from(new Set([
|
|
814
1242
|
'express',
|
|
815
1243
|
...function(rootDirectory) {
|
|
816
1244
|
let externals = [];
|
|
@@ -877,11 +1305,11 @@ let redirectStatusCodes = new Set([
|
|
|
877
1305
|
let envTools = normalized.environments?.[clientEnvName]?.tools?.rspack, rootTools = normalized.tools?.rspack;
|
|
878
1306
|
return getDevtoolFromRspackConfig(envTools) ?? getDevtoolFromRspackConfig(rootTools);
|
|
879
1307
|
}(normalized, clientEnvName);
|
|
880
|
-
(
|
|
1308
|
+
(isSourceMapEnabled(sourceMapSetting) || !0 === devtoolSetting || null != devtoolSetting && !1 !== devtoolSetting && ('string' == typeof devtoolSetting ? devtoolSetting.includes('source-map') : 'object' == typeof devtoolSetting)) && warn("\n WARNING: Source maps are enabled in production\n This makes your server code publicly visible in the browser.\n This is highly discouraged! If you insist, ensure that you are using\n environment variables for secrets and not hard-coding them in your source code.\n");
|
|
881
1309
|
}(api.getNormalizedConfig(), (msg)=>api.logger.warn(msg), 'web');
|
|
882
1310
|
}), api.onBeforeStartDevServer(async ()=>{
|
|
883
|
-
|
|
884
|
-
execa('npx', [
|
|
1311
|
+
if (typegenProcess) return;
|
|
1312
|
+
let { execa } = await import("execa"), process1 = execa('npx', [
|
|
885
1313
|
'--yes',
|
|
886
1314
|
'react-router',
|
|
887
1315
|
'typegen',
|
|
@@ -890,7 +1318,13 @@ let redirectStatusCodes = new Set([
|
|
|
890
1318
|
stdio: 'inherit',
|
|
891
1319
|
detached: !1,
|
|
892
1320
|
cleanup: !0
|
|
893
|
-
})
|
|
1321
|
+
});
|
|
1322
|
+
typegenProcess = process1, process1.catch(()=>{}).finally(()=>{
|
|
1323
|
+
typegenProcess === process1 && (typegenProcess = void 0);
|
|
1324
|
+
});
|
|
1325
|
+
}), api.onCloseDevServer(async ()=>{
|
|
1326
|
+
let process1 = typegenProcess;
|
|
1327
|
+
typegenProcess = void 0, process1 && (process1.kill('SIGTERM'), await process1.catch(()=>void 0));
|
|
894
1328
|
}), api.onBeforeBuild(async ()=>{
|
|
895
1329
|
let { execa } = await import("execa");
|
|
896
1330
|
await execa('npx', [
|
|
@@ -901,29 +1335,48 @@ let redirectStatusCodes = new Set([
|
|
|
901
1335
|
stdio: 'inherit'
|
|
902
1336
|
});
|
|
903
1337
|
});
|
|
904
|
-
let
|
|
1338
|
+
let configPath = findEntryFile(external_pathe_resolve('react-router.config')), configExists = existsSync(configPath), configWatchPaths = configExists ? configPath : JS_EXTENSIONS.map((extension)=>external_pathe_resolve(`react-router.config${extension}`)), reactRouterUserConfig = {};
|
|
905
1339
|
if (configExists) {
|
|
906
|
-
let displayPath = relative(process.cwd(), configPath)
|
|
1340
|
+
let displayPath = relative(process.cwd(), configPath), configJiti = createJiti(process.cwd(), {
|
|
1341
|
+
moduleCache: !0
|
|
1342
|
+
}), cacheKeysBeforeImport = new Set(Object.keys(configJiti.cache));
|
|
907
1343
|
try {
|
|
908
|
-
let imported = await
|
|
1344
|
+
let imported = await configJiti.import(configPath, {
|
|
909
1345
|
default: !0
|
|
910
|
-
});
|
|
911
|
-
if (
|
|
1346
|
+
}), importedConfigPaths = collectConfigImportWatchPaths(configPath, configJiti.cache, cacheKeysBeforeImport);
|
|
1347
|
+
if (importedConfigPaths.length > 0 && (configWatchPaths = [
|
|
1348
|
+
configPath,
|
|
1349
|
+
...importedConfigPaths
|
|
1350
|
+
]), void 0 === imported) throw Error(`${displayPath} must provide a default export`);
|
|
912
1351
|
if ('object' != typeof imported) throw Error(`${displayPath} must export a config`);
|
|
913
1352
|
reactRouterUserConfig = imported;
|
|
914
1353
|
} catch (error) {
|
|
915
1354
|
throw Error(`Error loading ${displayPath}: ${error}`);
|
|
1355
|
+
} finally{
|
|
1356
|
+
((moduleCache, filePaths)=>{
|
|
1357
|
+
let normalizedFilePaths = new Set(filePaths.map(config_imports_normalizePath));
|
|
1358
|
+
for (let [cacheKey, module] of Object.entries(moduleCache)){
|
|
1359
|
+
let cachedPath = config_imports_normalizePath(module?.filename ?? cacheKey);
|
|
1360
|
+
normalizedFilePaths.has(cachedPath) && delete moduleCache[cacheKey];
|
|
1361
|
+
}
|
|
1362
|
+
})(configJiti.cache, [
|
|
1363
|
+
configPath,
|
|
1364
|
+
...collectConfigImportWatchPaths(configPath, configJiti.cache, cacheKeysBeforeImport)
|
|
1365
|
+
]);
|
|
916
1366
|
}
|
|
917
1367
|
} else console.warn('No react-router.config found, using default configuration.');
|
|
918
|
-
let
|
|
919
|
-
|
|
1368
|
+
let jiti = createJiti(process.cwd(), {
|
|
1369
|
+
moduleCache: !1
|
|
1370
|
+
}), { resolved: resolvedConfig, presets: configPresets, hasConfiguredServerModuleFormat } = await resolveReactRouterConfig(reactRouterUserConfig), { appDirectory, basename, buildDirectory, future, allowedActionOrigins, routeDiscovery: userRouteDiscovery, ssr, prerender: prerenderConfig, serverBuildFile, serverModuleFormat, splitRouteModules, buildEnd } = resolvedConfig, hasExplicitServerOutput = Object.prototype.hasOwnProperty.call(options, 'serverOutput'), resolvedServerOutput = pluginOptions.serverOutput;
|
|
1371
|
+
if (hasExplicitServerOutput || (resolvedServerOutput = 'cjs' === serverModuleFormat ? 'commonjs' : 'module'), hasExplicitServerOutput && hasConfiguredServerModuleFormat && serverModuleFormat && ('commonjs' === resolvedServerOutput ? 'cjs' : 'esm') !== serverModuleFormat && api.logger.warn(`[${PLUGIN_NAME}] Both \`serverOutput\` and \`serverModuleFormat\` are set. Using \`serverOutput=${resolvedServerOutput}\` and ignoring \`serverModuleFormat=${serverModuleFormat}\`.`), serverBuildFile && !serverBuildFile.endsWith('.js')) throw Error('The `serverBuildFile` config must end in `.js`.');
|
|
920
1372
|
if ('esm' !== serverModuleFormat && 'cjs' !== serverModuleFormat) throw Error('The `serverModuleFormat` config must be "esm" or "cjs".');
|
|
921
|
-
serverBundles && api.logger.warn(`[${PLUGIN_NAME}] \`serverBundles\` is configured. Rsbuild currently emits a single server bundle, but the build manifest will include the server bundle mapping for compatibility.`);
|
|
922
1373
|
let prerenderConfigError = ((prerender)=>{
|
|
1374
|
+
let value;
|
|
923
1375
|
if (!prerender) return null;
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
1376
|
+
let config = getPrerenderConfigObject(prerender);
|
|
1377
|
+
if (!('boolean' == typeof (value = config && 'paths' in config ? config.paths : prerender) || 'function' == typeof value || Array.isArray(value))) return 'The `prerender`/`prerender.paths` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths.';
|
|
1378
|
+
let concurrency = getPrerenderConcurrencyConfig(config);
|
|
1379
|
+
return concurrency && (!Number.isInteger(concurrency.value) || concurrency.value <= 0) ? `The \`${concurrency.key}\` config must be a positive integer if specified.` : null;
|
|
927
1380
|
})(prerenderConfig);
|
|
928
1381
|
if (prerenderConfigError) throw Error(prerenderConfigError);
|
|
929
1382
|
if (userRouteDiscovery) {
|
|
@@ -940,62 +1393,76 @@ let redirectStatusCodes = new Set([
|
|
|
940
1393
|
} : {
|
|
941
1394
|
mode: 'initial'
|
|
942
1395
|
};
|
|
943
|
-
globalThis.__reactRouterAppDirectory =
|
|
944
|
-
let routesPath = findEntryFile(
|
|
1396
|
+
globalThis.__reactRouterAppDirectory = external_pathe_resolve(appDirectory);
|
|
1397
|
+
let routesPath = findEntryFile(external_pathe_resolve(appDirectory, 'routes'));
|
|
945
1398
|
if (!existsSync(routesPath)) throw Error(`Route config file not found at "${relative(process.cwd(), routesPath)}".`);
|
|
946
|
-
let
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1399
|
+
let loadRouteConfig = async ()=>{
|
|
1400
|
+
let routeConfigExport = await jiti.import(routesPath, {
|
|
1401
|
+
default: !0
|
|
1402
|
+
}), routeConfigValue = await routeConfigExport, validation = (({ routeConfigFile, routeConfig })=>{
|
|
1403
|
+
if (!routeConfig) return {
|
|
1404
|
+
valid: !1,
|
|
1405
|
+
message: `Route config must be the default export in "${routeConfigFile}".`
|
|
1406
|
+
};
|
|
1407
|
+
if (!Array.isArray(routeConfig)) return {
|
|
1408
|
+
valid: !1,
|
|
1409
|
+
message: `Route config in "${routeConfigFile}" must be an array.`
|
|
1410
|
+
};
|
|
1411
|
+
let issues = [];
|
|
1412
|
+
return (routeConfig.forEach((entry, index)=>validateEntry(entry, `routes.${index}`, issues)), issues.length > 0) ? {
|
|
1413
|
+
valid: !1,
|
|
1414
|
+
message: [
|
|
1415
|
+
`Route config in "${routeConfigFile}" is invalid.`,
|
|
1416
|
+
issues.join('\n\n')
|
|
1417
|
+
].join('\n\n')
|
|
1418
|
+
} : {
|
|
1419
|
+
valid: !0,
|
|
1420
|
+
routeConfig: routeConfig
|
|
1421
|
+
};
|
|
1422
|
+
})({
|
|
1423
|
+
routeConfigFile: relative(process.cwd(), routesPath),
|
|
1424
|
+
routeConfig: routeConfigValue
|
|
1425
|
+
});
|
|
1426
|
+
if (!validation.valid) throw Error(validation.message);
|
|
1427
|
+
return validation.routeConfig;
|
|
1428
|
+
}, routeConfig = await loadRouteConfig(), entryClientPath = findEntryFile(external_pathe_resolve(appDirectory, 'entry.client')), entryServerPath = findEntryFile(external_pathe_resolve(appDirectory, 'entry.server')), serverAppPath = findEntryFile(external_pathe_resolve(appDirectory, '../server/index')), hasServerApp = existsSync(serverAppPath), devServerBuildEntryName = hasServerApp ? 'static/js/react-router-server-build' : 'static/js/app', templateDir = external_pathe_resolve(src_dirname, 'templates'), templateClientPath = external_pathe_resolve(templateDir, 'entry.client.js'), templateServerPath = external_pathe_resolve(templateDir, 'entry.server.js'), finalEntryClientPath = existsSync(entryClientPath) ? entryClientPath : templateClientPath, finalEntryServerPath = existsSync(entryServerPath) ? entryServerPath : templateServerPath, rootRoutePath = findEntryFile(external_pathe_resolve(appDirectory, 'root')), rootRouteFile = relative(appDirectory, rootRoutePath), createRouteTopologySnapshot = (routeFile, routeConfig)=>{
|
|
1429
|
+
let routes;
|
|
1430
|
+
return new Set((Array.isArray(routes = [
|
|
1431
|
+
[
|
|
1432
|
+
'root',
|
|
1433
|
+
{
|
|
1434
|
+
path: '',
|
|
1435
|
+
id: 'root',
|
|
1436
|
+
file: routeFile
|
|
1437
|
+
}
|
|
1438
|
+
],
|
|
1439
|
+
...configRoutesToRouteManifestEntries(appDirectory, routeConfig)
|
|
1440
|
+
]) ? routes : Object.entries(routes)).map(([routeId, route], order)=>JSON.stringify([
|
|
1441
|
+
order,
|
|
1442
|
+
routeId,
|
|
1443
|
+
route.id,
|
|
1444
|
+
route.parentId ?? null,
|
|
1445
|
+
route.path ?? null,
|
|
1446
|
+
route.index ?? null,
|
|
1447
|
+
route.caseSensitive ?? null,
|
|
1448
|
+
route.file
|
|
1449
|
+
])));
|
|
1450
|
+
}, getWatchedRouteTopology = async ()=>{
|
|
1451
|
+
let latestRouteConfig = await loadRouteConfig();
|
|
1452
|
+
return createRouteTopologySnapshot(relative(appDirectory, findEntryFile(external_pathe_resolve(appDirectory, 'root'))), latestRouteConfig);
|
|
1453
|
+
}, routes = {
|
|
974
1454
|
root: {
|
|
975
1455
|
path: '',
|
|
976
1456
|
id: 'root',
|
|
977
1457
|
file: rootRouteFile
|
|
978
1458
|
},
|
|
979
1459
|
...function(appDirectory, routes, rootId = 'root') {
|
|
980
|
-
|
|
981
|
-
for (let route of routes)!function walk(route, parentId) {
|
|
982
|
-
let id = route.id || normalize(route.file.replace(/\.[^/.]+$/, '')), manifestItem = {
|
|
983
|
-
id,
|
|
984
|
-
parentId,
|
|
985
|
-
file: isAbsolute(route.file) ? relative(appDirectory, route.file) : route.file,
|
|
986
|
-
path: route.path,
|
|
987
|
-
index: route.index,
|
|
988
|
-
caseSensitive: route.caseSensitive
|
|
989
|
-
};
|
|
990
|
-
if (Object.prototype.hasOwnProperty.call(routeManifest, id)) throw Error(`Unable to define routes with duplicate route id: "${id}"`);
|
|
991
|
-
if (routeManifest[id] = manifestItem, route.children) for (let child of route.children)walk(child, id);
|
|
992
|
-
}(route, rootId);
|
|
993
|
-
return routeManifest;
|
|
1460
|
+
return Object.fromEntries(configRoutesToRouteManifestEntries(appDirectory, routes, rootId));
|
|
994
1461
|
}(appDirectory, routeConfig)
|
|
995
1462
|
}, resolvedConfigWithRoutes = {
|
|
996
1463
|
...resolvedConfig,
|
|
997
|
-
appDirectory:
|
|
998
|
-
buildDirectory:
|
|
1464
|
+
appDirectory: external_pathe_resolve(appDirectory),
|
|
1465
|
+
buildDirectory: external_pathe_resolve(buildDirectory),
|
|
999
1466
|
routeDiscovery,
|
|
1000
1467
|
prerender: prerenderConfig,
|
|
1001
1468
|
routes,
|
|
@@ -1005,224 +1472,639 @@ let redirectStatusCodes = new Set([
|
|
|
1005
1472
|
for (let preset of configPresets)await preset.reactRouterConfigResolved?.({
|
|
1006
1473
|
reactRouterConfig: resolvedConfigForPreset
|
|
1007
1474
|
});
|
|
1008
|
-
let isBuild = 'build' === api.context.action,
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1475
|
+
let isBuild = 'build' === api.context.action, isPrerenderEnabled = void 0 !== prerenderConfig && !1 !== prerenderConfig, isSpaMode = !ssr && !isPrerenderEnabled, routeCount = Object.keys(routes).length, routeChunkCache = new Map(), routeTransformExecutor = (({ parallelRouteTransform, routeChunkCache, splitRouteModules } = {})=>{
|
|
1476
|
+
let options = {
|
|
1477
|
+
routeChunkCache
|
|
1478
|
+
};
|
|
1479
|
+
if (void 0 === parallelRouteTransform || !1 === parallelRouteTransform) return {
|
|
1480
|
+
run: (task)=>executeRouteTransformTask(task, options),
|
|
1481
|
+
close: async ()=>{}
|
|
1482
|
+
};
|
|
1483
|
+
let workerCount = ((parallelRouteTransform)=>{
|
|
1484
|
+
if (!0 === parallelRouteTransform) return getDefaultConcurrency(void 0);
|
|
1485
|
+
if (!Number.isInteger(parallelRouteTransform) || parallelRouteTransform < 1) throw Error('[react-router] parallelRouteTransform must be true, false, or a positive integer.');
|
|
1486
|
+
return parallelRouteTransform;
|
|
1487
|
+
})(parallelRouteTransform);
|
|
1488
|
+
return workerCount < 1 ? {
|
|
1489
|
+
run: (task)=>executeRouteTransformTask(task, options),
|
|
1490
|
+
close: async ()=>{}
|
|
1491
|
+
} : new ParallelRouteTransformExecutor(workerCount, options, !!splitRouteModules);
|
|
1492
|
+
})({
|
|
1493
|
+
parallelRouteTransform: pluginOptions.parallelRouteTransform ?? routeCount >= 256,
|
|
1494
|
+
routeChunkCache,
|
|
1495
|
+
splitRouteModules: !!splitRouteModules
|
|
1496
|
+
}), routeChunkOptions = {
|
|
1013
1497
|
splitRouteModules,
|
|
1014
1498
|
rootRouteFile,
|
|
1015
1499
|
isBuild,
|
|
1016
1500
|
cache: routeChunkCache
|
|
1017
|
-
},
|
|
1018
|
-
|
|
1501
|
+
}, outputClientPath = external_pathe_resolve(buildDirectory, 'client'), assetsBuildDirectory = relative(process.cwd(), outputClientPath), watchDirectory = external_pathe_resolve(appDirectory), routeRestartMarkerPath = external_pathe_resolve(outputClientPath, '.react-router/route-watch'), routeWatchFiles = [
|
|
1502
|
+
{
|
|
1503
|
+
paths: configWatchPaths,
|
|
1504
|
+
type: 'reload-server'
|
|
1505
|
+
},
|
|
1506
|
+
...pluginOptions.onRouteTopologyChange ? [] : [
|
|
1507
|
+
{
|
|
1508
|
+
paths: routesPath,
|
|
1509
|
+
type: 'reload-server'
|
|
1510
|
+
},
|
|
1511
|
+
{
|
|
1512
|
+
paths: routeRestartMarkerPath,
|
|
1513
|
+
type: 'reload-server'
|
|
1514
|
+
}
|
|
1515
|
+
]
|
|
1516
|
+
];
|
|
1517
|
+
api.onBeforeStartDevServer(async ()=>{
|
|
1518
|
+
await ensureDevRestartMarker(routeRestartMarkerPath), closeRouteTopologyWatcher = await createRouteTopologyWatcher({
|
|
1519
|
+
watchDirectory,
|
|
1520
|
+
getRouteTopology: getWatchedRouteTopology,
|
|
1521
|
+
initialRouteTopology: createRouteTopologySnapshot(rootRouteFile, routeConfig),
|
|
1522
|
+
restartMarkerPath: routeRestartMarkerPath,
|
|
1523
|
+
onRouteTopologyChange: pluginOptions.onRouteTopologyChange,
|
|
1524
|
+
onError: (error)=>{
|
|
1525
|
+
api.logger.warn(`[${PLUGIN_NAME}] Failed to watch route topology changes: ${error}`);
|
|
1526
|
+
}
|
|
1527
|
+
});
|
|
1528
|
+
}), api.onCloseDevServer(async ()=>{
|
|
1529
|
+
await closeRouteTopologyWatcher?.(), closeRouteTopologyWatcher = void 0;
|
|
1530
|
+
}), api.onCloseBuild(async ()=>{
|
|
1531
|
+
await routeTransformExecutor.close();
|
|
1532
|
+
}), api.onCloseDevServer(async ()=>{
|
|
1533
|
+
await routeTransformExecutor.close();
|
|
1534
|
+
});
|
|
1535
|
+
let latestBrowserManifest = null, latestBrowserManifestModuleExports = {}, latestServerManifest = null, latestServerManifestsByBundleId = {}, routeByFilePath = new Map(Object.values(routes).map((route)=>[
|
|
1536
|
+
external_pathe_resolve(appDirectory, route.file),
|
|
1019
1537
|
route
|
|
1020
|
-
])),
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
import: `${routeFilePath}${BUILD_CLIENT_ROUTE_QUERY_STRING}`
|
|
1538
|
+
])), manifestChunkNames = new Set([
|
|
1539
|
+
'entry.client'
|
|
1540
|
+
]), webRouteEntries = Object.values(routes).reduce((acc, route)=>{
|
|
1541
|
+
let entryName = route.file.slice(0, route.file.lastIndexOf('.')), routeFilePath = external_pathe_resolve(appDirectory, route.file);
|
|
1542
|
+
if (manifestChunkNames.add(entryName), acc[entryName] = {
|
|
1543
|
+
import: `${routeFilePath}${BUILD_CLIENT_ROUTE_QUERY_STRING}`,
|
|
1544
|
+
html: !1
|
|
1028
1545
|
}, isBuild && splitRouteModules && 'root' !== route.id) {
|
|
1029
|
-
let source
|
|
1546
|
+
let source;
|
|
1030
1547
|
try {
|
|
1031
1548
|
source = readFileSync(routeFilePath, 'utf8');
|
|
1032
|
-
} catch
|
|
1033
|
-
|
|
1549
|
+
} catch (error) {
|
|
1550
|
+
if ('ENOENT' === error.code) return acc;
|
|
1551
|
+
throw error;
|
|
1552
|
+
}
|
|
1553
|
+
for (let exportName of routeChunkExportNames){
|
|
1554
|
+
if (!source.includes(exportName)) continue;
|
|
1555
|
+
let chunkEntryName = getRouteChunkEntryName(route.id, exportName);
|
|
1556
|
+
manifestChunkNames.add(chunkEntryName), acc[chunkEntryName] = {
|
|
1557
|
+
import: getRouteChunkModuleId(routeFilePath, exportName),
|
|
1558
|
+
html: !1
|
|
1559
|
+
};
|
|
1034
1560
|
}
|
|
1035
|
-
if (source) for (let exportName of routeChunkExportNames)source.includes(exportName) && (acc[getRouteChunkEntryName(route.id, exportName)] = {
|
|
1036
|
-
import: getRouteChunkModuleId(routeFilePath, exportName)
|
|
1037
|
-
});
|
|
1038
1561
|
}
|
|
1039
1562
|
return acc;
|
|
1040
|
-
}, {}),
|
|
1041
|
-
if (!buildManifest || !('routeIdToServerBundleId' in buildManifest)) return {};
|
|
1042
|
-
let routesByServerBundleId = {};
|
|
1043
|
-
for (let [routeId, serverBundleId] of Object.entries(buildManifest.routeIdToServerBundleId))for (let route of (routesByServerBundleId[serverBundleId] ??= {}, getRouteBranch(buildManifest.routes, routeId)))routesByServerBundleId[serverBundleId][route.id] = route;
|
|
1044
|
-
return routesByServerBundleId;
|
|
1045
|
-
})(await getBuildManifest({
|
|
1563
|
+
}, {}), buildManifest = await getBuildManifest({
|
|
1046
1564
|
reactRouterConfig: resolvedConfigWithRoutes,
|
|
1047
1565
|
routes,
|
|
1048
1566
|
rootDirectory: process.cwd()
|
|
1049
|
-
})
|
|
1567
|
+
}), routesByServerBundleId = ((buildManifest, sourceRoutes)=>{
|
|
1568
|
+
if (!buildManifest || !('routeIdToServerBundleId' in buildManifest)) return {};
|
|
1569
|
+
let routesByServerBundleId = {};
|
|
1570
|
+
for (let [routeId, serverBundleId] of Object.entries(buildManifest.routeIdToServerBundleId))for (let route of (routesByServerBundleId[serverBundleId] ??= {}, getRouteBranch(sourceRoutes, routeId)))routesByServerBundleId[serverBundleId][route.id] = route;
|
|
1571
|
+
return routesByServerBundleId;
|
|
1572
|
+
})(buildManifest, routes), serverBuildPlan = (({ routesByServerBundleId, serverBuildFile, defaultEntryName })=>{
|
|
1573
|
+
let serverBuildFileBase = (serverBuildFile || 'index.js').replace(/\.js$/, ''), serverBundleEntries = Object.entries(routesByServerBundleId).filter(([, bundleRoutes])=>!!(bundleRoutes && Object.keys(bundleRoutes).length > 0)).map(([bundleId])=>({
|
|
1574
|
+
bundleId,
|
|
1575
|
+
entryName: `${bundleId}/${serverBuildFileBase}`
|
|
1576
|
+
})), reservedNodeEntryNames = new Set([
|
|
1577
|
+
'static/js/app',
|
|
1578
|
+
'static/js/entry.server',
|
|
1579
|
+
defaultEntryName
|
|
1580
|
+
]);
|
|
1581
|
+
for (let { entryName } of serverBundleEntries){
|
|
1582
|
+
if (reservedNodeEntryNames.has(entryName)) throw Error(`[${PLUGIN_NAME}] Server bundle entry ${JSON.stringify(entryName)} conflicts with a reserved node entry.`);
|
|
1583
|
+
reservedNodeEntryNames.add(entryName);
|
|
1584
|
+
}
|
|
1585
|
+
return {
|
|
1586
|
+
defaultEntryName,
|
|
1587
|
+
entryNames: [
|
|
1588
|
+
defaultEntryName,
|
|
1589
|
+
...serverBundleEntries.map(({ entryName })=>entryName)
|
|
1590
|
+
],
|
|
1591
|
+
serverBundleEntries
|
|
1592
|
+
};
|
|
1593
|
+
})({
|
|
1594
|
+
routesByServerBundleId,
|
|
1595
|
+
serverBuildFile,
|
|
1596
|
+
defaultEntryName: devServerBuildEntryName
|
|
1597
|
+
}), { serverBundleEntries } = serverBuildPlan, devRuntime = (({ api, isBuild, buildPlan })=>{
|
|
1598
|
+
let scheduledCssAssetOwnershipReload, state, nextSessionId, closeObservationByServer, isCurrentBinding, applyCloseOutcome, observeClose, identityByCompilation, webIdentityByNodeCompilation;
|
|
1599
|
+
if (isBuild) return {
|
|
1600
|
+
captureWeb () {},
|
|
1601
|
+
createBuildLoader: ()=>()=>Promise.reject(Error(`[${PLUGIN_NAME}] The development server runtime is unavailable during a production build.`))
|
|
1602
|
+
};
|
|
1603
|
+
let lastCssAssetOwnershipReloadAt = 0, reloadAfterCssAssetOwnershipRemoval = !1, sendCssAssetOwnershipReload = ()=>{
|
|
1604
|
+
let binding = sessions.getActiveBinding();
|
|
1605
|
+
binding && (lastCssAssetOwnershipReloadAt = Date.now(), binding.server.sockWrite('full-reload', {
|
|
1606
|
+
path: '*'
|
|
1607
|
+
}));
|
|
1608
|
+
}, scheduleCssAssetOwnershipReload = ()=>{
|
|
1609
|
+
scheduledCssAssetOwnershipReload && clearTimeout(scheduledCssAssetOwnershipReload);
|
|
1610
|
+
let scheduledAt = Date.now();
|
|
1611
|
+
scheduledCssAssetOwnershipReload = setTimeout(()=>{
|
|
1612
|
+
scheduledCssAssetOwnershipReload = void 0, lastCssAssetOwnershipReloadAt > scheduledAt || sendCssAssetOwnershipReload();
|
|
1613
|
+
}, 1000);
|
|
1614
|
+
}, closeBinding = (binding, error)=>{
|
|
1615
|
+
scheduledCssAssetOwnershipReload && (clearTimeout(scheduledCssAssetOwnershipReload), scheduledCssAssetOwnershipReload = void 0), reloadAfterCssAssetOwnershipRemoval = !1;
|
|
1616
|
+
let pair = binding.compilers;
|
|
1617
|
+
pair && (pair.pendingAttempt = void 0, pair.latestCompletedWebIdentity = void 0, pair.latestWebStart = void 0, pair.latestNodeStart = void 0), binding.compilers = void 0, binding.runtime.close(error);
|
|
1618
|
+
var server = binding.server, runtime = binding.runtime;
|
|
1619
|
+
Reflect.get(server, DEV_RUNTIME_KEY) === runtime && Reflect.deleteProperty(server, DEV_RUNTIME_KEY);
|
|
1620
|
+
}, sessions = (state = {
|
|
1621
|
+
status: 'idle'
|
|
1622
|
+
}, nextSessionId = 1, closeObservationByServer = new WeakMap(), isCurrentBinding = (binding)=>('active' === state.status || 'closing' === state.status) && state.binding === binding, applyCloseOutcome = (observation, outcome)=>{
|
|
1623
|
+
observation.outcome = outcome;
|
|
1624
|
+
let { binding } = observation;
|
|
1625
|
+
if (binding) {
|
|
1626
|
+
if (outcome.ok) isCurrentBinding(binding) && ('active' === state.status && closeBinding(binding), state = {
|
|
1627
|
+
status: 'idle'
|
|
1628
|
+
});
|
|
1629
|
+
else ((binding, cause)=>{
|
|
1630
|
+
if (!isCurrentBinding(binding)) return;
|
|
1631
|
+
let error = Error(`[${PLUGIN_NAME}] The previous development server failed to close. Restart the process before retrying because Rsbuild may not have finished tearing down its compiler and watchers.`, {
|
|
1632
|
+
cause
|
|
1633
|
+
});
|
|
1634
|
+
closeBinding(binding, error), state = {
|
|
1635
|
+
status: 'terminal',
|
|
1636
|
+
error
|
|
1637
|
+
};
|
|
1638
|
+
})(binding, outcome.cause);
|
|
1639
|
+
observation.binding = void 0;
|
|
1640
|
+
}
|
|
1641
|
+
}, observeClose = (server)=>{
|
|
1642
|
+
let existing = closeObservationByServer.get(server);
|
|
1643
|
+
if (existing) return existing;
|
|
1644
|
+
let observation = {}, close = server.close.bind(server);
|
|
1645
|
+
return server.close = ()=>{
|
|
1646
|
+
let closePromise;
|
|
1647
|
+
if (observation.promise) return observation.promise;
|
|
1648
|
+
try {
|
|
1649
|
+
closePromise = close();
|
|
1650
|
+
} catch (cause) {
|
|
1651
|
+
closePromise = Promise.reject(cause);
|
|
1652
|
+
}
|
|
1653
|
+
return observation.promise = closePromise, closePromise.then(()=>applyCloseOutcome(observation, {
|
|
1654
|
+
ok: !0
|
|
1655
|
+
}), (cause)=>applyCloseOutcome(observation, {
|
|
1656
|
+
ok: !1,
|
|
1657
|
+
cause
|
|
1658
|
+
})), closePromise;
|
|
1659
|
+
}, closeObservationByServer.set(server, observation), observation;
|
|
1660
|
+
}, {
|
|
1661
|
+
getState: ()=>state,
|
|
1662
|
+
getActiveBinding: ()=>'active' === state.status ? state.binding : void 0,
|
|
1663
|
+
observeClose (server) {
|
|
1664
|
+
observeClose(server);
|
|
1665
|
+
},
|
|
1666
|
+
assertCanStart () {
|
|
1667
|
+
if ('terminal' === state.status) throw state.error;
|
|
1668
|
+
if ('active' === state.status) throw Error(`[${PLUGIN_NAME}] A development server is already active. Await its close() before calling createDevServer() again. If startup failed before returning the server, restart the process before retrying.`);
|
|
1669
|
+
if ('closing' === state.status) throw Error(`[${PLUGIN_NAME}] The previous development server is still closing. Await its close() before calling createDevServer() again.`);
|
|
1670
|
+
},
|
|
1671
|
+
createBinding (server, runtime) {
|
|
1672
|
+
let binding = {
|
|
1673
|
+
id: nextSessionId++,
|
|
1674
|
+
server,
|
|
1675
|
+
runtime
|
|
1676
|
+
};
|
|
1677
|
+
return state = {
|
|
1678
|
+
status: 'active',
|
|
1679
|
+
binding
|
|
1680
|
+
}, binding;
|
|
1681
|
+
},
|
|
1682
|
+
bindCloseObservation (binding) {
|
|
1683
|
+
let observation = observeClose(binding.server);
|
|
1684
|
+
observation.binding = binding, observation.outcome && applyCloseOutcome(observation, observation.outcome);
|
|
1685
|
+
},
|
|
1686
|
+
markClosing (binding) {
|
|
1687
|
+
isCurrentBinding(binding) && (state = {
|
|
1688
|
+
status: 'closing',
|
|
1689
|
+
binding
|
|
1690
|
+
});
|
|
1691
|
+
},
|
|
1692
|
+
terminate (binding, error) {
|
|
1693
|
+
isCurrentBinding(binding) && (closeBinding(binding, error), state = {
|
|
1694
|
+
status: 'terminal',
|
|
1695
|
+
error
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1698
|
+
}), compilationIdentities = (identityByCompilation = new WeakMap(), webIdentityByNodeCompilation = new WeakMap(), {
|
|
1699
|
+
getCompilationIdentity (compilation) {
|
|
1700
|
+
let existing = identityByCompilation.get(compilation);
|
|
1701
|
+
if (existing) return existing;
|
|
1702
|
+
let identity = Symbol();
|
|
1703
|
+
return identityByCompilation.set(compilation, identity), identity;
|
|
1704
|
+
},
|
|
1705
|
+
getWebIdentityForNodeCompilation: (compilation)=>webIdentityByNodeCompilation.get(compilation),
|
|
1706
|
+
setWebIdentityForNodeCompilation (compilation, identity) {
|
|
1707
|
+
webIdentityByNodeCompilation.set(compilation, identity);
|
|
1708
|
+
}
|
|
1709
|
+
}), { getCompilationIdentity } = compilationIdentities, flushSettledAttempt = (binding, pair)=>{
|
|
1710
|
+
let pending = pair.pendingAttempt;
|
|
1711
|
+
!pending || sessions.getActiveBinding()?.id !== binding.id || !pair.settledCompilations.has(pending.webCompilation) || !pair.settledCompilations.has(pending.nodeCompilation) || (pair.pendingAttempt = void 0, isLatestStartedCompilation(pending.identity.web, pair.latestWebStart) && isLatestStartedCompilation(pending.identity.node, pair.latestNodeStart) && binding.runtime.finishAttempt(pending.stats, pending.changes, pending.identity).catch((cause)=>{
|
|
1712
|
+
sessions.getActiveBinding()?.id === binding.id && binding.runtime.failAttempt(cause instanceof Error ? cause : Error(String(cause)));
|
|
1713
|
+
}));
|
|
1714
|
+
}, rejectUnsupportedCompiler = (reason)=>{
|
|
1715
|
+
let message = `[${PLUGIN_NAME}] Could not coordinate React Router development output because ${reason}.`;
|
|
1716
|
+
api.logger.warn(message);
|
|
1717
|
+
let binding = sessions.getActiveBinding();
|
|
1718
|
+
if (!binding) return;
|
|
1719
|
+
let error = Error(message);
|
|
1720
|
+
sessions.terminate(binding, error);
|
|
1721
|
+
};
|
|
1722
|
+
return api.modifyRsbuildConfig({
|
|
1723
|
+
order: 'post',
|
|
1724
|
+
handler (config) {
|
|
1725
|
+
let existingSetup = config.server?.setup, setup = existingSetup ? Array.isArray(existingSetup) ? existingSetup : [
|
|
1726
|
+
existingSetup
|
|
1727
|
+
] : [];
|
|
1728
|
+
return {
|
|
1729
|
+
...config,
|
|
1730
|
+
server: {
|
|
1731
|
+
...config.server,
|
|
1732
|
+
setup: [
|
|
1733
|
+
(context)=>{
|
|
1734
|
+
'dev' === context.action && sessions.observeClose(context.server);
|
|
1735
|
+
},
|
|
1736
|
+
...setup
|
|
1737
|
+
]
|
|
1738
|
+
}
|
|
1739
|
+
};
|
|
1740
|
+
}
|
|
1741
|
+
}), api.onBeforeStartDevServer({
|
|
1742
|
+
order: 'pre',
|
|
1743
|
+
async handler ({ server }) {
|
|
1744
|
+
sessions.assertCanStart();
|
|
1745
|
+
let runtime = (({ server, buildPlan, onEvaluationError, onCssAssetOwnershipChanged = ()=>void 0, onRouteManifestChanged = ()=>void 0, onWarning = ()=>void 0 })=>{
|
|
1746
|
+
let nextAttemptId = 1, reloadAfterCssRemoval = !1, state = {
|
|
1747
|
+
kind: 'starting',
|
|
1748
|
+
attemptId: 0,
|
|
1749
|
+
readiness: createDeferred()
|
|
1750
|
+
}, manifestsByCompilation = new WeakMap(), notifyCssAssetOwnershipChanged = (change)=>{
|
|
1751
|
+
try {
|
|
1752
|
+
onCssAssetOwnershipChanged(change);
|
|
1753
|
+
} catch (cause) {
|
|
1754
|
+
let reason = cause instanceof Error ? cause.message : String(cause);
|
|
1755
|
+
onWarning(`[rsbuild-plugin-react-router] Failed to notify the browser after CSS asset ownership changed: ${reason}`);
|
|
1756
|
+
}
|
|
1757
|
+
}, uniqueEntryNames = new Set(buildPlan.entryNames);
|
|
1758
|
+
if (uniqueEntryNames.size !== buildPlan.entryNames.length || !uniqueEntryNames.has(buildPlan.defaultEntryName)) throw Error('[rsbuild-plugin-react-router] The development server build plan must contain unique entries and include its default entry.');
|
|
1759
|
+
let selectBuild = (generation, requestedEntryName)=>{
|
|
1760
|
+
let entryName = requestedEntryName ?? buildPlan.defaultEntryName, build = generation.buildsByEntryName[entryName];
|
|
1761
|
+
if (!build) throw Error(`[rsbuild-plugin-react-router] Committed React Router server build ${JSON.stringify(entryName)} was not found.`);
|
|
1762
|
+
return build;
|
|
1763
|
+
}, getCurrentAttemptId = ()=>'starting' === state.kind ? state.attemptId : 'ready' === state.kind ? state.pendingAttemptId : null, rejectAttempt = (attemptId, error, report)=>{
|
|
1764
|
+
if (getCurrentAttemptId() === attemptId) {
|
|
1765
|
+
if ('starting' === state.kind) {
|
|
1766
|
+
let { readiness } = state;
|
|
1767
|
+
state = {
|
|
1768
|
+
kind: 'failed',
|
|
1769
|
+
attemptId,
|
|
1770
|
+
error
|
|
1771
|
+
}, readiness.reject(error);
|
|
1772
|
+
} else 'ready' === state.kind && (state = {
|
|
1773
|
+
...state,
|
|
1774
|
+
pendingAttemptId: null
|
|
1775
|
+
});
|
|
1776
|
+
report && onEvaluationError(error);
|
|
1777
|
+
}
|
|
1778
|
+
};
|
|
1779
|
+
return {
|
|
1780
|
+
beginAttempt () {
|
|
1781
|
+
if ('closed' === state.kind) return;
|
|
1782
|
+
let attemptId = nextAttemptId++;
|
|
1783
|
+
state = 'failed' === state.kind ? {
|
|
1784
|
+
kind: 'starting',
|
|
1785
|
+
attemptId,
|
|
1786
|
+
readiness: createDeferred()
|
|
1787
|
+
} : 'starting' === state.kind ? {
|
|
1788
|
+
...state,
|
|
1789
|
+
attemptId
|
|
1790
|
+
} : {
|
|
1791
|
+
...state,
|
|
1792
|
+
pendingAttemptId: attemptId
|
|
1793
|
+
};
|
|
1794
|
+
},
|
|
1795
|
+
captureWeb (compilation, manifestsByEntryName) {
|
|
1796
|
+
'closed' !== state.kind && manifestsByCompilation.set(compilation, structuredClone(manifestsByEntryName));
|
|
1797
|
+
},
|
|
1798
|
+
async finishAttempt (stats, changes, identity) {
|
|
1799
|
+
var previous;
|
|
1800
|
+
let previousEntryNames, nextEntryNames, side, attemptId = getCurrentAttemptId();
|
|
1801
|
+
if (null === attemptId) return;
|
|
1802
|
+
let webStats = getEnvironmentStats(stats, 'web'), nodeStats = getEnvironmentStats(stats, 'node');
|
|
1803
|
+
if (!webStats || !nodeStats) return void rejectAttempt(attemptId, Error('[rsbuild-plugin-react-router] Development compilation did not provide both web and node results.'), !0);
|
|
1804
|
+
if (webStats.compilation.needAdditionalPass || nodeStats.compilation.needAdditionalPass) return;
|
|
1805
|
+
if (webStats.hasErrors() || nodeStats.hasErrors()) return void rejectAttempt(attemptId, Error('[rsbuild-plugin-react-router] The React Router development compilation failed.'), !1);
|
|
1806
|
+
let webCompilation = webStats.compilation, nodeCompilation = nodeStats.compilation, webIdentity = identity.web, nodeIdentity = identity.node;
|
|
1807
|
+
if (!webIdentity || !nodeIdentity) return void rejectAttempt(attemptId, Error('[rsbuild-plugin-react-router] Development compilation identity was unavailable.'), !0);
|
|
1808
|
+
let previous1 = 'ready' === state.kind ? state.committed : void 0, webChanged = !previous1 || previous1.webIdentity !== webIdentity, nodeChanged = !previous1 || previous1.nodeIdentity !== nodeIdentity;
|
|
1809
|
+
if (!webChanged && !nodeChanged) return;
|
|
1810
|
+
let manifestsByEntryName = webChanged ? manifestsByCompilation.get(webCompilation) : previous1?.web.manifestsByEntryName;
|
|
1811
|
+
if (!manifestsByEntryName) return void rejectAttempt(attemptId, Error('[rsbuild-plugin-react-router] The web compilation completed without a matching React Router manifest. Keeping the last-good development build.'), !0);
|
|
1812
|
+
let cssAssetsRemoved = !!previous1 && webChanged && hasRemovedCssAssetOwnership(previous1.web.manifestsByEntryName, manifestsByEntryName), cssAssetsAdded = !!previous1 && webChanged && hasRemovedCssAssetOwnership(manifestsByEntryName, previous1.web.manifestsByEntryName), cssOnlyWebManifestChange = (cssAssetsRemoved || cssAssetsAdded) && (previous = previous1.web.manifestsByEntryName, previousEntryNames = Object.keys(previous).sort(), nextEntryNames = Object.keys(manifestsByEntryName).sort(), previousEntryNames.join('\0') === nextEntryNames.join('\0') && previousEntryNames.every((entryName)=>{
|
|
1813
|
+
let previousManifest = normalizeManifestForCssOwnershipCheck(previous[entryName]), nextManifest = normalizeManifestForCssOwnershipCheck(manifestsByEntryName[entryName]);
|
|
1814
|
+
return JSON.stringify(previousManifest) === JSON.stringify(nextManifest);
|
|
1815
|
+
})), routeManifestMetadataChanged = !!previous1 && webChanged && ((previous, next)=>{
|
|
1816
|
+
let previousEntryNames = Object.keys(previous);
|
|
1817
|
+
if (previousEntryNames.length !== Object.keys(next).length) return !0;
|
|
1818
|
+
for (let entryName of previousEntryNames){
|
|
1819
|
+
let nextManifest = next[entryName];
|
|
1820
|
+
if (!nextManifest) return !0;
|
|
1821
|
+
let previousRoutes = previous[entryName].routes ?? {}, nextRoutes = nextManifest.routes ?? {}, previousRouteIds = Object.keys(previousRoutes);
|
|
1822
|
+
if (previousRouteIds.length !== Object.keys(nextRoutes).length) return !0;
|
|
1823
|
+
for (let routeId of previousRouteIds){
|
|
1824
|
+
let previousRoute = previousRoutes[routeId], nextRoute = nextRoutes[routeId];
|
|
1825
|
+
if (!nextRoute || !hasSameRouteMetadata(previousRoute, nextRoute)) return !0;
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
return !1;
|
|
1829
|
+
})(previous1.web.manifestsByEntryName, manifestsByEntryName), reusePreviousNodeBuild = !!previous1 && cssOnlyWebManifestChange;
|
|
1830
|
+
if (nodeChanged && identity.nodeWeb !== webIdentity && !reusePreviousNodeBuild) {
|
|
1831
|
+
let message = '[rsbuild-plugin-react-router] Discarded web and node results from different compiler cycles and kept the last-good build.';
|
|
1832
|
+
if (!previous1) return;
|
|
1833
|
+
onWarning(message), rejectAttempt(attemptId, Error(message), !1);
|
|
1834
|
+
return;
|
|
1835
|
+
}
|
|
1836
|
+
let shouldEvaluateNode = nodeChanged && !reusePreviousNodeBuild;
|
|
1837
|
+
if (!(previous1 && webChanged !== shouldEvaluateNode && !cssOnlyWebManifestChange && (side = webChanged ? 'web-only' : 'node-only', !((changes, dependencies)=>{
|
|
1838
|
+
if (!changes.known || 0 === changes.files.size) return !1;
|
|
1839
|
+
for (let file of changes.files){
|
|
1840
|
+
if (dependencies.files.has(file) || dependencies.missing.has(file)) return !1;
|
|
1841
|
+
for (let directory of dependencies.contexts)if (isWithinDirectory(directory, file)) return !1;
|
|
1842
|
+
}
|
|
1843
|
+
return !0;
|
|
1844
|
+
})(webChanged ? changes.web : changes.node, webChanged ? previous1.nodeDependencies : previous1.web.dependencies) && (onWarning(`[rsbuild-plugin-react-router] Discarded an incomplete ${side} development result and kept the last-good build.`), rejectAttempt(attemptId, Error(`Incomplete ${side} development result.`), !1), 1)))) try {
|
|
1845
|
+
let buildsByEntryName = shouldEvaluateNode ? await evaluateServerBuilds(server, buildPlan.entryNames) : previous1.buildsByEntryName;
|
|
1846
|
+
if (getCurrentAttemptId() !== attemptId) return;
|
|
1847
|
+
let web = webChanged ? {
|
|
1848
|
+
manifestsByEntryName,
|
|
1849
|
+
dependencies: snapshotDependencies(webCompilation)
|
|
1850
|
+
} : previous1.web;
|
|
1851
|
+
if (!((attemptId, committed)=>{
|
|
1852
|
+
if (getCurrentAttemptId() !== attemptId) return !1;
|
|
1853
|
+
if ('starting' === state.kind) {
|
|
1854
|
+
let { readiness } = state;
|
|
1855
|
+
state = {
|
|
1856
|
+
kind: 'ready',
|
|
1857
|
+
committed,
|
|
1858
|
+
pendingAttemptId: null
|
|
1859
|
+
}, readiness.resolve(committed);
|
|
1860
|
+
} else 'ready' === state.kind && (state = {
|
|
1861
|
+
kind: 'ready',
|
|
1862
|
+
committed,
|
|
1863
|
+
pendingAttemptId: null
|
|
1864
|
+
});
|
|
1865
|
+
return !0;
|
|
1866
|
+
})(attemptId, {
|
|
1867
|
+
buildsByEntryName: ((builds, entryNames, manifestsByEntryName)=>{
|
|
1868
|
+
let pinned = {};
|
|
1869
|
+
for (let entryName of entryNames){
|
|
1870
|
+
let build = builds[entryName];
|
|
1871
|
+
if (!build) throw Error(`[rsbuild-plugin-react-router] Expected server build ${JSON.stringify(entryName)} was not evaluated.`);
|
|
1872
|
+
let manifest = manifestsByEntryName[entryName];
|
|
1873
|
+
if (!manifest) throw Error(`[rsbuild-plugin-react-router] Server build ${JSON.stringify(entryName)} has no matching web manifest.`);
|
|
1874
|
+
pinned[entryName] = pinBuildToManifest(entryName, build, manifest);
|
|
1875
|
+
}
|
|
1876
|
+
return pinned;
|
|
1877
|
+
})(buildsByEntryName, buildPlan.entryNames, web.manifestsByEntryName),
|
|
1878
|
+
webIdentity,
|
|
1879
|
+
nodeIdentity: shouldEvaluateNode ? nodeIdentity : previous1.nodeIdentity,
|
|
1880
|
+
web,
|
|
1881
|
+
nodeDependencies: shouldEvaluateNode ? snapshotDependencies(nodeCompilation) : previous1.nodeDependencies
|
|
1882
|
+
})) return;
|
|
1883
|
+
cssAssetsRemoved ? (reloadAfterCssRemoval = !cssAssetsAdded, notifyCssAssetOwnershipChanged('removed')) : cssAssetsAdded && (reloadAfterCssRemoval && notifyCssAssetOwnershipChanged('restored'), reloadAfterCssRemoval = !1), routeManifestMetadataChanged && (()=>{
|
|
1884
|
+
try {
|
|
1885
|
+
onRouteManifestChanged();
|
|
1886
|
+
} catch (cause) {
|
|
1887
|
+
let reason = cause instanceof Error ? cause.message : String(cause);
|
|
1888
|
+
onWarning(`[rsbuild-plugin-react-router] Failed to notify the browser after route manifest metadata changed: ${reason}`);
|
|
1889
|
+
}
|
|
1890
|
+
})();
|
|
1891
|
+
} catch (cause) {
|
|
1892
|
+
rejectAttempt(attemptId, cause instanceof Error ? cause : Error(String(cause)), !0);
|
|
1893
|
+
}
|
|
1894
|
+
},
|
|
1895
|
+
failAttempt (error) {
|
|
1896
|
+
let attemptId = getCurrentAttemptId();
|
|
1897
|
+
null !== attemptId && rejectAttempt(attemptId, error, !1);
|
|
1898
|
+
},
|
|
1899
|
+
load (entryName) {
|
|
1900
|
+
if (entryName && !uniqueEntryNames.has(entryName)) return Promise.reject(Error(`[rsbuild-plugin-react-router] React Router server build ${JSON.stringify(entryName)} is not part of this development server build plan.`));
|
|
1901
|
+
if ('ready' === state.kind) return Promise.resolve(selectBuild(state.committed, entryName));
|
|
1902
|
+
if ('starting' === state.kind) {
|
|
1903
|
+
let selected = state.readiness.promise.then((generation)=>selectBuild(generation, entryName));
|
|
1904
|
+
return selected.catch(()=>void 0), selected;
|
|
1905
|
+
}
|
|
1906
|
+
return Promise.reject(state.error);
|
|
1907
|
+
},
|
|
1908
|
+
close (error) {
|
|
1909
|
+
if ('closed' === state.kind) return;
|
|
1910
|
+
let closeError = error ?? Error('[rsbuild-plugin-react-router] The development server closed before a React Router build was ready.');
|
|
1911
|
+
'starting' === state.kind && state.readiness.reject(closeError), state = {
|
|
1912
|
+
kind: 'closed',
|
|
1913
|
+
error: closeError
|
|
1914
|
+
};
|
|
1915
|
+
}
|
|
1916
|
+
};
|
|
1917
|
+
})({
|
|
1918
|
+
server,
|
|
1919
|
+
buildPlan,
|
|
1920
|
+
onEvaluationError (error) {
|
|
1921
|
+
sessions.getActiveBinding()?.runtime === runtime && (api.logger.error(error.message), server.sockWrite('errors', {
|
|
1922
|
+
text: [
|
|
1923
|
+
error.message
|
|
1924
|
+
],
|
|
1925
|
+
html: error.message.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>')
|
|
1926
|
+
}));
|
|
1927
|
+
},
|
|
1928
|
+
onCssAssetOwnershipChanged (change) {
|
|
1929
|
+
sessions.getActiveBinding()?.runtime === runtime && (reloadAfterCssAssetOwnershipRemoval = 'removed' === change, sendCssAssetOwnershipReload());
|
|
1930
|
+
},
|
|
1931
|
+
onRouteManifestChanged () {
|
|
1932
|
+
sessions.getActiveBinding()?.runtime === runtime && server.sockWrite('full-reload', {
|
|
1933
|
+
path: '*'
|
|
1934
|
+
});
|
|
1935
|
+
},
|
|
1936
|
+
onWarning: (message)=>api.logger.warn(message)
|
|
1937
|
+
}), binding = sessions.createBinding(server, runtime);
|
|
1938
|
+
Object.defineProperty(server, DEV_RUNTIME_KEY, {
|
|
1939
|
+
configurable: !0,
|
|
1940
|
+
enumerable: !1,
|
|
1941
|
+
value: runtime
|
|
1942
|
+
}), sessions.bindCloseObservation(binding);
|
|
1943
|
+
}
|
|
1944
|
+
}), api.onCloseDevServer({
|
|
1945
|
+
order: 'pre',
|
|
1946
|
+
handler () {
|
|
1947
|
+
let binding = sessions.getActiveBinding();
|
|
1948
|
+
binding && (closeBinding(binding), sessions.markClosing(binding));
|
|
1949
|
+
}
|
|
1950
|
+
}), api.onBeforeDevCompile({
|
|
1951
|
+
order: 'pre',
|
|
1952
|
+
handler () {
|
|
1953
|
+
let binding = sessions.getActiveBinding(), pair = binding?.compilers;
|
|
1954
|
+
!binding || !pair || hasPendingCompilation(pair) || (pair.pendingAttempt = void 0, binding.runtime.beginAttempt());
|
|
1955
|
+
}
|
|
1956
|
+
}), api.onAfterCreateCompiler(({ compiler })=>{
|
|
1957
|
+
if (!('compilers' in compiler)) return void rejectUnsupportedCompiler('Rsbuild did not create a multi-compiler');
|
|
1958
|
+
let web = compiler.compilers.find((item)=>'web' === item.name), node = compiler.compilers.find((item)=>'node' === item.name);
|
|
1959
|
+
if (!web || !node) return void rejectUnsupportedCompiler('the web or node compiler was missing');
|
|
1960
|
+
let binding = sessions.getActiveBinding();
|
|
1961
|
+
if (!binding) return;
|
|
1962
|
+
let pair = {
|
|
1963
|
+
web,
|
|
1964
|
+
node,
|
|
1965
|
+
settledCompilations: new WeakSet()
|
|
1966
|
+
};
|
|
1967
|
+
binding.compilers = pair;
|
|
1968
|
+
let sessionId = binding.id, runtime = binding.runtime, failCurrentAttempt = (side, error)=>{
|
|
1969
|
+
sessions.getActiveBinding()?.id === sessionId && ('web' === side ? pair.latestWebStart = void 0 : pair.latestNodeStart = void 0, pair.pendingAttempt = void 0, runtime.failAttempt(error));
|
|
1970
|
+
}, beginCompilerAttempt = (side)=>{
|
|
1971
|
+
if (sessions.getActiveBinding()?.id === sessionId && pair[side]?.status !== 'pending') {
|
|
1972
|
+
let attemptAlreadyPending = hasPendingCompilation(pair);
|
|
1973
|
+
pair[side] = {
|
|
1974
|
+
status: 'pending'
|
|
1975
|
+
}, pair.pendingAttempt = void 0, attemptAlreadyPending || runtime.beginAttempt(), 'latestWebStart' === side && reloadAfterCssAssetOwnershipRemoval && (reloadAfterCssAssetOwnershipRemoval = !1, scheduleCssAssetOwnershipReload());
|
|
1976
|
+
}
|
|
1977
|
+
};
|
|
1978
|
+
web.hooks.invalid.tap(`${PLUGIN_NAME}:dev-web-invalid`, ()=>beginCompilerAttempt('latestWebStart')), node.hooks.invalid.tap(`${PLUGIN_NAME}:dev-node-invalid`, ()=>beginCompilerAttempt('latestNodeStart')), web.hooks.done.tap({
|
|
1979
|
+
name: `${PLUGIN_NAME}:dev-web-complete`,
|
|
1980
|
+
stage: -1000
|
|
1981
|
+
}, (stats)=>{
|
|
1982
|
+
sessions.getActiveBinding()?.id === sessionId && (pair.latestCompletedWebIdentity = getCompilationIdentity(stats.compilation));
|
|
1983
|
+
}), web.hooks.thisCompilation.tap(`${PLUGIN_NAME}:dev-web-compilation`, (compilation)=>{
|
|
1984
|
+
sessions.getActiveBinding()?.id === sessionId && (pair.latestWebStart = {
|
|
1985
|
+
status: 'started',
|
|
1986
|
+
identity: getCompilationIdentity(compilation)
|
|
1987
|
+
}, reloadAfterCssAssetOwnershipRemoval && (reloadAfterCssAssetOwnershipRemoval = !1, scheduleCssAssetOwnershipReload()));
|
|
1988
|
+
}), node.hooks.thisCompilation.tap(`${PLUGIN_NAME}:dev-node-web-compilation`, (compilation)=>{
|
|
1989
|
+
sessions.getActiveBinding()?.id === sessionId && (pair.latestNodeStart = {
|
|
1990
|
+
status: 'started',
|
|
1991
|
+
identity: getCompilationIdentity(compilation)
|
|
1992
|
+
}, pair.latestCompletedWebIdentity && compilationIdentities.setWebIdentityForNodeCompilation(compilation, pair.latestCompletedWebIdentity));
|
|
1993
|
+
});
|
|
1994
|
+
let settleCompilation = (stats)=>{
|
|
1995
|
+
sessions.getActiveBinding()?.id === sessionId && (pair.settledCompilations.add(stats.compilation), flushSettledAttempt(binding, pair));
|
|
1996
|
+
};
|
|
1997
|
+
web.hooks.afterDone.tap(`${PLUGIN_NAME}:dev-web-settled`, settleCompilation), node.hooks.afterDone.tap(`${PLUGIN_NAME}:dev-node-settled`, settleCompilation), web.hooks.failed.tap(`${PLUGIN_NAME}:dev-web-failed`, (error)=>failCurrentAttempt('web', error)), node.hooks.failed.tap(`${PLUGIN_NAME}:dev-node-failed`, (error)=>failCurrentAttempt('node', error));
|
|
1998
|
+
}), api.onAfterDevCompile(async ({ stats })=>{
|
|
1999
|
+
let binding = sessions.getActiveBinding(), pair = binding?.compilers;
|
|
2000
|
+
if (!binding || !pair) return;
|
|
2001
|
+
let webStats = getEnvironmentStats(stats, 'web'), nodeStats = getEnvironmentStats(stats, 'node');
|
|
2002
|
+
if (webStats && webStats.compilation.compiler !== pair.web || nodeStats && nodeStats.compilation.compiler !== pair.node) return;
|
|
2003
|
+
let webIdentity = webStats ? getCompilationIdentity(webStats.compilation) : void 0, nodeIdentity = nodeStats ? getCompilationIdentity(nodeStats.compilation) : void 0;
|
|
2004
|
+
if (!isLatestStartedCompilation(webIdentity, pair.latestWebStart) || !isLatestStartedCompilation(nodeIdentity, pair.latestNodeStart)) return;
|
|
2005
|
+
let changes = {
|
|
2006
|
+
web: snapshotDevChangedFiles(pair.web),
|
|
2007
|
+
node: snapshotDevChangedFiles(pair.node)
|
|
2008
|
+
}, identity = {
|
|
2009
|
+
web: webIdentity,
|
|
2010
|
+
node: nodeIdentity,
|
|
2011
|
+
nodeWeb: nodeStats ? compilationIdentities.getWebIdentityForNodeCompilation(nodeStats.compilation) : void 0
|
|
2012
|
+
};
|
|
2013
|
+
webStats && nodeStats ? (pair.pendingAttempt = {
|
|
2014
|
+
stats,
|
|
2015
|
+
changes,
|
|
2016
|
+
identity,
|
|
2017
|
+
webCompilation: webStats.compilation,
|
|
2018
|
+
nodeCompilation: nodeStats.compilation
|
|
2019
|
+
}, flushSettledAttempt(binding, pair)) : await binding.runtime.finishAttempt(stats, changes, identity);
|
|
2020
|
+
}), {
|
|
2021
|
+
captureWeb (compilation, manifestsByEntryName) {
|
|
2022
|
+
let binding = sessions.getActiveBinding();
|
|
2023
|
+
binding?.compilers?.web === compilation.compiler && binding.runtime.captureWeb(compilation, manifestsByEntryName);
|
|
2024
|
+
},
|
|
2025
|
+
createBuildLoader (entryName) {
|
|
2026
|
+
let server = sessions.getActiveBinding()?.server;
|
|
2027
|
+
if (server) return ()=>loadReactRouterServerBuild(server, entryName);
|
|
2028
|
+
let state = sessions.getState();
|
|
2029
|
+
if ('terminal' === state.status) {
|
|
2030
|
+
let { error } = state;
|
|
2031
|
+
return ()=>Promise.reject(error);
|
|
2032
|
+
}
|
|
2033
|
+
return ()=>Promise.reject(Error(`[${PLUGIN_NAME}] The development server runtime is not ready.`));
|
|
2034
|
+
}
|
|
2035
|
+
};
|
|
2036
|
+
})({
|
|
2037
|
+
api,
|
|
2038
|
+
isBuild,
|
|
2039
|
+
buildPlan: serverBuildPlan
|
|
2040
|
+
});
|
|
1050
2041
|
api.onAfterEnvironmentCompile(({ stats, environment })=>{
|
|
1051
|
-
if ('web' === environment.name && (clientStats = stats?.
|
|
1052
|
-
let serverBuildDir =
|
|
2042
|
+
if ('web' === environment.name && (clientStats = createReactRouterManifestStats(stats?.compilation, manifestChunkNames)), pluginOptions.federation && ssr) {
|
|
2043
|
+
let serverBuildDir = external_pathe_resolve(buildDirectory, 'server'), clientBuildDir = external_pathe_resolve(buildDirectory, 'client');
|
|
1053
2044
|
if (existsSync(serverBuildDir)) {
|
|
1054
|
-
let ssrDir =
|
|
2045
|
+
let ssrDir = external_pathe_resolve(clientBuildDir, 'static');
|
|
1055
2046
|
fs_extra.copySync(serverBuildDir, ssrDir);
|
|
1056
2047
|
}
|
|
1057
2048
|
}
|
|
2049
|
+
logPerformance && performanceProfiler.flush(environment.name, {
|
|
2050
|
+
compilerLifecycleMs: roundMs(performance.now() - setupStartMs)
|
|
2051
|
+
});
|
|
1058
2052
|
});
|
|
1059
2053
|
let prerenderPaths = await resolvePrerenderPaths(prerenderConfig, ssr, routeConfig, {
|
|
1060
2054
|
logWarning: !0,
|
|
1061
2055
|
warn: (message)=>api.logger.warn(message)
|
|
1062
|
-
})
|
|
1063
|
-
let grouped = {};
|
|
1064
|
-
return Object.values(manifest).forEach((route)=>{
|
|
1065
|
-
if (!route) return;
|
|
1066
|
-
let parentId = route.parentId || '';
|
|
1067
|
-
grouped[parentId] || (grouped[parentId] = []), grouped[parentId].push(route);
|
|
1068
|
-
}), grouped;
|
|
1069
|
-
}, createPrerenderRoutes = (manifest, parentId = '', grouped = groupRoutesByParentId(manifest))=>(grouped[parentId] || []).map((route)=>{
|
|
1070
|
-
let common = {
|
|
1071
|
-
id: route.id,
|
|
1072
|
-
path: route.path
|
|
1073
|
-
};
|
|
1074
|
-
return route.index ? {
|
|
1075
|
-
index: !0,
|
|
1076
|
-
...common
|
|
1077
|
-
} : {
|
|
1078
|
-
...common,
|
|
1079
|
-
children: createPrerenderRoutes(manifest, route.id, grouped)
|
|
1080
|
-
};
|
|
1081
|
-
}), normalizePrerenderMatchPath = (path)=>`/${path}/`.replace(/^\/\/+/, '/'), prerenderData = async (handler, prerenderPath, onlyRoutes, clientBuildDir, requestInit)=>{
|
|
1082
|
-
let dataRequestPath;
|
|
1083
|
-
dataRequestPath = future?.unstable_trailingSlashAwareDataRequests ? prerenderPath.endsWith('/') ? `${prerenderPath}_.data` : `${prerenderPath}.data` : '/' === prerenderPath ? '/_root.data' : `${prerenderPath.replace(/\/$/, '')}.data`;
|
|
1084
|
-
let normalizedPath = `${basename}${dataRequestPath}`.replace(/\/\/+/g, '/'), url = new URL(`http://localhost${normalizedPath}`);
|
|
1085
|
-
onlyRoutes?.length && url.searchParams.set('_routes', onlyRoutes.join(','));
|
|
1086
|
-
let request = new Request(url, requestInit), response = await handler(request), data = await response.text();
|
|
1087
|
-
if (200 !== response.status && 202 !== response.status) throw Error(`Prerender (data): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${prerenderPath}\` path.\n${normalizedPath}`);
|
|
1088
|
-
let outputPath = resolve(clientBuildDir, ...normalizedPath.split('/'));
|
|
1089
|
-
return await mkdir(dirname(outputPath), {
|
|
1090
|
-
recursive: !0
|
|
1091
|
-
}), await writeFile(outputPath, data), api.logger.info(`Prerender (data): ${prerenderPath} -> ${relative(process.cwd(), outputPath)}`), data;
|
|
1092
|
-
}, prerenderRoute = async (handler, prerenderPath, clientBuildDir, requestInit)=>{
|
|
1093
|
-
let normalizedPath = `${basename}${prerenderPath}/`.replace(/\/\/+/g, '/'), request = new Request(`http://localhost${normalizedPath}`, requestInit), response = await handler(request), html = await response.text();
|
|
1094
|
-
if (redirectStatusCodes.has(response.status)) {
|
|
1095
|
-
let location = response.headers.get('Location'), delay = 2 * (302 === response.status);
|
|
1096
|
-
html = `<!doctype html>
|
|
1097
|
-
<head>
|
|
1098
|
-
<title>Redirecting to: ${location}</title>
|
|
1099
|
-
<meta http-equiv="refresh" content="${delay};url=${location}">
|
|
1100
|
-
<meta name="robots" content="noindex">
|
|
1101
|
-
</head>
|
|
1102
|
-
<body>
|
|
1103
|
-
\t<a href="${location}">
|
|
1104
|
-
Redirecting from <code>${normalizedPath}</code> to <code>${location}</code>
|
|
1105
|
-
</a>
|
|
1106
|
-
</body>
|
|
1107
|
-
</html>`;
|
|
1108
|
-
} else if (200 !== response.status) throw Error(`Prerender (html): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${normalizedPath}\` path.\n` + html);
|
|
1109
|
-
let outputPath = resolve(clientBuildDir, ...normalizedPath.split('/'), 'index.html');
|
|
1110
|
-
await mkdir(dirname(outputPath), {
|
|
1111
|
-
recursive: !0
|
|
1112
|
-
}), await writeFile(outputPath, html), api.logger.info(`Prerender (html): ${prerenderPath} -> ${relative(process.cwd(), outputPath)}`);
|
|
1113
|
-
}, prerenderResourceRoute = async (handler, prerenderPath, clientBuildDir, requestInit)=>{
|
|
1114
|
-
let normalizedPath = `${basename}${prerenderPath}/`.replace(/\/\/+/g, '/').replace(/\/$/g, ''), request = new Request(`http://localhost${normalizedPath}`, requestInit), response = await handler(request), content = Buffer.from(await response.arrayBuffer());
|
|
1115
|
-
if (200 !== response.status) throw Error(`Prerender (resource): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${normalizedPath}\` path.\n` + content.toString('utf8'));
|
|
1116
|
-
let outputPath = resolve(clientBuildDir, ...normalizedPath.split('/'));
|
|
1117
|
-
await mkdir(dirname(outputPath), {
|
|
1118
|
-
recursive: !0
|
|
1119
|
-
}), await writeFile(outputPath, content), api.logger.info(`Prerender (resource): ${prerenderPath} -> ${relative(process.cwd(), outputPath)}`);
|
|
1120
|
-
}, handleSpaMode = async (handler, build, clientBuildDir)=>{
|
|
1121
|
-
let request = new Request(`http://localhost${basename}`, {
|
|
1122
|
-
headers: {
|
|
1123
|
-
'X-React-Router-SPA-Mode': 'yes'
|
|
1124
|
-
}
|
|
1125
|
-
}), response = await handler(request), html = await response.text(), isPrerenderSpaFallback = build.prerender?.includes('/'), filename = isPrerenderSpaFallback ? '__spa-fallback.html' : 'index.html';
|
|
1126
|
-
if (200 !== response.status) {
|
|
1127
|
-
if (isPrerenderSpaFallback) throw Error(`Prerender: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering your \`${filename}\` file.\n` + html);
|
|
1128
|
-
throw Error(`SPA Mode: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering your \`${filename}\` file.\n` + html);
|
|
1129
|
-
}
|
|
1130
|
-
if (!html.includes('window.__reactRouterContext =') || !html.includes('window.__reactRouterRouteModules =')) throw Error("SPA Mode: Did you forget to include `<Scripts/>` in your root route? Your pre-rendered HTML cannot hydrate without `<Scripts />`.");
|
|
1131
|
-
let outputPath = resolve(clientBuildDir, filename);
|
|
1132
|
-
await writeFile(outputPath, html);
|
|
1133
|
-
let prettyPath = relative(process.cwd(), outputPath);
|
|
1134
|
-
build.prerender?.length ? api.logger.info(`Prerender (html): SPA Fallback -> ${prettyPath}`) : api.logger.info(`SPA Mode: Generated ${prettyPath}`);
|
|
1135
|
-
}, validateSsrFalsePrerenderExports = async (manifest, prerenderList)=>{
|
|
1136
|
-
if (0 === prerenderList.length) return;
|
|
1137
|
-
let prerenderRoutes = createPrerenderRoutes(routes), prerenderedRoutes = new Set();
|
|
1138
|
-
for (let path of prerenderList){
|
|
1139
|
-
let matches = matchRoutes(prerenderRoutes, normalizePrerenderMatchPath(path));
|
|
1140
|
-
if (!matches) throw Error(`Unable to prerender path because it does not match any routes: ${path}`);
|
|
1141
|
-
matches.forEach((match)=>prerenderedRoutes.add(match.route.id));
|
|
1142
|
-
}
|
|
1143
|
-
let routeExports = {};
|
|
1144
|
-
for (let route of Object.values(routes)){
|
|
1145
|
-
let filePath = resolve(appDirectory, route.file);
|
|
1146
|
-
routeExports[route.id] = await getRouteModuleExports(filePath);
|
|
1147
|
-
}
|
|
1148
|
-
let errors = [];
|
|
1149
|
-
for (let [routeId, route] of Object.entries(manifest.routes)){
|
|
1150
|
-
let exports = routeExports[routeId] ?? [], invalidApis = [];
|
|
1151
|
-
if (exports.includes('headers') && invalidApis.push('headers'), exports.includes('action') && invalidApis.push('action'), invalidApis.length > 0 && errors.push(`Prerender: ${invalidApis.length} invalid route export(s) in \`${routeId}\` when pre-rendering with \`ssr:false\`: ${invalidApis.map((api)=>`\`${api}\``).join(', ')}. See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information.`), !prerenderedRoutes.has(routeId)) {
|
|
1152
|
-
exports.includes('loader') && errors.push(`Prerender: 1 invalid route export in \`${routeId}\` when pre-rendering with \`ssr:false\`: \`loader\`. See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information.`);
|
|
1153
|
-
let parentRoute = route.parentId && manifest.routes[route.parentId] ? manifest.routes[route.parentId] : null;
|
|
1154
|
-
for(; parentRoute && 'root' !== parentRoute.id;)parentRoute.hasLoader && !parentRoute.hasClientLoader && errors.push(`Prerender: 1 invalid route export in \`${parentRoute.id}\` when pre-rendering with \`ssr:false\`: \`loader\`. See https://reactrouter.com/how-to/pre-rendering#invalid-exports for more information.`), parentRoute = parentRoute.parentId && 'root' !== parentRoute.parentId ? manifest.routes[parentRoute.parentId] : null;
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
if (errors.length > 0) throw api.logger.error(errors.join('\n')), Error('Invalid route exports found when prerendering with `ssr:false`');
|
|
1158
|
-
};
|
|
2056
|
+
});
|
|
1159
2057
|
api.onAfterBuild(async ({ environments })=>{
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
return 1;
|
|
1184
|
-
})(prerenderConfig), pending = new Set(), enqueue = async (path)=>{
|
|
1185
|
-
let matches = matchRoutes(buildRoutes, normalizePrerenderMatchPath(path));
|
|
1186
|
-
if (!matches) return;
|
|
1187
|
-
let leafRoute = matches[matches.length - 1]?.route, manifestRoute = leafRoute ? build.routes?.[leafRoute.id]?.module : null;
|
|
1188
|
-
if (!manifestRoute || manifestRoute.default || manifestRoute.ErrorBoundary) {
|
|
1189
|
-
let data;
|
|
1190
|
-
matches.some((match)=>{
|
|
1191
|
-
let routeId = match.route.id;
|
|
1192
|
-
return !!routeId && build.assets?.routes?.[routeId]?.hasLoader;
|
|
1193
|
-
}) && (data = await prerenderData(requestHandler, path, null, clientBuildDir)), await prerenderRoute(requestHandler, path, clientBuildDir, data ? {
|
|
1194
|
-
headers: {
|
|
1195
|
-
'X-React-Router-Prerender-Data': encodeURI(data)
|
|
1196
|
-
}
|
|
1197
|
-
} : void 0);
|
|
1198
|
-
} else manifestRoute.loader ? (await prerenderData(requestHandler, path, [
|
|
1199
|
-
leafRoute.id
|
|
1200
|
-
], clientBuildDir), await prerenderResourceRoute(requestHandler, path, clientBuildDir)) : api.logger.warn(`⚠️ Skipping prerendering for resource route without a loader: ${leafRoute?.id}`);
|
|
1201
|
-
};
|
|
1202
|
-
for (let path of prerenderPaths){
|
|
1203
|
-
let task = enqueue(path);
|
|
1204
|
-
pending.add(task), task.finally(()=>pending.delete(task)), pending.size >= concurrency && await Promise.race(pending);
|
|
1205
|
-
}
|
|
1206
|
-
await Promise.all(pending);
|
|
1207
|
-
}
|
|
1208
|
-
ssr || await handleSpaMode(requestHandler, build, clientBuildDir);
|
|
1209
|
-
}
|
|
1210
|
-
if (ssr || (await fs_extra.remove(serverBuildDir), api.logger.info(`[${PLUGIN_NAME}] Removed server build (static deployment)`)), buildEnd) {
|
|
1211
|
-
let buildManifest = await getBuildManifest({
|
|
1212
|
-
reactRouterConfig: resolvedConfigWithRoutes,
|
|
1213
|
-
routes,
|
|
1214
|
-
rootDirectory: process.cwd()
|
|
1215
|
-
});
|
|
1216
|
-
await buildEnd({
|
|
1217
|
-
buildManifest,
|
|
1218
|
-
reactRouterConfig: resolvedConfigWithRoutes,
|
|
1219
|
-
viteConfig: api.getNormalizedConfig()
|
|
1220
|
-
});
|
|
1221
|
-
}
|
|
2058
|
+
await runReactRouterPrerenderBuild({
|
|
2059
|
+
api,
|
|
2060
|
+
hasWebEnvironment: !!environments.web,
|
|
2061
|
+
buildDirectory,
|
|
2062
|
+
serverBuildFile,
|
|
2063
|
+
ssr,
|
|
2064
|
+
isPrerenderEnabled,
|
|
2065
|
+
prerenderConfig,
|
|
2066
|
+
prerenderPaths,
|
|
2067
|
+
basename,
|
|
2068
|
+
future,
|
|
2069
|
+
routes,
|
|
2070
|
+
latestBrowserManifest,
|
|
2071
|
+
latestBrowserManifestModuleExports,
|
|
2072
|
+
clientStats,
|
|
2073
|
+
pluginOptions,
|
|
2074
|
+
appDirectory,
|
|
2075
|
+
assetPrefix,
|
|
2076
|
+
routeChunkOptions,
|
|
2077
|
+
buildManifest,
|
|
2078
|
+
resolvedConfigWithRoutes,
|
|
2079
|
+
buildEnd
|
|
2080
|
+
});
|
|
1222
2081
|
});
|
|
1223
|
-
let allowedActionOriginsForBuild = !1 === allowedActionOrigins ? void 0 : allowedActionOrigins
|
|
1224
|
-
|
|
1225
|
-
|
|
2082
|
+
let allowedActionOriginsForBuild = !1 === allowedActionOrigins ? void 0 : allowedActionOrigins;
|
|
2083
|
+
api.modifyRsbuildConfig(async (config, { mergeRsbuildConfig })=>{
|
|
2084
|
+
var existing, publicPath;
|
|
2085
|
+
let bundleVirtualModules, bundleManifestModules, vmodPlugin = (publicPath = assetPrefix = normalizeAssetPrefix(config.output?.assetPrefix), bundleVirtualModules = Object.fromEntries(Object.entries(routesByServerBundleId).map(([bundleId, bundleRoutes])=>[
|
|
2086
|
+
`virtual/react-router/server-build-${bundleId}`,
|
|
2087
|
+
generateServerBuild(bundleRoutes, {
|
|
2088
|
+
entryServerPath: finalEntryServerPath,
|
|
2089
|
+
assetsBuildDirectory,
|
|
2090
|
+
basename,
|
|
2091
|
+
appDirectory,
|
|
2092
|
+
ssr,
|
|
2093
|
+
federation: options.federation,
|
|
2094
|
+
future,
|
|
2095
|
+
allowedActionOrigins: allowedActionOriginsForBuild,
|
|
2096
|
+
prerender: prerenderPaths,
|
|
2097
|
+
routeDiscovery,
|
|
2098
|
+
publicPath,
|
|
2099
|
+
serverManifestId: `virtual/react-router/server-manifest-${bundleId}`
|
|
2100
|
+
})
|
|
2101
|
+
])), bundleManifestModules = Object.fromEntries(Object.entries(routesByServerBundleId).filter(([, bundleRoutes])=>bundleRoutes && Object.keys(bundleRoutes).length > 0).map(([bundleId])=>[
|
|
2102
|
+
`virtual/react-router/server-manifest-${bundleId}`,
|
|
2103
|
+
'export default {};'
|
|
2104
|
+
])), new rspack.experiments.VirtualModulesPlugin(Object.fromEntries(Object.entries({
|
|
2105
|
+
'virtual/react-router/browser-manifest': 'export default {};',
|
|
2106
|
+
'virtual/react-router/server-manifest': 'export default {};',
|
|
2107
|
+
'virtual/react-router/server-build': generateServerBuild(routes, {
|
|
1226
2108
|
entryServerPath: finalEntryServerPath,
|
|
1227
2109
|
assetsBuildDirectory,
|
|
1228
2110
|
basename,
|
|
@@ -1233,107 +2115,112 @@ let redirectStatusCodes = new Set([
|
|
|
1233
2115
|
allowedActionOrigins: allowedActionOriginsForBuild,
|
|
1234
2116
|
prerender: prerenderPaths,
|
|
1235
2117
|
routeDiscovery,
|
|
1236
|
-
publicPath
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
2118
|
+
publicPath
|
|
2119
|
+
}),
|
|
2120
|
+
...bundleVirtualModules,
|
|
2121
|
+
...bundleManifestModules,
|
|
2122
|
+
'virtual/react-router/with-props': generateWithProps()
|
|
2123
|
+
}).map(([moduleId, contents])=>[
|
|
2124
|
+
((moduleId)=>{
|
|
2125
|
+
if (!moduleId.startsWith(VIRTUAL_MODULE_PREFIX)) throw Error(`Virtual module id must start with ${JSON.stringify(VIRTUAL_MODULE_PREFIX)}: ${moduleId}`);
|
|
2126
|
+
let relativeId = moduleId.slice(VIRTUAL_MODULE_PREFIX.length), segments = relativeId.split('/');
|
|
2127
|
+
if (!relativeId || segments.some((segment)=>!segment || '.' === segment || '..' === segment)) throw Error(`Invalid virtual module id: ${moduleId}`);
|
|
2128
|
+
return `node_modules/${moduleId}.js`;
|
|
2129
|
+
})(moduleId),
|
|
2130
|
+
contents
|
|
2131
|
+
])))), useAsyncNodeChunkLoading = options.federation && 'commonjs' === resolvedServerOutput, nodeChunkLoading = 'require';
|
|
2132
|
+
'module' === resolvedServerOutput ? nodeChunkLoading = 'import' : useAsyncNodeChunkLoading && (nodeChunkLoading = 'async-node');
|
|
2133
|
+
let nodeEntries = (({ hasServerApp, isBuild, serverAppPath, entryServerPath, defaultEntryName, serverBundleEntries })=>{
|
|
2134
|
+
let entries = {
|
|
2135
|
+
'static/js/app': hasServerApp ? serverAppPath : 'virtual/react-router/server-build',
|
|
2136
|
+
'static/js/entry.server': entryServerPath
|
|
2137
|
+
};
|
|
2138
|
+
for (let { bundleId, entryName } of (hasServerApp && !isBuild && (entries[defaultEntryName] = 'virtual/react-router/server-build'), serverBundleEntries))entries[entryName] = `virtual/react-router/server-build-${bundleId}`;
|
|
2139
|
+
return entries;
|
|
2140
|
+
})({
|
|
2141
|
+
hasServerApp,
|
|
2142
|
+
isBuild,
|
|
2143
|
+
serverAppPath,
|
|
1246
2144
|
entryServerPath: finalEntryServerPath,
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
export function withErrorBoundaryProps(ErrorBoundary) {
|
|
1286
|
-
return function Wrapped() {
|
|
1287
|
-
const props = {
|
|
1288
|
-
params: useParams(),
|
|
1289
|
-
loaderData: useLoaderData(),
|
|
1290
|
-
actionData: useActionData(),
|
|
1291
|
-
error: useRouteError(),
|
|
1292
|
-
};
|
|
1293
|
-
return h(ErrorBoundary, props);
|
|
1294
|
-
};
|
|
1295
|
-
}
|
|
1296
|
-
`
|
|
1297
|
-
}, vmodTempDir);
|
|
1298
|
-
api.modifyRsbuildConfig(async (config, { mergeRsbuildConfig })=>{
|
|
1299
|
-
assetPrefix = normalizeAssetPrefix(config.output?.assetPrefix);
|
|
1300
|
-
let useAsyncNodeChunkLoading = options.federation && 'commonjs' === resolvedServerOutput, nodeChunkLoading = 'module' === resolvedServerOutput ? 'import' : useAsyncNodeChunkLoading ? 'async-node' : 'require', serverBuildFileBase = (serverBuildFile || 'index.js').replace(/\.js$/, ''), nodeEntries = {
|
|
1301
|
-
...hasServerApp ? {
|
|
1302
|
-
'static/js/app': serverAppPath
|
|
1303
|
-
} : {
|
|
1304
|
-
'static/js/app': 'virtual/react-router/server-build'
|
|
1305
|
-
},
|
|
1306
|
-
'static/js/entry.server': finalEntryServerPath
|
|
1307
|
-
};
|
|
1308
|
-
for (let [bundleId, bundleRoutes] of Object.entries(routesByServerBundleId))bundleRoutes && 0 !== Object.keys(bundleRoutes).length && (nodeEntries[`${bundleId}/${serverBuildFileBase}`] = `virtual/react-router/server-build-${bundleId}`);
|
|
2145
|
+
defaultEntryName: devServerBuildEntryName,
|
|
2146
|
+
serverBundleEntries
|
|
2147
|
+
}), guardedLazyCompilation = (({ lazyCompilation, entryClientPath })=>{
|
|
2148
|
+
let eagerPatterns;
|
|
2149
|
+
if (void 0 === lazyCompilation || !1 === lazyCompilation) return lazyCompilation;
|
|
2150
|
+
let options = !0 === lazyCompilation ? {
|
|
2151
|
+
entries: !0,
|
|
2152
|
+
imports: !0
|
|
2153
|
+
} : lazyCompilation, userTest = options.test, isReactRouterHydrationModule = (eagerPatterns = [
|
|
2154
|
+
entryClientPath.replace(/\\/g, '/'),
|
|
2155
|
+
'virtual/react-router/browser-manifest',
|
|
2156
|
+
BUILD_CLIENT_ROUTE_QUERY_STRING,
|
|
2157
|
+
'?react-router-route'
|
|
2158
|
+
], (module)=>[
|
|
2159
|
+
module.request,
|
|
2160
|
+
module.userRequest,
|
|
2161
|
+
module.rawRequest,
|
|
2162
|
+
module.resource,
|
|
2163
|
+
module.identifier?.(),
|
|
2164
|
+
module.nameForCondition?.()
|
|
2165
|
+
].filter((value)=>!!value).some((value)=>{
|
|
2166
|
+
let normalizedValue = value.replace(/\\/g, '/');
|
|
2167
|
+
return eagerPatterns.some((pattern)=>normalizedValue.includes(pattern));
|
|
2168
|
+
}));
|
|
2169
|
+
return {
|
|
2170
|
+
...options,
|
|
2171
|
+
test (module) {
|
|
2172
|
+
if (isReactRouterHydrationModule(module)) return !1;
|
|
2173
|
+
if (!userTest) return !0;
|
|
2174
|
+
if ('function' == typeof userTest) return userTest(module);
|
|
2175
|
+
let conditionName = module.nameForCondition?.();
|
|
2176
|
+
return !!conditionName && (userTest.lastIndex = 0, userTest.test(conditionName));
|
|
2177
|
+
}
|
|
2178
|
+
};
|
|
2179
|
+
})({
|
|
2180
|
+
lazyCompilation: void 0 === pluginOptions.lazyCompilation ? config.dev?.lazyCompilation : pluginOptions.lazyCompilation,
|
|
2181
|
+
entryClientPath: finalEntryClientPath
|
|
2182
|
+
}), shouldCompactFileSizeReport = isBuild && routeCount >= 256 && (config.performance?.printFileSize === void 0 || !0 === config.performance.printFileSize);
|
|
1309
2183
|
return mergeRsbuildConfig(config, {
|
|
2184
|
+
...shouldCompactFileSizeReport ? {
|
|
2185
|
+
performance: {
|
|
2186
|
+
printFileSize: {
|
|
2187
|
+
total: !0,
|
|
2188
|
+
detail: !1,
|
|
2189
|
+
compressed: !1
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
} : {},
|
|
1310
2193
|
output: {
|
|
1311
2194
|
assetPrefix: config.output?.assetPrefix || '/'
|
|
1312
2195
|
},
|
|
1313
2196
|
dev: {
|
|
1314
2197
|
writeToDisk: !0,
|
|
2198
|
+
...void 0 === guardedLazyCompilation ? {} : {
|
|
2199
|
+
lazyCompilation: guardedLazyCompilation
|
|
2200
|
+
},
|
|
2201
|
+
watchFiles: (existing = config.dev?.watchFiles, existing ? [
|
|
2202
|
+
...Array.isArray(existing) ? existing : [
|
|
2203
|
+
existing
|
|
2204
|
+
],
|
|
2205
|
+
...routeWatchFiles
|
|
2206
|
+
] : routeWatchFiles),
|
|
1315
2207
|
setupMiddlewares: pluginOptions.customServer || !ssr ? [] : [
|
|
1316
|
-
(middlewares
|
|
1317
|
-
|
|
2208
|
+
(middlewares)=>{
|
|
2209
|
+
var dependencies;
|
|
2210
|
+
let listenerPromise;
|
|
2211
|
+
middlewares.push((dependencies = {
|
|
2212
|
+
loadBuild: devRuntime.createBuildLoader()
|
|
2213
|
+
}, async (req, res, next)=>{
|
|
1318
2214
|
try {
|
|
1319
|
-
let
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
if (error instanceof Error && error.message.includes("Can't find entry")) return null;
|
|
1324
|
-
throw error;
|
|
1325
|
-
}
|
|
1326
|
-
}, bundle = await tryLoadBundle('static/js/app') ?? await tryLoadBundle('app');
|
|
1327
|
-
if (!bundle || !bundle.routes) throw Error('Server bundle not found or invalid');
|
|
1328
|
-
let rr = await import("react-router"), nfs = await import("@remix-run/node-fetch-server");
|
|
1329
|
-
if ('function' != typeof rr.createRequestHandler) throw Error('[rsbuild-plugin-react-router] Missing `createRequestHandler` export from `react-router`');
|
|
1330
|
-
if ('function' != typeof nfs.createRequestListener) throw Error('[rsbuild-plugin-react-router] Missing `createRequestListener` export from `@remix-run/node-fetch-server`');
|
|
1331
|
-
let normalizedBuild = normalizeBuildModule(bundle), build = await resolveBuildExports(normalizedBuild), requestHandler = rr.createRequestHandler(build, 'development'), listener = nfs.createRequestListener((request)=>requestHandler(request));
|
|
2215
|
+
let listener = await (listenerPromise ??= (async ()=>{
|
|
2216
|
+
let createRequestHandler = dependencies.createRequestHandler ?? (await import("react-router")).createRequestHandler;
|
|
2217
|
+
return (dependencies.createRequestListener ?? (await import("@remix-run/node-fetch-server")).createRequestListener)(createRequestHandler(dependencies.loadBuild, 'development'));
|
|
2218
|
+
})());
|
|
1332
2219
|
await listener(req, res);
|
|
1333
2220
|
} catch (error) {
|
|
1334
|
-
|
|
2221
|
+
next(error);
|
|
1335
2222
|
}
|
|
1336
|
-
});
|
|
2223
|
+
}));
|
|
1337
2224
|
}
|
|
1338
2225
|
]
|
|
1339
2226
|
},
|
|
@@ -1346,10 +2233,20 @@ let redirectStatusCodes = new Set([
|
|
|
1346
2233
|
},
|
|
1347
2234
|
environments: {
|
|
1348
2235
|
web: {
|
|
2236
|
+
...resolvedConfigWithRoutes.subResourceIntegrity ? {
|
|
2237
|
+
security: {
|
|
2238
|
+
sri: {
|
|
2239
|
+
enable: !0
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
} : {},
|
|
1349
2243
|
source: {
|
|
1350
2244
|
entry: {
|
|
1351
2245
|
'entry.client': finalEntryClientPath,
|
|
1352
|
-
'virtual/react-router/browser-manifest':
|
|
2246
|
+
'virtual/react-router/browser-manifest': {
|
|
2247
|
+
import: 'virtual/react-router/browser-manifest',
|
|
2248
|
+
html: !1
|
|
2249
|
+
},
|
|
1353
2250
|
...webRouteEntries
|
|
1354
2251
|
}
|
|
1355
2252
|
},
|
|
@@ -1364,9 +2261,14 @@ let redirectStatusCodes = new Set([
|
|
|
1364
2261
|
tools: {
|
|
1365
2262
|
rspack: {
|
|
1366
2263
|
name: 'web',
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
2264
|
+
module: {
|
|
2265
|
+
rules: [
|
|
2266
|
+
{
|
|
2267
|
+
resourceQuery: urlAssetResourceQuery,
|
|
2268
|
+
exclude: cssUrlAssetExtensions,
|
|
2269
|
+
type: 'asset/resource'
|
|
2270
|
+
}
|
|
2271
|
+
]
|
|
1370
2272
|
},
|
|
1371
2273
|
...options.federation ? {
|
|
1372
2274
|
output: {
|
|
@@ -1385,46 +2287,48 @@ let redirectStatusCodes = new Set([
|
|
|
1385
2287
|
module: !0
|
|
1386
2288
|
},
|
|
1387
2289
|
optimization: {
|
|
2290
|
+
avoidEntryIife: !0,
|
|
1388
2291
|
runtimeChunk: 'single'
|
|
1389
2292
|
}
|
|
1390
2293
|
}
|
|
1391
2294
|
}
|
|
1392
2295
|
},
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
2296
|
+
node: {
|
|
2297
|
+
source: {
|
|
2298
|
+
entry: nodeEntries
|
|
2299
|
+
},
|
|
2300
|
+
output: {
|
|
2301
|
+
distPath: {
|
|
2302
|
+
root: external_pathe_resolve(buildDirectory, 'server')
|
|
1397
2303
|
},
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
2304
|
+
target: config.environments?.node?.output?.target || 'node',
|
|
2305
|
+
filename: {
|
|
2306
|
+
js: '[name].js'
|
|
2307
|
+
}
|
|
2308
|
+
},
|
|
2309
|
+
tools: {
|
|
2310
|
+
rspack: {
|
|
2311
|
+
target: options.federation ? 'async-node' : 'node',
|
|
2312
|
+
module: {
|
|
2313
|
+
rules: [
|
|
2314
|
+
{
|
|
2315
|
+
resourceQuery: urlAssetResourceQuery,
|
|
2316
|
+
exclude: cssUrlAssetExtensions,
|
|
2317
|
+
type: 'asset/resource'
|
|
2318
|
+
}
|
|
2319
|
+
]
|
|
1401
2320
|
},
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
],
|
|
1414
|
-
experiments: {
|
|
1415
|
-
outputModule: 'module' === resolvedServerOutput,
|
|
1416
|
-
...options.federation ? {
|
|
1417
|
-
asyncStartup: !0
|
|
1418
|
-
} : {}
|
|
1419
|
-
},
|
|
1420
|
-
externalsType: resolvedServerOutput,
|
|
1421
|
-
output: {
|
|
1422
|
-
chunkFormat: resolvedServerOutput,
|
|
1423
|
-
chunkLoading: nodeChunkLoading,
|
|
1424
|
-
workerChunkLoading: nodeChunkLoading,
|
|
1425
|
-
wasmLoading: 'fetch',
|
|
1426
|
-
module: 'module' === resolvedServerOutput
|
|
1427
|
-
}
|
|
2321
|
+
externals: nodeExternals,
|
|
2322
|
+
dependencies: [
|
|
2323
|
+
'web'
|
|
2324
|
+
],
|
|
2325
|
+
externalsType: resolvedServerOutput,
|
|
2326
|
+
output: {
|
|
2327
|
+
chunkFormat: resolvedServerOutput,
|
|
2328
|
+
chunkLoading: nodeChunkLoading,
|
|
2329
|
+
workerChunkLoading: nodeChunkLoading,
|
|
2330
|
+
wasmLoading: 'fetch',
|
|
2331
|
+
module: 'module' === resolvedServerOutput
|
|
1428
2332
|
}
|
|
1429
2333
|
}
|
|
1430
2334
|
}
|
|
@@ -1443,400 +2347,236 @@ let redirectStatusCodes = new Set([
|
|
|
1443
2347
|
asyncStartup: !0
|
|
1444
2348
|
});
|
|
1445
2349
|
}
|
|
1446
|
-
})(rspackConfig), 'node' === name
|
|
1447
|
-
let output = rspackConfig.output
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
return {
|
|
1457
|
-
apply (compiler) {
|
|
1458
|
-
compiler.hooks.emit.tapAsync('ModifyBrowserManifest', async (compilation, callback)=>{
|
|
1459
|
-
let sri, stats = compilation.getStats().toJson(), manifest = await getReactRouterManifestForDev(routes, pluginOptions, stats, appDirectory, assetPrefix, routeChunkOptions), virtualManifestPath = 'static/js/virtual/react-router/browser-manifest.js';
|
|
1460
|
-
if (compilation.assets[virtualManifestPath]) {
|
|
1461
|
-
let newSource = compilation.assets[virtualManifestPath].source().toString().replace(/["'`]PLACEHOLDER["'`]/, jsesc(manifest, {
|
|
1462
|
-
es6: !0
|
|
1463
|
-
}));
|
|
1464
|
-
compilation.assets[virtualManifestPath] = {
|
|
1465
|
-
source: ()=>newSource,
|
|
1466
|
-
size: ()=>newSource.length,
|
|
1467
|
-
map: ()=>({
|
|
1468
|
-
version: 3,
|
|
1469
|
-
sources: [
|
|
1470
|
-
virtualManifestPath
|
|
1471
|
-
],
|
|
1472
|
-
names: [],
|
|
1473
|
-
mappings: '',
|
|
1474
|
-
file: virtualManifestPath,
|
|
1475
|
-
sourcesContent: [
|
|
1476
|
-
newSource
|
|
1477
|
-
]
|
|
1478
|
-
}),
|
|
1479
|
-
sourceAndMap: ()=>({
|
|
1480
|
-
source: newSource,
|
|
1481
|
-
map: {
|
|
1482
|
-
version: 3,
|
|
1483
|
-
sources: [
|
|
1484
|
-
virtualManifestPath
|
|
1485
|
-
],
|
|
1486
|
-
names: [],
|
|
1487
|
-
mappings: '',
|
|
1488
|
-
file: virtualManifestPath,
|
|
1489
|
-
sourcesContent: [
|
|
1490
|
-
newSource
|
|
1491
|
-
]
|
|
1492
|
-
}
|
|
1493
|
-
}),
|
|
1494
|
-
updateHash: (hash)=>hash.update(newSource),
|
|
1495
|
-
buffer: ()=>Buffer.from(newSource)
|
|
1496
|
-
};
|
|
1497
|
-
}
|
|
1498
|
-
if (routeChunkOptions?.isBuild) {
|
|
1499
|
-
let entryAssets = stats?.assetsByChunkName?.['entry.client'], entryJsAssets = entryAssets?.filter((asset)=>asset.endsWith('.js')) || [], manifestPath = getReactRouterManifestPath({
|
|
1500
|
-
version: manifest.version,
|
|
1501
|
-
isBuild: !0,
|
|
1502
|
-
entryModulePath: entryJsAssets[0]
|
|
1503
|
-
}), manifestSource = `window.__reactRouterManifest=${jsesc(manifest, {
|
|
1504
|
-
es6: !0
|
|
1505
|
-
})};`;
|
|
1506
|
-
compilation.assets[manifestPath] = new rspack.sources.RawSource(manifestSource);
|
|
1507
|
-
}
|
|
1508
|
-
if (routeChunkOptions?.isBuild && options?.future?.unstable_subResourceIntegrity) for (let asset of (sri = {}, 'function' == typeof compilation.getAssets ? compilation.getAssets() : Object.entries(compilation.assets).map(([name, asset])=>({
|
|
1509
|
-
name,
|
|
1510
|
-
source: asset
|
|
1511
|
-
})))){
|
|
1512
|
-
if (!asset.name.endsWith('.js')) continue;
|
|
1513
|
-
let source = asset.source.source().toString(), hash = createHash('sha384').update(source).digest('base64');
|
|
1514
|
-
sri[combineURLs(assetPrefix, asset.name)] = `sha384-${hash}`;
|
|
1515
|
-
}
|
|
1516
|
-
options?.onManifest?.(manifest, sri), callback();
|
|
1517
|
-
});
|
|
1518
|
-
}
|
|
1519
|
-
};
|
|
1520
|
-
}(routes, pluginOptions, appDirectory, assetPrefix, routeChunkOptions, {
|
|
1521
|
-
future,
|
|
1522
|
-
onManifest: (manifest, sri)=>{
|
|
1523
|
-
let baseServerManifest = {
|
|
1524
|
-
...manifest,
|
|
1525
|
-
sri
|
|
2350
|
+
})(rspackConfig), 'node' === name) {
|
|
2351
|
+
let output = rspackConfig.output;
|
|
2352
|
+
if (output) {
|
|
2353
|
+
let library = output.library, libraryOptions = library && 'object' == typeof library && !Array.isArray(library) ? library : {};
|
|
2354
|
+
rspackConfig.output = {
|
|
2355
|
+
...output,
|
|
2356
|
+
library: {
|
|
2357
|
+
...libraryOptions,
|
|
2358
|
+
type: 'module' === resolvedServerOutput ? 'module' : 'commonjs2'
|
|
2359
|
+
}
|
|
1526
2360
|
};
|
|
1527
|
-
for (let [bundleId, bundleRoutes] of (latestServerManifest = baseServerManifest, Object.entries(routesByServerBundleId))){
|
|
1528
|
-
if (!bundleRoutes) continue;
|
|
1529
|
-
let routeIds = new Set(Object.keys(bundleRoutes)), filteredRoutes = Object.fromEntries(Object.entries(manifest.routes).filter(([routeId])=>routeIds.has(routeId)));
|
|
1530
|
-
latestServerManifestsByBundleId[bundleId] = {
|
|
1531
|
-
...baseServerManifest,
|
|
1532
|
-
routes: filteredRoutes
|
|
1533
|
-
};
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
})), rspackConfig;
|
|
1537
|
-
}
|
|
1538
|
-
}
|
|
1539
|
-
})), api.processAssets({
|
|
1540
|
-
stage: 'additional',
|
|
1541
|
-
targets: [
|
|
1542
|
-
'node'
|
|
1543
|
-
]
|
|
1544
|
-
}, ({ sources, compilation })=>{
|
|
1545
|
-
let packageJsonPath = 'package.json', source = new sources.RawSource(`{"type": "${resolvedServerOutput}"}`);
|
|
1546
|
-
compilation.getAsset(packageJsonPath) ? compilation.updateAsset(packageJsonPath, source) : compilation.emitAsset(packageJsonPath, source);
|
|
1547
|
-
}), api.transform({
|
|
1548
|
-
test: /virtual\/react-router\/(browser|server)-manifest/
|
|
1549
|
-
}, async (args)=>{
|
|
1550
|
-
if ('web' === args.environment.name) return {
|
|
1551
|
-
code: 'window.__reactRouterManifest = "PLACEHOLDER";'
|
|
1552
|
-
};
|
|
1553
|
-
let bundleMatch = args.resource.match(/virtual\/react-router\/server-manifest(?:-([^?]+))?/), bundleId = bundleMatch?.[1]?.replace(/\\.js$/, ''), manifest = (isBuild && latestServerManifest ? bundleId && latestServerManifestsByBundleId[bundleId] ? latestServerManifestsByBundleId[bundleId] : latestServerManifest : null) ?? await getReactRouterManifestForDev(routes, pluginOptions, clientStats, appDirectory, assetPrefix, routeChunkOptions);
|
|
1554
|
-
return {
|
|
1555
|
-
code: `export default ${jsesc(manifest, {
|
|
1556
|
-
es6: !0
|
|
1557
|
-
})};`
|
|
1558
|
-
};
|
|
1559
|
-
}), api.transform({
|
|
1560
|
-
resourceQuery: /__react-router-build-client-route/
|
|
1561
|
-
}, async (args)=>{
|
|
1562
|
-
let code = await transformToEsm(args.code, args.resourcePath), exportNames = await getExportNames(code), isServer = args.environment?.name === 'node', chunkedExportSet = new Set(!isServer && isBuild && splitRouteModules ? (await detectRouteChunksIfEnabled(routeChunkCache, routeChunkConfig, args.resourcePath, code)).chunkedExports : []), reexports = exportNames.filter((exp)=>!chunkedExportSet.has(exp) && (CLIENT_ROUTE_EXPORTS.includes(exp) || isServer && SERVER_ONLY_ROUTE_EXPORTS.includes(exp))), target = `${args.resourcePath}?react-router-route`;
|
|
1563
|
-
return {
|
|
1564
|
-
code: `export { ${reexports.join(', ')} } from ${JSON.stringify(target)};`
|
|
1565
|
-
};
|
|
1566
|
-
}), api.transform({
|
|
1567
|
-
resourceQuery: /route-chunk=/
|
|
1568
|
-
}, async (args)=>{
|
|
1569
|
-
if (args.environment?.name !== 'web') return {
|
|
1570
|
-
code: args.code,
|
|
1571
|
-
map: null
|
|
1572
|
-
};
|
|
1573
|
-
let preventEmptyChunkSnippet = (reason)=>`Math.random()<0&&console.log(${JSON.stringify(reason)});`;
|
|
1574
|
-
if (!isBuild || !splitRouteModules) return {
|
|
1575
|
-
code: preventEmptyChunkSnippet('Split route modules disabled'),
|
|
1576
|
-
map: null
|
|
1577
|
-
};
|
|
1578
|
-
let chunkName = ((id)=>{
|
|
1579
|
-
if (!id.includes(routeChunkQueryStringPrefix)) return null;
|
|
1580
|
-
let chunkName = id.split(routeChunkQueryStringPrefix)[1].split('&')[0];
|
|
1581
|
-
return 'main' === chunkName || routeChunkExportNames.includes(chunkName) ? chunkName : null;
|
|
1582
|
-
})(args.resource);
|
|
1583
|
-
if (!chunkName) throw Error(`Invalid route chunk name in "${args.resource}"`);
|
|
1584
|
-
let transformed = await transformToEsm(args.code, args.resourcePath), chunk = await getRouteChunkIfEnabled(routeChunkCache, routeChunkConfig, args.resourcePath, chunkName, transformed);
|
|
1585
|
-
if (enforceSplitRouteModules && 'main' === chunkName && chunk) {
|
|
1586
|
-
let exportNames = await getExportNames(chunk);
|
|
1587
|
-
validateRouteChunks({
|
|
1588
|
-
config: routeChunkConfig,
|
|
1589
|
-
id: args.resourcePath,
|
|
1590
|
-
valid: {
|
|
1591
|
-
clientAction: !exportNames.includes('clientAction'),
|
|
1592
|
-
clientLoader: !exportNames.includes('clientLoader'),
|
|
1593
|
-
clientMiddleware: !exportNames.includes('clientMiddleware'),
|
|
1594
|
-
HydrateFallback: !exportNames.includes('HydrateFallback')
|
|
1595
|
-
}
|
|
1596
|
-
});
|
|
1597
|
-
}
|
|
1598
|
-
return {
|
|
1599
|
-
code: chunk ?? preventEmptyChunkSnippet(`No ${chunkName} chunk`),
|
|
1600
|
-
map: null
|
|
1601
|
-
};
|
|
1602
|
-
}), api.transform({
|
|
1603
|
-
test: /\.[cm]?[jt]sx?$/
|
|
1604
|
-
}, async (args)=>{
|
|
1605
|
-
if (args.environment?.name !== 'web' || !isBuild || !splitRouteModules || args.resource.includes(BUILD_CLIENT_ROUTE_QUERY_STRING) || args.resource.includes('?react-router-route') || args.resource.includes('route-chunk=') || !routeByFilePath.get(args.resourcePath)) return {
|
|
1606
|
-
code: args.code,
|
|
1607
|
-
map: null
|
|
1608
|
-
};
|
|
1609
|
-
let transformed = await transformToEsm(args.code, args.resourcePath), { hasRouteChunks, chunkedExports } = await detectRouteChunksIfEnabled(routeChunkCache, routeChunkConfig, args.resourcePath, transformed);
|
|
1610
|
-
if (!hasRouteChunks) return {
|
|
1611
|
-
code: args.code,
|
|
1612
|
-
map: null
|
|
1613
|
-
};
|
|
1614
|
-
let sourceExports = await getCachedRouteExports(args.resourcePath), chunkedExportSet = new Set(chunkedExports), mainChunkReexports = sourceExports.filter((name)=>!chunkedExportSet.has(name)).join(', '), chunkBasePath = `./${external_pathe_basename(args.resourcePath)}`;
|
|
1615
|
-
return {
|
|
1616
|
-
code: [
|
|
1617
|
-
mainChunkReexports ? `export { ${mainChunkReexports} } from "${getRouteChunkModuleId(chunkBasePath, 'main')}";` : null,
|
|
1618
|
-
...chunkedExports.map((exportName)=>`export { ${exportName} } from "${getRouteChunkModuleId(chunkBasePath, exportName)}";`)
|
|
1619
|
-
].filter(Boolean).join('\n'),
|
|
1620
|
-
map: null
|
|
1621
|
-
};
|
|
1622
|
-
}), api.transform({
|
|
1623
|
-
test: /[\\/]\.server[\\/]|\.server(\.[cm]?[jt]sx?)?$/
|
|
1624
|
-
}, async (args)=>{
|
|
1625
|
-
if (args.environment?.name !== 'web') return {
|
|
1626
|
-
code: args.code,
|
|
1627
|
-
map: null
|
|
1628
|
-
};
|
|
1629
|
-
let relativePath = relative(process.cwd(), args.resourcePath);
|
|
1630
|
-
throw Error(`[${PLUGIN_NAME}] Server-only module referenced by client: ${relativePath}`);
|
|
1631
|
-
}), api.transform({
|
|
1632
|
-
test: /[\\/]\.client[\\/]|\.client(\.[cm]?[jt]sx?)?$/
|
|
1633
|
-
}, async (args)=>{
|
|
1634
|
-
if (args.environment?.name !== 'node') return {
|
|
1635
|
-
code: args.code,
|
|
1636
|
-
map: null
|
|
1637
|
-
};
|
|
1638
|
-
let code = await transformToEsm(args.code, args.resourcePath), { exportNames: directExportNames, exportAllModules } = await getExportNamesAndExportAll(code), exportNames = new Set(directExportNames), unresolvedExportAll = new Set(), visitedModules = new Set(), resolveIndexFile = (dirPath)=>{
|
|
1639
|
-
for (let ext of JS_EXTENSIONS){
|
|
1640
|
-
let candidate = resolve(dirPath, `index${ext}`);
|
|
1641
|
-
if (existsSync(candidate)) try {
|
|
1642
|
-
if (statSync(candidate).isFile()) return candidate;
|
|
1643
|
-
} catch {
|
|
1644
|
-
continue;
|
|
1645
|
-
}
|
|
1646
|
-
}
|
|
1647
|
-
return null;
|
|
1648
|
-
}, resolveExportAllModule = (specifier, importerPath)=>{
|
|
1649
|
-
if (specifier.startsWith('.') || specifier.startsWith('/')) {
|
|
1650
|
-
let resolvedPath = ((basePath)=>{
|
|
1651
|
-
if (existsSync(basePath)) try {
|
|
1652
|
-
let stats = statSync(basePath);
|
|
1653
|
-
if (stats.isFile()) return basePath;
|
|
1654
|
-
if (stats.isDirectory()) return resolveIndexFile(basePath);
|
|
1655
|
-
} catch {}
|
|
1656
|
-
for (let ext of JS_EXTENSIONS){
|
|
1657
|
-
let candidate = `${basePath}${ext}`;
|
|
1658
|
-
if (existsSync(candidate)) try {
|
|
1659
|
-
if (statSync(candidate).isFile()) return candidate;
|
|
1660
|
-
} catch {
|
|
1661
|
-
continue;
|
|
1662
2361
|
}
|
|
1663
2362
|
}
|
|
1664
|
-
return
|
|
1665
|
-
})(specifier.startsWith('/') ? specifier : resolve(dirname(importerPath), specifier));
|
|
1666
|
-
if (resolvedPath) return resolvedPath;
|
|
1667
|
-
}
|
|
1668
|
-
try {
|
|
1669
|
-
return createRequire(pathToFileURL(importerPath).href).resolve(specifier);
|
|
1670
|
-
} catch {
|
|
1671
|
-
return null;
|
|
1672
|
-
}
|
|
1673
|
-
}, collectExportNamesFromModule = async (modulePath)=>{
|
|
1674
|
-
if (visitedModules.has(modulePath)) return;
|
|
1675
|
-
visitedModules.add(modulePath);
|
|
1676
|
-
let source = await readFile(modulePath, 'utf8'), moduleCode = await transformToEsm(source, modulePath), { exportNames: moduleExportNames, exportAllModules: moduleExportAll } = await getExportNamesAndExportAll(moduleCode);
|
|
1677
|
-
for (let name of moduleExportNames)'default' !== name && exportNames.add(name);
|
|
1678
|
-
for (let nestedSpecifier of moduleExportAll){
|
|
1679
|
-
let nestedPath = resolveExportAllModule(nestedSpecifier, modulePath);
|
|
1680
|
-
if (!nestedPath) {
|
|
1681
|
-
unresolvedExportAll.add(nestedSpecifier);
|
|
1682
|
-
continue;
|
|
2363
|
+
return rspackConfig;
|
|
1683
2364
|
}
|
|
1684
|
-
await collectExportNamesFromModule(nestedPath);
|
|
1685
2365
|
}
|
|
1686
|
-
}
|
|
1687
|
-
|
|
1688
|
-
let
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
2366
|
+
})), function(api, routes, pluginOptions, appDirectory, assetPrefix = '/', routeChunkOptions, options) {
|
|
2367
|
+
let getAssetPrefix = 'function' == typeof assetPrefix ? assetPrefix : ()=>assetPrefix, manifestChunkNames = options?.manifestChunkNames ?? ((routes, splitRouteModules = !1)=>{
|
|
2368
|
+
let chunkNames = new Set([
|
|
2369
|
+
'entry.client'
|
|
2370
|
+
]);
|
|
2371
|
+
for (let route of Object.values(routes))if (chunkNames.add(getRouteEntryName(route)), splitRouteModules && 'root' !== route.id) for (let exportName of routeChunkExportNames)chunkNames.add(getRouteChunkEntryName(route.id, exportName));
|
|
2372
|
+
return chunkNames;
|
|
2373
|
+
})(routes, routeChunkOptions?.splitRouteModules), finalizeSri = !!(routeChunkOptions?.isBuild && (options?.subResourceIntegrity ?? options?.future?.unstable_subResourceIntegrity)), generatedManifests = finalizeSri ? new WeakMap() : void 0;
|
|
2374
|
+
api.processAssets({
|
|
2375
|
+
stage: 'additions',
|
|
2376
|
+
environments: [
|
|
2377
|
+
'web'
|
|
2378
|
+
]
|
|
2379
|
+
}, async ({ assets, sources, compilation })=>{
|
|
2380
|
+
let currentAssetPrefix = getAssetPrefix(), stats = createReactRouterManifestStats(compilation, manifestChunkNames), { manifest, moduleExportsByRouteId } = await generateReactRouterManifestForDev(routes, pluginOptions, stats, appDirectory, currentAssetPrefix, routeChunkOptions), manifestForBrowser = finalizeSri ? {
|
|
2381
|
+
...manifest,
|
|
2382
|
+
sri: !0
|
|
2383
|
+
} : manifest, browserManifestAsset = assets[BROWSER_MANIFEST_ASSET];
|
|
2384
|
+
if (browserManifestAsset) {
|
|
2385
|
+
let newSource = browserManifestAsset.source().toString().replace(/["'`]PLACEHOLDER["'`]/, jsesc(manifestForBrowser, {
|
|
2386
|
+
es6: !0
|
|
2387
|
+
}));
|
|
2388
|
+
compilation.updateAsset(BROWSER_MANIFEST_ASSET, new sources.RawSource(newSource));
|
|
1692
2389
|
}
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
}, async (args)=>{
|
|
1703
|
-
let code, scopeCrawled;
|
|
1704
|
-
try {
|
|
1705
|
-
code = await transformToEsm(args.code, args.resourcePath);
|
|
1706
|
-
} catch (error) {
|
|
1707
|
-
throw console.error(args.resourcePath), error;
|
|
1708
|
-
}
|
|
1709
|
-
if ('web' === args.environment.name && !ssr && isSpaMode) {
|
|
1710
|
-
let exportNames = await getExportNames(code), isRootRoute = args.resourcePath === rootRoutePath, invalidServerOnly = exportNames.filter((exp)=>(!isRootRoute || 'loader' !== exp) && SERVER_ONLY_ROUTE_EXPORTS.includes(exp));
|
|
1711
|
-
if (invalidServerOnly.length > 0) {
|
|
1712
|
-
let list = invalidServerOnly.map((e)=>`\`${e}\``).join(', ');
|
|
1713
|
-
throw Error(`SPA Mode: ${invalidServerOnly.length} invalid route export(s) in \`${relative(process.cwd(), args.resourcePath)}\`: ${list}. See https://reactrouter.com/how-to/spa for more information.`);
|
|
2390
|
+
if (routeChunkOptions?.isBuild) {
|
|
2391
|
+
let entryAssets = stats?.assetsByChunkName?.['entry.client'], entryJsAssets = entryAssets?.filter((asset)=>asset.endsWith('.js')) || [], manifestPath = getReactRouterManifestPath({
|
|
2392
|
+
version: manifest.version,
|
|
2393
|
+
isBuild: !0,
|
|
2394
|
+
entryModulePath: entryJsAssets[0]
|
|
2395
|
+
}), manifestSource = `window.__reactRouterManifest=${jsesc(manifestForBrowser, {
|
|
2396
|
+
es6: !0
|
|
2397
|
+
})};`, source = new sources.RawSource(manifestSource);
|
|
2398
|
+
compilation.getAsset(manifestPath) ? compilation.updateAsset(manifestPath, source) : compilation.emitAsset(manifestPath, source);
|
|
1714
2399
|
}
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
2400
|
+
generatedManifests ? generatedManifests.set(compilation, {
|
|
2401
|
+
manifest,
|
|
2402
|
+
moduleExportsByRouteId,
|
|
2403
|
+
manifestStats: stats,
|
|
2404
|
+
assetPrefix: currentAssetPrefix
|
|
2405
|
+
}) : options?.onManifest?.(manifest, void 0, moduleExportsByRouteId, {
|
|
2406
|
+
compilation,
|
|
2407
|
+
manifestStats: stats
|
|
2408
|
+
});
|
|
2409
|
+
}), generatedManifests && api.processAssets({
|
|
2410
|
+
stage: 'report',
|
|
2411
|
+
environments: [
|
|
2412
|
+
'web'
|
|
2413
|
+
]
|
|
2414
|
+
}, ({ compilation })=>{
|
|
2415
|
+
let generatedManifest = generatedManifests.get(compilation);
|
|
2416
|
+
if (!generatedManifest) return;
|
|
2417
|
+
generatedManifests.delete(compilation);
|
|
2418
|
+
let sri = ((stats, compilation, assetPrefix = '/')=>{
|
|
2419
|
+
let sri = {};
|
|
2420
|
+
for (let asset of stats?.assets ?? [])addIntegrity(sri, assetPrefix, asset.name, asset.integrity);
|
|
2421
|
+
if ('function' == typeof compilation?.getAssets) for (let asset of compilation.getAssets())addIntegrity(sri, assetPrefix, asset.name, asset.info?.integrity);
|
|
2422
|
+
return Object.keys(sri).length > 0 ? sri : void 0;
|
|
2423
|
+
})(void 0, compilation, generatedManifest.assetPrefix) ?? !0;
|
|
2424
|
+
options?.onManifest?.({
|
|
2425
|
+
...generatedManifest.manifest,
|
|
2426
|
+
sri
|
|
2427
|
+
}, sri, generatedManifest.moduleExportsByRouteId, {
|
|
2428
|
+
compilation,
|
|
2429
|
+
manifestStats: generatedManifest.manifestStats
|
|
2430
|
+
});
|
|
1721
2431
|
});
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
if ('RestElement' === property.type && 'Identifier' === property.argument.type && exportsToRemove.includes(property.argument.name)) throw invalidDestructureError(property.argument.name);
|
|
1747
|
-
}
|
|
1748
|
-
}
|
|
1749
|
-
}(declaration.id, exportsToRemove), !0)), 0 === declaration.declarations.length && markedForRemoval.add(path);
|
|
1750
|
-
}
|
|
1751
|
-
if (path.node.declaration?.type === 'FunctionDeclaration') {
|
|
1752
|
-
let id = path.node.declaration.id;
|
|
1753
|
-
id && exportsToRemove.includes(id.name) && markedForRemoval.add(path);
|
|
1754
|
-
}
|
|
1755
|
-
if (path.node.declaration?.type === 'ClassDeclaration') {
|
|
1756
|
-
let id = path.node.declaration.id;
|
|
1757
|
-
id && exportsToRemove.includes(id.name) && markedForRemoval.add(path);
|
|
1758
|
-
}
|
|
1759
|
-
}
|
|
1760
|
-
'ExportDefaultDeclaration' === path.node.type && exportsToRemove.includes('default') && (markedForRemoval.add(path), path.node.declaration && ('Identifier' === path.node.declaration.type ? removedExportLocalNames.add(path.node.declaration.name) : ('FunctionDeclaration' === path.node.declaration.type || 'ClassDeclaration' === path.node.declaration.type) && path.node.declaration.id && removedExportLocalNames.add(path.node.declaration.id.name)));
|
|
1761
|
-
}
|
|
1762
|
-
}), traverse(ast, {
|
|
1763
|
-
ExpressionStatement (path) {
|
|
1764
|
-
if (!path.parentPath.isProgram()) return;
|
|
1765
|
-
let expr = path.node.expression;
|
|
1766
|
-
if ('AssignmentExpression' !== expr.type) return;
|
|
1767
|
-
let left = expr.left;
|
|
1768
|
-
'MemberExpression' === left.type && 'Identifier' === left.object.type && (exportsToRemove.includes(left.object.name) || removedExportLocalNames.has(left.object.name)) && markedForRemoval.add(path);
|
|
2432
|
+
}(api, routes, pluginOptions, appDirectory, ()=>assetPrefix, routeChunkOptions, {
|
|
2433
|
+
subResourceIntegrity: resolvedConfigWithRoutes.subResourceIntegrity,
|
|
2434
|
+
future,
|
|
2435
|
+
manifestChunkNames,
|
|
2436
|
+
onManifest: (manifest, sri, moduleExportsByRouteId, context)=>{
|
|
2437
|
+
var compilation;
|
|
2438
|
+
return compilation = context.compilation, void performanceProfiler.recordSync('web', 'manifest:stage', 'virtual/react-router/browser-manifest', ()=>{
|
|
2439
|
+
latestBrowserManifest = manifest, latestBrowserManifestModuleExports = moduleExportsByRouteId;
|
|
2440
|
+
let baseServerManifest = {
|
|
2441
|
+
...manifest,
|
|
2442
|
+
sri: sri
|
|
2443
|
+
};
|
|
2444
|
+
latestServerManifest = baseServerManifest;
|
|
2445
|
+
let manifestsByEntryName = {
|
|
2446
|
+
[devServerBuildEntryName]: baseServerManifest
|
|
2447
|
+
};
|
|
2448
|
+
for (let { bundleId, entryName } of serverBundleEntries){
|
|
2449
|
+
let bundleRoutes = routesByServerBundleId[bundleId];
|
|
2450
|
+
if (!bundleRoutes) continue;
|
|
2451
|
+
let routeIds = new Set(Object.keys(bundleRoutes)), filteredRoutes = Object.fromEntries(Object.entries(manifest.routes).filter(([routeId])=>routeIds.has(routeId))), bundleManifest = {
|
|
2452
|
+
...baseServerManifest,
|
|
2453
|
+
routes: filteredRoutes
|
|
2454
|
+
};
|
|
2455
|
+
latestServerManifestsByBundleId[bundleId] = bundleManifest, manifestsByEntryName[entryName] = bundleManifest;
|
|
1769
2456
|
}
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
deadCodeElimination(ast, previouslyReferencedIdentifiers);
|
|
1773
|
-
}
|
|
1774
|
-
}
|
|
1775
|
-
let hocs = [];
|
|
1776
|
-
function getHocUid(path, hocName) {
|
|
1777
|
-
let uid = path.scope.generateUidIdentifier(hocName);
|
|
1778
|
-
return hocs.push([
|
|
1779
|
-
hocName,
|
|
1780
|
-
uid
|
|
1781
|
-
]), uid;
|
|
2457
|
+
isBuild || devRuntime.captureWeb(compilation, manifestsByEntryName);
|
|
2458
|
+
});
|
|
1782
2459
|
}
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
2460
|
+
}), (({ api, resolvedServerOutput, performanceProfiler, getLatestServerManifest, getLatestServerManifestByBundleId, routes, pluginOptions, getClientStats, appDirectory, getAssetPrefix, routeChunkOptions, routeTransformExecutor, routeByFilePath, routeChunkConfig, isBuild, splitRouteModules, ssr, isSpaMode, rootRoutePath })=>{
|
|
2461
|
+
let transformRouteModule = async (args)=>performanceProfiler.record(args.environment?.name, 'route:module', args.resource, async ()=>routeTransformExecutor.run({
|
|
2462
|
+
kind: 'routeModule',
|
|
2463
|
+
code: args.code,
|
|
2464
|
+
resource: args.resource,
|
|
2465
|
+
resourcePath: args.resourcePath,
|
|
2466
|
+
environmentName: args.environment.name,
|
|
2467
|
+
sourceMaps: isSourceMapEnabled(args.environment.config.output.sourceMap),
|
|
2468
|
+
ssr,
|
|
2469
|
+
isBuild,
|
|
2470
|
+
isSpaMode,
|
|
2471
|
+
rootRoutePath
|
|
2472
|
+
}));
|
|
2473
|
+
api.processAssets({
|
|
2474
|
+
stage: 'additional',
|
|
2475
|
+
targets: [
|
|
2476
|
+
'node'
|
|
2477
|
+
]
|
|
2478
|
+
}, ({ sources, compilation })=>{
|
|
2479
|
+
let packageJsonPath = 'package.json', source = new sources.RawSource(`{"type": "${resolvedServerOutput}"}`);
|
|
2480
|
+
compilation.getAsset(packageJsonPath) ? compilation.updateAsset(packageJsonPath, source) : compilation.emitAsset(packageJsonPath, source);
|
|
2481
|
+
}), api.transform({
|
|
2482
|
+
test: /virtual\/react-router\/(browser|server)-manifest/
|
|
2483
|
+
}, async (args)=>performanceProfiler.record(args.environment?.name, 'manifest:transform', args.resource, async ()=>{
|
|
2484
|
+
if ('web' === args.environment.name) return {
|
|
2485
|
+
code: 'window.__reactRouterManifest = "PLACEHOLDER";'
|
|
2486
|
+
};
|
|
2487
|
+
let bundleMatch = args.resource.match(/virtual\/react-router\/server-manifest(?:-([^?]+))?/), bundleId = bundleMatch?.[1]?.replace(/\.js$/, ''), latestServerManifest = getLatestServerManifest(), manifest = (latestServerManifest ? (bundleId && getLatestServerManifestByBundleId(bundleId)) ?? latestServerManifest : null) ?? await getReactRouterManifestForDev(routes, pluginOptions, getClientStats(), appDirectory, getAssetPrefix(), routeChunkOptions);
|
|
2488
|
+
return {
|
|
2489
|
+
code: `export default ${jsesc(manifest, {
|
|
2490
|
+
es6: !0
|
|
2491
|
+
})};`
|
|
2492
|
+
};
|
|
2493
|
+
})), api.transform({
|
|
2494
|
+
resourceQuery: /__react-router-build-client-route/
|
|
2495
|
+
}, async (args)=>performanceProfiler.record(args.environment?.name, 'route:client-entry', args.resource, async ()=>routeTransformExecutor.run({
|
|
2496
|
+
kind: 'routeClientEntry',
|
|
2497
|
+
code: args.code,
|
|
2498
|
+
resourcePath: args.resourcePath,
|
|
2499
|
+
environmentName: args.environment?.name,
|
|
2500
|
+
isBuild,
|
|
2501
|
+
routeChunkConfig
|
|
2502
|
+
}))), api.transform({
|
|
2503
|
+
resourceQuery: /route-chunk=/,
|
|
2504
|
+
environments: [
|
|
2505
|
+
'web'
|
|
2506
|
+
]
|
|
2507
|
+
}, async (args)=>performanceProfiler.record(args.environment?.name, 'route:chunk', args.resource, async ()=>routeTransformExecutor.run({
|
|
2508
|
+
kind: 'routeChunk',
|
|
2509
|
+
code: args.code,
|
|
2510
|
+
resource: args.resource,
|
|
2511
|
+
resourcePath: args.resourcePath,
|
|
2512
|
+
isBuild,
|
|
2513
|
+
routeChunkConfig
|
|
2514
|
+
}))), isBuild && splitRouteModules && api.transform({
|
|
2515
|
+
test: (path)=>routeByFilePath.has(path),
|
|
2516
|
+
resourceQuery: {
|
|
2517
|
+
not: /__react-router-build-client-route|react-router-route|route-chunk=/
|
|
1824
2518
|
},
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
})
|
|
2519
|
+
environments: [
|
|
2520
|
+
'web'
|
|
2521
|
+
]
|
|
2522
|
+
}, async (args)=>performanceProfiler.record(args.environment?.name, 'route:split-exports', args.resource, async ()=>routeTransformExecutor.run({
|
|
2523
|
+
kind: 'splitRouteExports',
|
|
2524
|
+
code: args.code,
|
|
2525
|
+
resourcePath: args.resourcePath,
|
|
2526
|
+
routeChunkConfig
|
|
2527
|
+
}))), api.transform({
|
|
2528
|
+
test: /[\\/]\.server[\\/]|\.server(\.[cm]?[jt]sx?)?$/,
|
|
2529
|
+
environments: [
|
|
2530
|
+
'web'
|
|
2531
|
+
]
|
|
2532
|
+
}, async (args)=>performanceProfiler.record(args.environment?.name, 'module:server-only-guard', args.resource, async ()=>{
|
|
2533
|
+
let relativePath = relative(process.cwd(), args.resourcePath);
|
|
2534
|
+
throw Error(`[${PLUGIN_NAME}] Server-only module referenced by client: ${relativePath}`);
|
|
2535
|
+
})), api.transform({
|
|
2536
|
+
test: /[\\/]\.client[\\/]|\.client(\.[cm]?[jt]sx?)?$/,
|
|
2537
|
+
environments: [
|
|
2538
|
+
'node'
|
|
2539
|
+
]
|
|
2540
|
+
}, async (args)=>performanceProfiler.record(args.environment?.name, 'module:client-only-stub', args.resource, async ()=>routeTransformExecutor.run({
|
|
2541
|
+
kind: 'clientOnlyStub',
|
|
2542
|
+
code: args.code,
|
|
2543
|
+
resourcePath: args.resourcePath,
|
|
2544
|
+
resolveExportAllModule: 'function' == typeof args.resolve ? createBundlerRouteExportResolver(args.resolve) : void 0
|
|
2545
|
+
}))), api.transform({
|
|
2546
|
+
resourceQuery: /\?react-router-route/,
|
|
2547
|
+
order: 'post'
|
|
2548
|
+
}, transformRouteModule), api.transform({
|
|
2549
|
+
test: (path)=>routeByFilePath.has(path),
|
|
2550
|
+
resourceQuery: {
|
|
2551
|
+
not: /__react-router-build-client-route|react-router-route|route-chunk=/
|
|
2552
|
+
},
|
|
2553
|
+
order: 'post'
|
|
2554
|
+
}, transformRouteModule);
|
|
2555
|
+
})({
|
|
2556
|
+
api,
|
|
2557
|
+
resolvedServerOutput,
|
|
2558
|
+
performanceProfiler,
|
|
2559
|
+
getLatestServerManifest: ()=>latestServerManifest,
|
|
2560
|
+
getLatestServerManifestByBundleId: (bundleId)=>latestServerManifestsByBundleId[bundleId],
|
|
2561
|
+
routes,
|
|
2562
|
+
pluginOptions,
|
|
2563
|
+
getClientStats: ()=>clientStats,
|
|
2564
|
+
appDirectory,
|
|
2565
|
+
getAssetPrefix: ()=>assetPrefix,
|
|
2566
|
+
routeChunkOptions,
|
|
2567
|
+
routeTransformExecutor,
|
|
2568
|
+
routeByFilePath,
|
|
2569
|
+
routeChunkConfig: {
|
|
2570
|
+
splitRouteModules,
|
|
2571
|
+
appDirectory,
|
|
2572
|
+
rootRouteFile
|
|
2573
|
+
},
|
|
2574
|
+
isBuild,
|
|
2575
|
+
splitRouteModules: !!splitRouteModules,
|
|
2576
|
+
ssr,
|
|
2577
|
+
isSpaMode,
|
|
2578
|
+
rootRoutePath
|
|
1839
2579
|
});
|
|
1840
2580
|
}
|
|
1841
2581
|
});
|
|
1842
|
-
export { pluginReactRouter };
|
|
2582
|
+
export { loadReactRouterServerBuild, pluginReactRouter, resolveReactRouterServerBuild };
|