@modern-js/runtime 3.0.4 → 3.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/router/cli/code/index.js +6 -2
- package/dist/cjs/router/cli/code/templates.js +37 -9
- package/dist/cjs/router/runtime/rsc-router.js +119 -55
- package/dist/cjs/router/runtime/utils.js +5 -0
- package/dist/esm/router/cli/code/index.mjs +6 -2
- package/dist/esm/router/cli/code/templates.mjs +38 -10
- package/dist/esm/router/runtime/rsc-router.mjs +119 -55
- package/dist/esm/router/runtime/utils.mjs +5 -0
- package/dist/esm-node/router/cli/code/index.mjs +6 -2
- package/dist/esm-node/router/cli/code/templates.mjs +38 -10
- package/dist/esm-node/router/runtime/rsc-router.mjs +119 -55
- package/dist/esm-node/router/runtime/utils.mjs +5 -0
- package/dist/types/core/context/serverPayload/index.server.d.ts +5 -5
- package/dist/types/router/cli/code/templates.d.ts +4 -2
- package/dist/types/router/runtime/rsc-router.d.ts +8 -2
- package/dist/types/router/runtime/types.d.ts +17 -0
- package/package.json +8 -8
|
@@ -3,8 +3,9 @@ import { ElementsContext, createFromReadableStream } from "@modern-js/render/cli
|
|
|
3
3
|
import { StaticRouterProvider, createBrowserRouter, createStaticRouter, redirect } from "@modern-js/runtime-utils/router";
|
|
4
4
|
import react from "react";
|
|
5
5
|
import { CSSLinks } from "./CSSLinks.mjs";
|
|
6
|
-
const safeUse = (
|
|
7
|
-
|
|
6
|
+
const safeUse = (value)=>{
|
|
7
|
+
const reactUse = react.use;
|
|
8
|
+
if ('function' == typeof reactUse) return reactUse(value);
|
|
8
9
|
return null;
|
|
9
10
|
};
|
|
10
11
|
function collectCssFilesFromRoutes(matches, routes) {
|
|
@@ -22,6 +23,17 @@ function collectCssFilesFromRoutes(matches, routes) {
|
|
|
22
23
|
}
|
|
23
24
|
const createServerPayload = (routerContext, routes)=>{
|
|
24
25
|
const cssFiles = collectCssFilesFromRoutes(routerContext.matches, routes);
|
|
26
|
+
let cssInjectionIndex = -1;
|
|
27
|
+
if (cssFiles.length > 0) {
|
|
28
|
+
for(let i = routerContext.matches.length - 1; i >= 0; i--){
|
|
29
|
+
const matchRoute = findRouteInTree(routes, routerContext.matches[i].route.id);
|
|
30
|
+
if (matchRoute && !matchRoute.isClientComponent) {
|
|
31
|
+
cssInjectionIndex = i;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (-1 === cssInjectionIndex) cssInjectionIndex = routerContext.matches.length - 1;
|
|
36
|
+
}
|
|
25
37
|
return {
|
|
26
38
|
type: 'render',
|
|
27
39
|
actionData: routerContext.actionData,
|
|
@@ -29,45 +41,42 @@ const createServerPayload = (routerContext, routes)=>{
|
|
|
29
41
|
loaderData: routerContext.loaderData,
|
|
30
42
|
location: routerContext.location,
|
|
31
43
|
routes: routerContext.matches.map((match, index, matches)=>{
|
|
32
|
-
const
|
|
44
|
+
const route = match.route;
|
|
45
|
+
const element = route.element;
|
|
33
46
|
const parentMatch = index > 0 ? matches[index - 1] : void 0;
|
|
34
47
|
let processedElement;
|
|
35
48
|
if (element) {
|
|
36
49
|
const ElementComponent = element.type;
|
|
37
50
|
const elementProps = {
|
|
38
|
-
loaderData: routerContext?.loaderData?.[
|
|
39
|
-
actionData: routerContext?.actionData?.[
|
|
51
|
+
loaderData: routerContext?.loaderData?.[route.id],
|
|
52
|
+
actionData: routerContext?.actionData?.[route.id],
|
|
40
53
|
params: match.params,
|
|
41
|
-
matches: routerContext.matches.map((m)=>{
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
handle: route.handle
|
|
49
|
-
};
|
|
50
|
-
})
|
|
54
|
+
matches: routerContext.matches.map((m)=>({
|
|
55
|
+
id: m.route.id,
|
|
56
|
+
pathname: m.pathname,
|
|
57
|
+
params: m.params,
|
|
58
|
+
data: routerContext?.loaderData?.[m.route.id],
|
|
59
|
+
handle: m.route.handle
|
|
60
|
+
}))
|
|
51
61
|
};
|
|
52
62
|
const routeElement = /*#__PURE__*/ react.createElement(ElementComponent, elementProps);
|
|
53
|
-
|
|
54
|
-
processedElement = isLeafRoute && cssFiles.length > 0 ? /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(CSSLinks, {
|
|
63
|
+
processedElement = index === cssInjectionIndex ? /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(CSSLinks, {
|
|
55
64
|
cssFiles
|
|
56
65
|
}), routeElement) : routeElement;
|
|
57
66
|
}
|
|
58
67
|
return {
|
|
59
68
|
element: processedElement,
|
|
60
|
-
errorElement:
|
|
61
|
-
handle:
|
|
62
|
-
hasAction: !!
|
|
63
|
-
hasErrorBoundary: !!
|
|
64
|
-
hasLoader: !!
|
|
65
|
-
hasClientLoader: !!
|
|
66
|
-
id:
|
|
67
|
-
index:
|
|
69
|
+
errorElement: route.errorElement,
|
|
70
|
+
handle: route.handle,
|
|
71
|
+
hasAction: !!route.action,
|
|
72
|
+
hasErrorBoundary: !!route.hasErrorBoundary,
|
|
73
|
+
hasLoader: !!route.loader,
|
|
74
|
+
hasClientLoader: !!route.hasClientLoader,
|
|
75
|
+
id: route.id,
|
|
76
|
+
index: route.index,
|
|
68
77
|
params: match.params,
|
|
69
|
-
parentId: parentMatch?.route.id ||
|
|
70
|
-
path:
|
|
78
|
+
parentId: parentMatch?.route.id || route.parentId,
|
|
79
|
+
path: route.path,
|
|
71
80
|
pathname: match.pathname,
|
|
72
81
|
pathnameBase: match.pathnameBase
|
|
73
82
|
};
|
|
@@ -87,10 +96,11 @@ const handleRSCRedirect = (headers, basename, status)=>{
|
|
|
87
96
|
});
|
|
88
97
|
};
|
|
89
98
|
const prepareRSCRoutes = async (routes)=>{
|
|
90
|
-
const isLazyComponent = (component)=>component && 'object' == typeof component &&
|
|
99
|
+
const isLazyComponent = (component)=>null != component && 'object' == typeof component && '_init' in component && '_payload' in component;
|
|
91
100
|
const processRoutes = async (routesList)=>{
|
|
92
101
|
await Promise.all(routesList.map(async (route)=>{
|
|
93
|
-
|
|
102
|
+
const modernRoute = route;
|
|
103
|
+
if ('lazyImport' in modernRoute && isLazyComponent(modernRoute.component)) modernRoute.component = (await modernRoute.lazyImport()).default;
|
|
94
104
|
if (route.children && Array.isArray(route.children)) await processRoutes(route.children);
|
|
95
105
|
}));
|
|
96
106
|
};
|
|
@@ -107,12 +117,14 @@ const mergeRoutes = (routes, originalRoutes)=>{
|
|
|
107
117
|
};
|
|
108
118
|
buildRoutesMap(routes);
|
|
109
119
|
const mergeRoutesRecursive = (origRoutes)=>origRoutes.map((origRoute)=>{
|
|
110
|
-
|
|
111
|
-
|
|
120
|
+
const modernOrig = origRoute;
|
|
121
|
+
if (modernOrig.id && routesMap.has(modernOrig.id)) {
|
|
122
|
+
const matchedRoute = routesMap.get(modernOrig.id);
|
|
112
123
|
const result = {
|
|
113
|
-
loader:
|
|
124
|
+
loader: modernOrig.hasClientLoader ? modernOrig.loader : void 0,
|
|
114
125
|
...matchedRoute
|
|
115
126
|
};
|
|
127
|
+
if (modernOrig.isClientComponent) result.isClientComponent = true;
|
|
116
128
|
if (origRoute.children && Array.isArray(origRoute.children)) result.children = mergeRoutesRecursive(origRoute.children);
|
|
117
129
|
return result;
|
|
118
130
|
}
|
|
@@ -130,6 +142,68 @@ const findRouteInTree = (routes, routeId)=>{
|
|
|
130
142
|
}
|
|
131
143
|
return null;
|
|
132
144
|
};
|
|
145
|
+
function getChangedMatches(matches, currentMatches) {
|
|
146
|
+
const currentById = new Map();
|
|
147
|
+
for (const m of currentMatches)if (m.route?.id) currentById.set(m.route.id, m);
|
|
148
|
+
return matches.filter((match)=>{
|
|
149
|
+
const current = currentById.get(match.route?.id);
|
|
150
|
+
return !current || JSON.stringify(current.params) !== JSON.stringify(match.params);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
function canSkipRscFetch(matches, routerState) {
|
|
154
|
+
const changedMatches = getChangedMatches(matches, routerState?.matches || []);
|
|
155
|
+
return changedMatches.length > 0 && changedMatches.every((m)=>{
|
|
156
|
+
const route = m.route;
|
|
157
|
+
return route.isClientComponent && !(route.hasLoader && !route.hasClientLoader);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function injectRouteCss(routeId) {
|
|
161
|
+
if ("u" < typeof window) return;
|
|
162
|
+
const cssAssets = window._MODERNJS_ROUTE_MANIFEST?.routeAssets?.[routeId]?.referenceCssAssets;
|
|
163
|
+
if (!cssAssets) return;
|
|
164
|
+
const publicPath = window.__webpack_public_path__ || '/';
|
|
165
|
+
for (const css of cssAssets){
|
|
166
|
+
const href = css.startsWith('http') || css.startsWith('/') ? css : publicPath + css;
|
|
167
|
+
if (!document.querySelector(`link[href="${CSS.escape(href)}"]`)) {
|
|
168
|
+
const link = document.createElement('link');
|
|
169
|
+
link.rel = 'stylesheet';
|
|
170
|
+
link.href = href;
|
|
171
|
+
document.head.appendChild(link);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function ensureClientComponent(route, originalRoutes) {
|
|
176
|
+
if (route.isClientComponent && !route.Component) {
|
|
177
|
+
const origRoute = findRouteInTree(originalRoutes, route.id);
|
|
178
|
+
if (origRoute?.Component) {
|
|
179
|
+
route.Component = origRoute.Component;
|
|
180
|
+
delete route.element;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function resolveClientLoaders(matches, originalRoutes) {
|
|
185
|
+
const clientMatches = matches.filter((m)=>m.route.hasClientLoader);
|
|
186
|
+
if (0 === clientMatches.length) return Promise.resolve([]);
|
|
187
|
+
return Promise.all(clientMatches.map(async (clientMatch)=>{
|
|
188
|
+
const origRoute = findRouteInTree(originalRoutes, clientMatch.route.id);
|
|
189
|
+
clientMatch.route.loader = origRoute?.loader;
|
|
190
|
+
const result = await clientMatch.resolve();
|
|
191
|
+
return {
|
|
192
|
+
routeId: clientMatch.route.id,
|
|
193
|
+
result
|
|
194
|
+
};
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
197
|
+
function applyLoaderResults(results, loaderResults) {
|
|
198
|
+
for (const { routeId, result } of loaderResults)results[routeId] = result;
|
|
199
|
+
}
|
|
200
|
+
async function resolveClientOnlyNavigation(matches, results, originalRoutes, routerState) {
|
|
201
|
+
const changedMatches = getChangedMatches(matches, routerState?.matches || []);
|
|
202
|
+
for (const match of changedMatches)ensureClientComponent(match.route, originalRoutes);
|
|
203
|
+
applyLoaderResults(results, await resolveClientLoaders(changedMatches, originalRoutes));
|
|
204
|
+
for (const match of changedMatches)if (match.route.id) injectRouteCss(match.route.id);
|
|
205
|
+
return results;
|
|
206
|
+
}
|
|
133
207
|
const createClientRouterFromPayload = (payload, originalRoutes, basename = '')=>{
|
|
134
208
|
const processedRoutes = payload.routes.reduceRight((previous, route)=>{
|
|
135
209
|
if (previous.length > 0) return [
|
|
@@ -146,42 +220,28 @@ const createClientRouterFromPayload = (payload, originalRoutes, basename = '')=>
|
|
|
146
220
|
const router = createBrowserRouter(mergedRoutes, {
|
|
147
221
|
hydrationData: payload,
|
|
148
222
|
basename: basename,
|
|
149
|
-
dataStrategy: async (
|
|
150
|
-
const { request, matches } = context;
|
|
223
|
+
dataStrategy: async ({ request, matches })=>{
|
|
151
224
|
const results = {};
|
|
152
|
-
|
|
225
|
+
if (canSkipRscFetch(matches, router.state)) return resolveClientOnlyNavigation(matches, results, originalRoutes, router.state);
|
|
153
226
|
const fetchPromise = fetch(request.url, {
|
|
154
227
|
headers: {
|
|
155
228
|
'x-rsc-tree': 'true'
|
|
156
229
|
}
|
|
157
230
|
});
|
|
158
|
-
const clientLoadersPromise =
|
|
159
|
-
const foundRoute = findRouteInTree(originalRoutes, clientMatch.route.id);
|
|
160
|
-
clientMatch.route.loader = foundRoute?.loader;
|
|
161
|
-
const res = await clientMatch.resolve();
|
|
162
|
-
return {
|
|
163
|
-
routeId: clientMatch.route.id,
|
|
164
|
-
result: res
|
|
165
|
-
};
|
|
166
|
-
})) : Promise.resolve([]);
|
|
231
|
+
const clientLoadersPromise = resolveClientLoaders(matches, originalRoutes);
|
|
167
232
|
const res = await fetchPromise;
|
|
168
233
|
const redirectLocation = res.headers.get('X-Modernjs-Redirect');
|
|
169
234
|
if (redirectLocation) {
|
|
170
235
|
matches.forEach((match)=>{
|
|
171
236
|
const routeId = match.route.id;
|
|
172
237
|
if (routeId) results[routeId] = {
|
|
173
|
-
type: '
|
|
238
|
+
type: 'data',
|
|
174
239
|
result: redirect(redirectLocation)
|
|
175
240
|
};
|
|
176
241
|
});
|
|
177
242
|
return results;
|
|
178
243
|
}
|
|
179
|
-
|
|
180
|
-
clientLoadersPromise
|
|
181
|
-
]);
|
|
182
|
-
clientLoaderResults.forEach(({ routeId, result })=>{
|
|
183
|
-
results[routeId] = result;
|
|
184
|
-
});
|
|
244
|
+
applyLoaderResults(results, await clientLoadersPromise);
|
|
185
245
|
if (!res.body) throw new Error('Response body is null');
|
|
186
246
|
const payload = await createFromReadableStream(res.body);
|
|
187
247
|
if ('object' != typeof payload || null === payload || void 0 === payload.type || 'render' !== payload.type) throw new Error('Unexpected payload type');
|
|
@@ -189,10 +249,14 @@ const createClientRouterFromPayload = (payload, originalRoutes, basename = '')=>
|
|
|
189
249
|
matches.forEach((match)=>{
|
|
190
250
|
const routeId = match.route.id;
|
|
191
251
|
const matchedRoute = serverPayload.routes.find((route)=>route.id === routeId);
|
|
192
|
-
if (matchedRoute)
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
252
|
+
if (matchedRoute) {
|
|
253
|
+
const modernMatch = match.route;
|
|
254
|
+
router.patchRoutes(matchedRoute.parentId ?? null, [
|
|
255
|
+
matchedRoute
|
|
256
|
+
], true);
|
|
257
|
+
if (modernMatch.isClientComponent && modernMatch.Component) delete modernMatch.Component;
|
|
258
|
+
}
|
|
259
|
+
if (serverPayload.loaderData && routeId in serverPayload.loaderData) results[routeId] = {
|
|
196
260
|
type: 'data',
|
|
197
261
|
result: serverPayload.loaderData[routeId]
|
|
198
262
|
};
|
|
@@ -67,7 +67,12 @@ function getRouteObjects(routes, { globalApp, ssrMode, props }) {
|
|
|
67
67
|
...'object' == typeof route.config ? route.config?.handle : {}
|
|
68
68
|
},
|
|
69
69
|
index: route.index,
|
|
70
|
+
hasLoader: !!route.loader,
|
|
70
71
|
hasClientLoader: !!route.clientData,
|
|
72
|
+
hasAction: !!route.action,
|
|
73
|
+
...route.isClientComponent ? {
|
|
74
|
+
isClientComponent: true
|
|
75
|
+
} : {},
|
|
71
76
|
Component: route.component ? route.component : void 0,
|
|
72
77
|
errorElement: route.error ? /*#__PURE__*/ jsx(route.error, {}) : void 0,
|
|
73
78
|
children: route.children ? route.children.map((child)=>getRouteObjects([
|
|
@@ -90,7 +90,9 @@ const generateCode = async (appContext, config, entrypoints, api)=>{
|
|
|
90
90
|
entryName: entrypoint.entryName,
|
|
91
91
|
internalDirectory,
|
|
92
92
|
splitRouteChunks: config?.output?.splitRouteChunks,
|
|
93
|
-
|
|
93
|
+
isRscClientBundle: isUseRsc(config),
|
|
94
|
+
srcDirectory,
|
|
95
|
+
internalSrcAlias: appContext.internalSrcAlias
|
|
94
96
|
})
|
|
95
97
|
});
|
|
96
98
|
if (entrypoint.nestedRoutesEntry && (isUseSSRBundle(config) || isUseRsc(config))) {
|
|
@@ -110,7 +112,9 @@ const generateCode = async (appContext, config, entrypoints, api)=>{
|
|
|
110
112
|
entryName: entrypoint.entryName,
|
|
111
113
|
internalDirectory,
|
|
112
114
|
splitRouteChunks: config?.output?.splitRouteChunks,
|
|
113
|
-
|
|
115
|
+
isRscClientBundle: false,
|
|
116
|
+
srcDirectory,
|
|
117
|
+
internalSrcAlias: appContext.internalSrcAlias
|
|
114
118
|
});
|
|
115
119
|
await fs.outputFile(path.resolve(internalDirectory, `./${entryName}/routes.server.js`), serverRoutesCode, 'utf8');
|
|
116
120
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import __rslib_shim_module__ from "node:module";
|
|
2
2
|
const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)());
|
|
3
|
+
import { open as promises_open } from "node:fs/promises";
|
|
3
4
|
import path from "path";
|
|
4
|
-
import { findExists, formatImportPath, fs, getEntryOptions, isSSGEntry, slash } from "@modern-js/utils";
|
|
5
|
+
import { JS_EXTENSIONS, findExists, formatImportPath, fs, getEntryOptions, isSSGEntry, slash } from "@modern-js/utils";
|
|
5
6
|
import { ROUTE_MODULES } from "@modern-js/utils/universal/constants";
|
|
6
7
|
import { APP_INIT_EXPORTED, TEMP_LOADERS_DIR } from "../constants.mjs";
|
|
7
8
|
import { getPathWithoutExt, getServerLoadersFile, parseModule, replaceWithAlias } from "./utils.mjs";
|
|
@@ -72,7 +73,25 @@ const routesForServer = ({ routesForServerLoaderMatches })=>{
|
|
|
72
73
|
`;
|
|
73
74
|
};
|
|
74
75
|
const createMatchReg = (keyword)=>new RegExp(`("${keyword}":\\s)"([^\n]+)"`, 'g');
|
|
75
|
-
|
|
76
|
+
async function hasUseClientDirective(componentPath, srcDirectory, internalSrcAlias) {
|
|
77
|
+
let realPath = componentPath;
|
|
78
|
+
if (internalSrcAlias && srcDirectory && realPath.startsWith(internalSrcAlias)) realPath = path.join(srcDirectory, realPath.slice(internalSrcAlias.length));
|
|
79
|
+
const filePath = findExists(JS_EXTENSIONS.map((ext)=>`${realPath}${ext}`));
|
|
80
|
+
if (!filePath) return false;
|
|
81
|
+
let fh;
|
|
82
|
+
try {
|
|
83
|
+
fh = await promises_open(filePath, 'r');
|
|
84
|
+
const buf = Buffer.alloc(64);
|
|
85
|
+
const { bytesRead } = await fh.read(buf, 0, 64, 0);
|
|
86
|
+
const content = buf.toString('utf-8', 0, bytesRead).trimStart();
|
|
87
|
+
return content.startsWith("'use client'") || content.startsWith('"use client"');
|
|
88
|
+
} catch {
|
|
89
|
+
return false;
|
|
90
|
+
} finally{
|
|
91
|
+
await fh?.close();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry, entryName, internalDirectory, splitRouteChunks = true, isRscClientBundle = false, srcDirectory, internalSrcAlias })=>{
|
|
76
95
|
const components = [];
|
|
77
96
|
const loadings = [];
|
|
78
97
|
const errors = [];
|
|
@@ -97,9 +116,9 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
97
116
|
const importOptions = webpackChunkName ? `/* webpackChunkName: "${routeId}" */ ` : eager ? '/* webpackMode: "eager" */ ' : '';
|
|
98
117
|
return `() => import(${importOptions}'${componentPath}').then(routeModule => handleRouteModule(routeModule, "${routeId}")).catch(handleRouteModuleError)`;
|
|
99
118
|
};
|
|
100
|
-
const traverseRouteTree = (route,
|
|
119
|
+
const traverseRouteTree = async (route, isRscClientBundle)=>{
|
|
101
120
|
let children;
|
|
102
|
-
if ('children' in route && route.children) children = route
|
|
121
|
+
if ('children' in route && route.children) children = await Promise.all(route.children.map((child)=>traverseRouteTree(child, isRscClientBundle)));
|
|
103
122
|
let loading;
|
|
104
123
|
let error;
|
|
105
124
|
let loader;
|
|
@@ -171,6 +190,8 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
171
190
|
components.push(route._component);
|
|
172
191
|
component = `component_${components.length - 1}`;
|
|
173
192
|
}
|
|
193
|
+
const isClientComponent = 'nested' === route.type && Boolean(route._component) && Boolean(srcDirectory) && Boolean(internalSrcAlias) && await hasUseClientDirective(route._component, srcDirectory, internalSrcAlias);
|
|
194
|
+
const shouldIncludeClientBundle = !isRscClientBundle || isClientComponent;
|
|
174
195
|
const finalRoute = {
|
|
175
196
|
...route,
|
|
176
197
|
loading,
|
|
@@ -178,10 +199,17 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
178
199
|
action,
|
|
179
200
|
config,
|
|
180
201
|
error,
|
|
181
|
-
children
|
|
202
|
+
children,
|
|
203
|
+
...isClientComponent && {
|
|
204
|
+
isClientComponent: true
|
|
205
|
+
},
|
|
206
|
+
...shouldIncludeClientBundle && {
|
|
207
|
+
lazyImport
|
|
208
|
+
},
|
|
209
|
+
...shouldIncludeClientBundle && route._component && {
|
|
210
|
+
component
|
|
211
|
+
}
|
|
182
212
|
};
|
|
183
|
-
if (!isRscClient) finalRoute.lazyImport = lazyImport;
|
|
184
|
-
if (route._component && !isRscClient) finalRoute.component = component;
|
|
185
213
|
if ('nested' === route.type && route._component && (route.loader || route.data)) finalRoute.shouldRevalidate = `createShouldRevalidate("${route.id}")`;
|
|
186
214
|
return finalRoute;
|
|
187
215
|
};
|
|
@@ -189,7 +217,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
189
217
|
export const routes = [
|
|
190
218
|
`;
|
|
191
219
|
for (const route of routes)if ('type' in route) {
|
|
192
|
-
const newRoute = traverseRouteTree(route,
|
|
220
|
+
const newRoute = await traverseRouteTree(route, isRscClientBundle);
|
|
193
221
|
const routeStr = JSON.stringify(newRoute, null, 2);
|
|
194
222
|
const keywords = [
|
|
195
223
|
'component',
|
|
@@ -264,9 +292,9 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
264
292
|
`;
|
|
265
293
|
return `
|
|
266
294
|
${importLazyCode}
|
|
267
|
-
${!
|
|
295
|
+
${!isRscClientBundle ? importComponentsCode : ''}
|
|
268
296
|
${importRuntimeRouterCode}
|
|
269
|
-
${!
|
|
297
|
+
${!isRscClientBundle ? rootLayoutCode : ''}
|
|
270
298
|
${importLoadingCode}
|
|
271
299
|
${importErrorComponentsCode}
|
|
272
300
|
${importLoadersCode}
|