@modern-js/runtime 2.68.0 → 2.68.2
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/cli/code.js +6 -3
- package/dist/cjs/cli/template.js +72 -21
- package/dist/cjs/cli/template.server.js +62 -13
- package/dist/cjs/core/context/index.js +19 -2
- package/dist/cjs/core/context/serverPayload.server.js +40 -0
- package/dist/cjs/core/server/requestHandler.js +47 -11
- package/dist/cjs/router/cli/code/index.js +13 -6
- package/dist/cjs/router/cli/code/templates.js +44 -20
- package/dist/cjs/router/cli/handler.js +17 -2
- package/dist/cjs/router/cli/index.js +6 -5
- package/dist/cjs/router/index.js +0 -21
- package/dist/cjs/router/internal.js +30 -0
- package/dist/cjs/router/runtime/PrefetchLink.js +3 -4
- package/dist/cjs/router/runtime/constants.js +2 -2
- package/dist/cjs/router/runtime/index.js +1 -12
- package/dist/cjs/router/runtime/internal.js +36 -0
- package/dist/cjs/router/runtime/plugin.js +134 -76
- package/dist/cjs/router/runtime/plugin.node.js +73 -32
- package/dist/cjs/router/runtime/rsc-router.js +322 -0
- package/dist/cjs/router/runtime/utils.js +76 -1
- package/dist/cjs/rsc/client.js +11 -0
- package/dist/cjs/rsc/server.js +40 -0
- package/dist/esm/cli/code.js +6 -3
- package/dist/esm/cli/template.js +25 -6
- package/dist/esm/cli/template.server.js +3 -3
- package/dist/esm/core/context/index.js +14 -1
- package/dist/esm/core/context/serverPayload.server.js +15 -0
- package/dist/esm/core/server/requestHandler.js +102 -9
- package/dist/esm/router/cli/code/index.js +12 -6
- package/dist/esm/router/cli/code/templates.js +29 -13
- package/dist/esm/router/cli/handler.js +33 -6
- package/dist/esm/router/cli/index.js +6 -5
- package/dist/esm/router/index.js +0 -6
- package/dist/esm/router/internal.js +5 -0
- package/dist/esm/router/runtime/PrefetchLink.js +2 -2
- package/dist/esm/router/runtime/constants.js +2 -2
- package/dist/esm/router/runtime/index.js +1 -9
- package/dist/esm/router/runtime/internal.js +10 -0
- package/dist/esm/router/runtime/plugin.js +134 -85
- package/dist/esm/router/runtime/plugin.node.js +110 -40
- package/dist/esm/router/runtime/rsc-router.js +437 -0
- package/dist/esm/router/runtime/utils.js +95 -1
- package/dist/esm/rsc/client.js +6 -0
- package/dist/esm/rsc/server.js +86 -0
- package/dist/esm-node/cli/code.js +6 -3
- package/dist/esm-node/cli/template.js +72 -21
- package/dist/esm-node/cli/template.server.js +62 -13
- package/dist/esm-node/core/context/index.js +14 -1
- package/dist/esm-node/core/context/serverPayload.server.js +15 -0
- package/dist/esm-node/core/server/requestHandler.js +45 -9
- package/dist/esm-node/router/cli/code/index.js +12 -6
- package/dist/esm-node/router/cli/code/templates.js +44 -20
- package/dist/esm-node/router/cli/handler.js +17 -2
- package/dist/esm-node/router/cli/index.js +6 -5
- package/dist/esm-node/router/index.js +0 -6
- package/dist/esm-node/router/internal.js +5 -0
- package/dist/esm-node/router/runtime/PrefetchLink.js +2 -2
- package/dist/esm-node/router/runtime/constants.js +2 -2
- package/dist/esm-node/router/runtime/index.js +1 -9
- package/dist/esm-node/router/runtime/internal.js +10 -0
- package/dist/esm-node/router/runtime/plugin.js +126 -78
- package/dist/esm-node/router/runtime/plugin.node.js +75 -34
- package/dist/esm-node/router/runtime/rsc-router.js +284 -0
- package/dist/esm-node/router/runtime/utils.js +74 -1
- package/dist/esm-node/rsc/client.js +6 -0
- package/dist/esm-node/rsc/server.js +35 -0
- package/dist/types/cli/template.d.ts +4 -2
- package/dist/types/cli/template.server.d.ts +2 -1
- package/dist/types/common.d.ts +1 -1
- package/dist/types/config.d.ts +1 -1
- package/dist/types/core/context/index.d.ts +38 -3
- package/dist/types/core/context/serverPayload.server.d.ts +3 -0
- package/dist/types/core/server/requestHandler.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/router/cli/code/index.d.ts +1 -0
- package/dist/types/router/cli/code/templates.d.ts +4 -2
- package/dist/types/router/index.d.ts +0 -2
- package/dist/types/router/internal.d.ts +2 -0
- package/dist/types/router/runtime/PrefetchLink.d.ts +0 -1
- package/dist/types/router/runtime/constants.d.ts +3 -3
- package/dist/types/router/runtime/index.d.ts +1 -9
- package/dist/types/router/runtime/internal.d.ts +8 -0
- package/dist/types/router/runtime/rsc-router.d.ts +14 -0
- package/dist/types/router/runtime/utils.d.ts +26 -5
- package/dist/types/rsc/client.d.ts +1 -0
- package/dist/types/rsc/server.d.ts +1 -0
- package/package.json +21 -12
- package/static/modern-inline.js +1 -1
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { JS_EXTENSIONS, findExists, formatImportPath } from "@modern-js/utils";
|
|
3
3
|
import { ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME, ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME } from "./constants";
|
|
4
|
-
const
|
|
4
|
+
const genRenderStatement = ({ customBootstrap, enableRsc, mountId, isNestedRouter }) => {
|
|
5
|
+
if (customBootstrap) {
|
|
6
|
+
return `customBootstrap(ModernRoot, () => render(<ModernRoot />, '${mountId || "root"}'));`;
|
|
7
|
+
}
|
|
8
|
+
if (enableRsc) {
|
|
9
|
+
if (!isNestedRouter) {
|
|
10
|
+
return `render(<ModernRoot>
|
|
11
|
+
<RscClientRoot rscPayload={data} />
|
|
12
|
+
</ModernRoot>, '${mountId || "root"}');`;
|
|
13
|
+
}
|
|
14
|
+
return `render(<ModernRoot rscPayload={data} />, '${mountId || "root"}');`;
|
|
15
|
+
}
|
|
16
|
+
return `render(<ModernRoot />, '${mountId || "root"}');`;
|
|
17
|
+
};
|
|
18
|
+
const genRenderCode = ({ srcDirectory, internalSrcAlias, metaName, entry, customEntry, customBootstrap, mountId, enableRsc, isNestedRouter }) => {
|
|
5
19
|
if (customEntry) {
|
|
6
20
|
return `import '${formatImportPath(entry.replace(srcDirectory, internalSrcAlias))}'`;
|
|
7
21
|
}
|
|
@@ -20,11 +34,14 @@ ${customBootstrap ? `import customBootstrap from '${formatImportPath(customBoots
|
|
|
20
34
|
|
|
21
35
|
const ModernRoot = createRoot();
|
|
22
36
|
|
|
23
|
-
${
|
|
24
|
-
|
|
25
|
-
|
|
37
|
+
${genRenderStatement({
|
|
38
|
+
customBootstrap,
|
|
39
|
+
enableRsc,
|
|
40
|
+
mountId,
|
|
41
|
+
isNestedRouter
|
|
42
|
+
})}`;
|
|
26
43
|
};
|
|
27
|
-
const entryForCSRWithRSC = ({ metaName, entryName, urlPath = "/", mountId = "root" }) => {
|
|
44
|
+
const entryForCSRWithRSC = ({ metaName, entryName, urlPath = "/", mountId = "root", isNestedRouter }) => {
|
|
28
45
|
return `
|
|
29
46
|
import '@${metaName}/runtime/registry/${entryName}';
|
|
30
47
|
import { render } from '@${metaName}/runtime/browser';
|
|
@@ -32,28 +49,61 @@ const entryForCSRWithRSC = ({ metaName, entryName, urlPath = "/", mountId = "roo
|
|
|
32
49
|
|
|
33
50
|
import {
|
|
34
51
|
RscClientRoot,
|
|
35
|
-
createFromFetch
|
|
52
|
+
createFromFetch,
|
|
53
|
+
isRedirectResponse,
|
|
54
|
+
rscStream,
|
|
55
|
+
callServer,
|
|
56
|
+
createFromReadableStream
|
|
36
57
|
} from '@${metaName}/runtime/rsc/client';
|
|
37
58
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
59
|
+
const handleRedirectResponse = (res: Response) => {
|
|
60
|
+
const { headers } = res;
|
|
61
|
+
const location = headers.get('X-Modernjs-Redirect');
|
|
62
|
+
const baseUrl = headers.get('X-Modernjs-BaseUrl');
|
|
63
|
+
if (location) {
|
|
64
|
+
if (baseUrl !== '/') {
|
|
65
|
+
window.location.replace(baseUrl + location);
|
|
66
|
+
} else {
|
|
67
|
+
window.location.replace(location);
|
|
68
|
+
}
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
return res;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
${process.env.MODERN_DISABLE_INJECT_RSC_DATA ? `
|
|
75
|
+
const data = createFromFetch(
|
|
76
|
+
fetch(location.pathname, {
|
|
77
|
+
headers: {
|
|
78
|
+
'x-rsc-tree': 'true',
|
|
79
|
+
},
|
|
80
|
+
}).then(handleRedirectResponse),
|
|
81
|
+
)
|
|
82
|
+
` : `
|
|
83
|
+
const data = createFromReadableStream(rscStream, {
|
|
84
|
+
callServer: callServer,
|
|
85
|
+
});
|
|
86
|
+
`}
|
|
45
87
|
|
|
46
88
|
const ModernRoot = createRoot();
|
|
47
89
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
90
|
+
${isNestedRouter ? `
|
|
91
|
+
render(
|
|
92
|
+
<ModernRoot rscPayload={data}>
|
|
93
|
+
</ModernRoot>,
|
|
94
|
+
'${mountId}',
|
|
95
|
+
);
|
|
96
|
+
` : `
|
|
97
|
+
render(
|
|
98
|
+
<ModernRoot>
|
|
99
|
+
<RscClientRoot rscPayload={data} />
|
|
100
|
+
</ModernRoot>,
|
|
101
|
+
'${mountId}',
|
|
102
|
+
);
|
|
103
|
+
`}
|
|
54
104
|
`;
|
|
55
105
|
};
|
|
56
|
-
const index = ({ srcDirectory, internalSrcAlias, metaName, entry, entryName, customEntry, customBootstrap, mountId, enableRsc }) => `import '@${metaName}/runtime/registry/${entryName}';
|
|
106
|
+
const index = ({ srcDirectory, internalSrcAlias, metaName, entry, entryName, customEntry, customBootstrap, mountId, enableRsc, isNestedRouter }) => `import '@${metaName}/runtime/registry/${entryName}';
|
|
57
107
|
${genRenderCode({
|
|
58
108
|
srcDirectory,
|
|
59
109
|
internalSrcAlias,
|
|
@@ -62,7 +112,8 @@ ${genRenderCode({
|
|
|
62
112
|
customEntry,
|
|
63
113
|
customBootstrap,
|
|
64
114
|
mountId,
|
|
65
|
-
enableRsc
|
|
115
|
+
enableRsc,
|
|
116
|
+
isNestedRouter
|
|
66
117
|
})}
|
|
67
118
|
`;
|
|
68
119
|
const register = () => `import './${ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME}';
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
createRequestHandler,
|
|
25
25
|
} from '@#metaName/runtime/ssr/server';
|
|
26
26
|
import { RSCServerSlot } from '@#metaName/runtime/rsc/client';
|
|
27
|
+
import { renderRsc } from '@#metaName/runtime/rsc/server';
|
|
27
28
|
export { handleAction } from '@#metaName/runtime/rsc/server';
|
|
28
29
|
|
|
29
30
|
const handleRequest = async (request, ServerRoot, options) => {
|
|
@@ -34,7 +35,7 @@ const handleRequest = async (request, ServerRoot, options) => {
|
|
|
34
35
|
</ServerRoot>,
|
|
35
36
|
{
|
|
36
37
|
...options,
|
|
37
|
-
rscRoot:
|
|
38
|
+
rscRoot: options.rscRoot,
|
|
38
39
|
},
|
|
39
40
|
);
|
|
40
41
|
|
|
@@ -46,7 +47,22 @@ const handleRequest = async (request, ServerRoot, options) => {
|
|
|
46
47
|
};
|
|
47
48
|
|
|
48
49
|
export const requestHandler = createRequestHandler(handleRequest, {
|
|
49
|
-
enableRsc: true
|
|
50
|
+
enableRsc: true
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const handleRSCRequest = async (request, ServerRoot, options) => {
|
|
54
|
+
const { serverPayload } = options;
|
|
55
|
+
const stream = renderRsc({
|
|
56
|
+
element: options.rscRoot,
|
|
57
|
+
clientManifest: options.rscClientManifest!,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return new Response(stream);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
export const rscPayloadHandler = createRequestHandler(handleRSCRequest, {
|
|
65
|
+
enableRsc: true
|
|
50
66
|
});
|
|
51
67
|
`;
|
|
52
68
|
const serverIndex = (options) => {
|
|
@@ -56,24 +72,57 @@ const serverIndex = (options) => {
|
|
|
56
72
|
${genHandlerCode(options)}
|
|
57
73
|
`;
|
|
58
74
|
};
|
|
59
|
-
const entryForCSRWithRSC = ({ metaName }) => {
|
|
75
|
+
const entryForCSRWithRSC = ({ metaName, entryName }) => {
|
|
60
76
|
return `
|
|
61
|
-
import
|
|
62
|
-
import {
|
|
77
|
+
import '@${metaName}/runtime/registry/${entryName}';
|
|
78
|
+
import {
|
|
79
|
+
createRequestHandler,
|
|
80
|
+
} from '@${metaName}/runtime/ssr/server';
|
|
81
|
+
import { renderRsc, processRSCStream } from '@${metaName}/runtime/rsc/server'
|
|
63
82
|
export { handleAction } from '@${metaName}/runtime/rsc/server';
|
|
64
83
|
|
|
84
|
+
const handleCSRRender = async (request, ServerRoot, options) => {
|
|
85
|
+
const rscPayloadStream = renderRsc({
|
|
86
|
+
element: options.rscRoot,
|
|
87
|
+
clientManifest: options.rscClientManifest!,
|
|
88
|
+
});
|
|
89
|
+
const stream = new ReadableStream({
|
|
90
|
+
start(controller) {
|
|
91
|
+
const encoder = new TextEncoder();
|
|
92
|
+
|
|
93
|
+
controller.enqueue(encoder.encode(options.html));
|
|
65
94
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
95
|
+
processRSCStream(rscPayloadStream, controller, encoder)
|
|
96
|
+
.catch(err => {
|
|
97
|
+
controller.error(err);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
return new Response(stream, {
|
|
103
|
+
status: 200,
|
|
104
|
+
headers: new Headers({
|
|
105
|
+
'content-type': 'text/html; charset=UTF-8',
|
|
106
|
+
}),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export const renderRscStreamHandler = createRequestHandler(handleCSRRender, {
|
|
111
|
+
enableRsc: true
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const handleRequest = async (request, ServerRoot, options) => {
|
|
69
115
|
const stream = renderRsc({
|
|
70
|
-
|
|
71
|
-
clientManifest
|
|
72
|
-
})
|
|
116
|
+
element: options.rscRoot,
|
|
117
|
+
clientManifest: options.rscClientManifest!,
|
|
118
|
+
});
|
|
73
119
|
|
|
74
|
-
|
|
75
|
-
return response
|
|
120
|
+
return new Response(stream);
|
|
76
121
|
}
|
|
122
|
+
|
|
123
|
+
export const rscPayloadHandler = createRequestHandler(handleRequest, {
|
|
124
|
+
enableRsc: true
|
|
125
|
+
});
|
|
77
126
|
`;
|
|
78
127
|
};
|
|
79
128
|
function genHandlerCode({ mode, metaName, customServerEntry, srcDirectory, internalSrcAlias, enableRsc }) {
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { RuntimeReactContext, getInitialContext } from "./runtime";
|
|
2
2
|
const globalContext = {};
|
|
3
|
+
import { getServerPayload, setServerPayload } from "./serverPayload.server";
|
|
4
|
+
function getGlobalIsRscClient() {
|
|
5
|
+
return globalContext.isRscClient;
|
|
6
|
+
}
|
|
7
|
+
function getGlobalEnableRsc() {
|
|
8
|
+
return globalContext.enableRsc;
|
|
9
|
+
}
|
|
3
10
|
function setGlobalContext(context) {
|
|
4
11
|
globalContext.entryName = context.entryName;
|
|
5
12
|
globalContext.App = context.App;
|
|
@@ -8,6 +15,8 @@ function setGlobalContext(context) {
|
|
|
8
15
|
globalContext.appConfig = typeof context.appConfig === "function" ? context.appConfig() : context.appConfig;
|
|
9
16
|
globalContext.layoutApp = context.layoutApp;
|
|
10
17
|
globalContext.RSCRoot = context.RSCRoot;
|
|
18
|
+
globalContext.isRscClient = context.isRscClient;
|
|
19
|
+
globalContext.enableRsc = context.enableRsc;
|
|
11
20
|
}
|
|
12
21
|
function getCurrentEntryName() {
|
|
13
22
|
return globalContext.entryName;
|
|
@@ -44,11 +53,15 @@ export {
|
|
|
44
53
|
getGlobalApp,
|
|
45
54
|
getGlobalAppConfig,
|
|
46
55
|
getGlobalAppInit,
|
|
56
|
+
getGlobalEnableRsc,
|
|
47
57
|
getGlobalInternalRuntimeContext,
|
|
58
|
+
getGlobalIsRscClient,
|
|
48
59
|
getGlobalLayoutApp,
|
|
49
60
|
getGlobalRSCRoot,
|
|
50
61
|
getGlobalRoutes,
|
|
51
62
|
getInitialContext,
|
|
63
|
+
getServerPayload,
|
|
52
64
|
setGlobalContext,
|
|
53
|
-
setGlobalInternalRuntimeContext
|
|
65
|
+
setGlobalInternalRuntimeContext,
|
|
66
|
+
setServerPayload
|
|
54
67
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { storage } from "@modern-js/runtime-utils/node";
|
|
2
|
+
const getServerPayload = () => {
|
|
3
|
+
const context = storage.useContext();
|
|
4
|
+
return context === null || context === void 0 ? void 0 : context.serverPayload;
|
|
5
|
+
};
|
|
6
|
+
const setServerPayload = (payload) => {
|
|
7
|
+
const context = storage.useContext();
|
|
8
|
+
if (context) {
|
|
9
|
+
context.serverPayload = payload;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
getServerPayload,
|
|
14
|
+
setServerPayload
|
|
15
|
+
};
|
|
@@ -1,12 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
2
|
import { storage } from "@modern-js/runtime-utils/node";
|
|
2
3
|
import { getPathname, parseCookie, parseHeaders, parseQuery } from "@modern-js/runtime-utils/universal/request";
|
|
4
|
+
import { Fragment } from "react";
|
|
3
5
|
import { getGlobalAppInit, getGlobalInternalRuntimeContext, getGlobalRSCRoot } from "../context";
|
|
4
6
|
import { getInitialContext } from "../context/runtime";
|
|
7
|
+
import { getServerPayload } from "../context/serverPayload.server";
|
|
5
8
|
import { createLoaderManager } from "../loader/loaderManager";
|
|
6
9
|
import { createRoot } from "../react";
|
|
7
10
|
import { CHUNK_CSS_PLACEHOLDER } from "./constants";
|
|
8
11
|
import { SSRErrors } from "./tracer";
|
|
9
12
|
import { getSSRConfigByEntry, getSSRMode } from "./utils";
|
|
13
|
+
async function handleRSCRequest(request, Root, context, options, handleRequest) {
|
|
14
|
+
const serverPayload = getServerPayload();
|
|
15
|
+
if (typeof serverPayload !== "undefined") {
|
|
16
|
+
return await handleRequest(request, Root, {
|
|
17
|
+
...options,
|
|
18
|
+
runtimeContext: context,
|
|
19
|
+
rscRoot: serverPayload
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
const App = getGlobalRSCRoot();
|
|
23
|
+
if (App) {
|
|
24
|
+
return await handleRequest(request, Fragment, {
|
|
25
|
+
...options,
|
|
26
|
+
runtimeContext: context,
|
|
27
|
+
rscRoot: /* @__PURE__ */ _jsx(App, {})
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return await handleRequest(request, Root, {
|
|
31
|
+
...options,
|
|
32
|
+
runtimeContext: context
|
|
33
|
+
});
|
|
34
|
+
}
|
|
10
35
|
function createSSRContext(request, options) {
|
|
11
36
|
const { config, loaderContext, onError, onTiming, locals, resource, params, responseProxy, logger, metrics, reporter } = options;
|
|
12
37
|
const { nonce, useJsonScript } = config;
|
|
@@ -77,7 +102,8 @@ const createRequestHandler = async (handleRequest, createRequestOptions) => {
|
|
|
77
102
|
request,
|
|
78
103
|
monitors: options.monitors,
|
|
79
104
|
responseProxy,
|
|
80
|
-
activeDeferreds
|
|
105
|
+
activeDeferreds,
|
|
106
|
+
serverPayload: void 0
|
|
81
107
|
}, async () => {
|
|
82
108
|
var _context_routerContext, _context_routerContext1, _context_routerContext2;
|
|
83
109
|
const Root = createRoot();
|
|
@@ -135,15 +161,25 @@ const createRequestHandler = async (handleRequest, createRequestOptions) => {
|
|
|
135
161
|
context.initialData = initialData;
|
|
136
162
|
const redirectResponse = getRedirectResponse(initialData);
|
|
137
163
|
if (redirectResponse) {
|
|
138
|
-
|
|
164
|
+
if (createRequestOptions === null || createRequestOptions === void 0 ? void 0 : createRequestOptions.enableRsc) {
|
|
165
|
+
return initialData;
|
|
166
|
+
} else {
|
|
167
|
+
return redirectResponse;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (!(createRequestOptions === null || createRequestOptions === void 0 ? void 0 : createRequestOptions.enableRsc)) {
|
|
171
|
+
const { htmlTemplate } = options.resource;
|
|
172
|
+
options.resource.htmlTemplate = htmlTemplate.replace("</head>", `${CHUNK_CSS_PLACEHOLDER}</head>`);
|
|
173
|
+
}
|
|
174
|
+
let response;
|
|
175
|
+
if (createRequestOptions === null || createRequestOptions === void 0 ? void 0 : createRequestOptions.enableRsc) {
|
|
176
|
+
response = await handleRSCRequest(request, Root, context, options, handleRequest);
|
|
177
|
+
} else {
|
|
178
|
+
response = await handleRequest(request, Root, {
|
|
179
|
+
...options,
|
|
180
|
+
runtimeContext: context
|
|
181
|
+
});
|
|
139
182
|
}
|
|
140
|
-
const { htmlTemplate } = options.resource;
|
|
141
|
-
options.resource.htmlTemplate = htmlTemplate.replace("</head>", `${CHUNK_CSS_PLACEHOLDER}</head>`);
|
|
142
|
-
const response = await handleRequest(request, Root, {
|
|
143
|
-
...options,
|
|
144
|
-
runtimeContext: context,
|
|
145
|
-
RSCRoot: (createRequestOptions === null || createRequestOptions === void 0 ? void 0 : createRequestOptions.enableRsc) && getGlobalRSCRoot()
|
|
146
|
-
});
|
|
147
183
|
Object.entries(responseProxy.headers).forEach(([key, value]) => {
|
|
148
184
|
response.headers.set(key, value);
|
|
149
185
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
-
import { fs, getEntryOptions, isSSGEntry, isUseSSRBundle, logger } from "@modern-js/utils";
|
|
2
|
+
import { fs, getEntryOptions, isSSGEntry, isUseRsc, isUseSSRBundle, logger } from "@modern-js/utils";
|
|
3
3
|
import { filterRoutesForServer, filterRoutesLoader, markRoutes } from "@modern-js/utils";
|
|
4
4
|
import { cloneDeep } from "@modern-js/utils/lodash";
|
|
5
5
|
import { ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME } from "../../../cli/constants";
|
|
@@ -73,14 +73,15 @@ const generateCode = async (appContext, config, entrypoints, api, isRouterV5) =>
|
|
|
73
73
|
code: await templates.fileSystemRoutes({
|
|
74
74
|
metaName,
|
|
75
75
|
routes,
|
|
76
|
-
ssrMode: useSSG ? "string" : mode,
|
|
76
|
+
ssrMode: useSSG ? "string" : isUseRsc(config2) ? "stream" : mode,
|
|
77
77
|
nestedRoutesEntry: entrypoint.nestedRoutesEntry,
|
|
78
78
|
entryName: entrypoint.entryName,
|
|
79
79
|
internalDirectory,
|
|
80
|
-
splitRouteChunks: config2 === null || config2 === void 0 ? void 0 : (_config_output = config2.output) === null || _config_output === void 0 ? void 0 : _config_output.splitRouteChunks
|
|
80
|
+
splitRouteChunks: config2 === null || config2 === void 0 ? void 0 : (_config_output = config2.output) === null || _config_output === void 0 ? void 0 : _config_output.splitRouteChunks,
|
|
81
|
+
isRscClient: isUseRsc(config2)
|
|
81
82
|
})
|
|
82
83
|
});
|
|
83
|
-
if (entrypoint.nestedRoutesEntry && isUseSSRBundle(config2)) {
|
|
84
|
+
if (entrypoint.nestedRoutesEntry && (isUseSSRBundle(config2) || isUseRsc(config2))) {
|
|
84
85
|
var _config_output1;
|
|
85
86
|
const routesServerFile = getServerLoadersFile(internalDirectory, entryName);
|
|
86
87
|
const filtedRoutesForServer = filterRoutesForServer(routes);
|
|
@@ -97,7 +98,8 @@ const generateCode = async (appContext, config, entrypoints, api, isRouterV5) =>
|
|
|
97
98
|
nestedRoutesEntry: entrypoint.nestedRoutesEntry,
|
|
98
99
|
entryName: entrypoint.entryName,
|
|
99
100
|
internalDirectory,
|
|
100
|
-
splitRouteChunks: config2 === null || config2 === void 0 ? void 0 : (_config_output1 = config2.output) === null || _config_output1 === void 0 ? void 0 : _config_output1.splitRouteChunks
|
|
101
|
+
splitRouteChunks: config2 === null || config2 === void 0 ? void 0 : (_config_output1 = config2.output) === null || _config_output1 === void 0 ? void 0 : _config_output1.splitRouteChunks,
|
|
102
|
+
isRscClient: false
|
|
101
103
|
});
|
|
102
104
|
await fs.outputFile(path.resolve(internalDirectory, `./${entryName}/routes.server.js`), serverRoutesCode, "utf8");
|
|
103
105
|
}
|
|
@@ -114,7 +116,11 @@ const generateCode = async (appContext, config, entrypoints, api, isRouterV5) =>
|
|
|
114
116
|
function generatorRegisterCode(internalDirectory, entryName, code) {
|
|
115
117
|
fs.outputFileSync(path.resolve(internalDirectory, `./${entryName}/${ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME}.js`), code, "utf8");
|
|
116
118
|
}
|
|
119
|
+
function generatorServerRegisterCode(internalDirectory, entryName, code) {
|
|
120
|
+
fs.outputFileSync(path.resolve(internalDirectory, `./${entryName}/${ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME}.server.js`), code, "utf8");
|
|
121
|
+
}
|
|
117
122
|
export {
|
|
118
123
|
generateCode,
|
|
119
|
-
generatorRegisterCode
|
|
124
|
+
generatorRegisterCode,
|
|
125
|
+
generatorServerRegisterCode
|
|
120
126
|
};
|
|
@@ -85,7 +85,7 @@ const routesForServer = ({ routesForServerLoaderMatches }) => {
|
|
|
85
85
|
};
|
|
86
86
|
const createMatchReg = (keyword) => new RegExp(`("${keyword}":\\s)"([^
|
|
87
87
|
]+)"`, "g");
|
|
88
|
-
const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry, entryName, internalDirectory, splitRouteChunks = true }) => {
|
|
88
|
+
const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry, entryName, internalDirectory, splitRouteChunks = true, isRscClient = false }) => {
|
|
89
89
|
const components = [];
|
|
90
90
|
const loadings = [];
|
|
91
91
|
const errors = [];
|
|
@@ -111,14 +111,14 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
111
111
|
return "";
|
|
112
112
|
};
|
|
113
113
|
const createLazyImport = ({ componentPath, routeId, webpackChunkName, eager }) => {
|
|
114
|
-
const importOptions = webpackChunkName ? `/* webpackChunkName: "${routeId}" */
|
|
114
|
+
const importOptions = webpackChunkName ? `/* webpackChunkName: "${routeId}" */ ` : eager ? `/* webpackMode: "eager" */ ` : "";
|
|
115
115
|
return `() => import(${importOptions}'${componentPath}').then(routeModule => handleRouteModule(routeModule, "${routeId}")).catch(handleRouteModuleError)`;
|
|
116
116
|
};
|
|
117
|
-
const traverseRouteTree = (route) => {
|
|
117
|
+
const traverseRouteTree = (route, isRscClient2) => {
|
|
118
118
|
let children;
|
|
119
119
|
if ("children" in route && route.children) {
|
|
120
120
|
var _route_children;
|
|
121
|
-
children = route === null || route === void 0 ? void 0 : (_route_children = route.children) === null || _route_children === void 0 ? void 0 : _route_children.map(traverseRouteTree);
|
|
121
|
+
children = route === null || route === void 0 ? void 0 : (_route_children = route.children) === null || _route_children === void 0 ? void 0 : _route_children.map((child) => traverseRouteTree(child, isRscClient2));
|
|
122
122
|
}
|
|
123
123
|
let loading;
|
|
124
124
|
let error;
|
|
@@ -201,7 +201,6 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
201
201
|
}
|
|
202
202
|
const finalRoute = {
|
|
203
203
|
...route,
|
|
204
|
-
lazyImport,
|
|
205
204
|
loading,
|
|
206
205
|
loader,
|
|
207
206
|
action,
|
|
@@ -209,7 +208,10 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
209
208
|
error,
|
|
210
209
|
children
|
|
211
210
|
};
|
|
212
|
-
if (
|
|
211
|
+
if (!isRscClient2) {
|
|
212
|
+
finalRoute.lazyImport = lazyImport;
|
|
213
|
+
}
|
|
214
|
+
if (route._component && !isRscClient2) {
|
|
213
215
|
finalRoute.component = component;
|
|
214
216
|
}
|
|
215
217
|
if (route.type === "nested" && route._component && (route.loader || route.data)) {
|
|
@@ -222,7 +224,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
222
224
|
`;
|
|
223
225
|
for (const route of routes) {
|
|
224
226
|
if ("type" in route) {
|
|
225
|
-
const newRoute = traverseRouteTree(route);
|
|
227
|
+
const newRoute = traverseRouteTree(route, isRscClient);
|
|
226
228
|
const routeStr = JSON.stringify(newRoute, null, 2);
|
|
227
229
|
const keywords = [
|
|
228
230
|
"component",
|
|
@@ -321,9 +323,9 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
321
323
|
`;
|
|
322
324
|
return `
|
|
323
325
|
${importLazyCode}
|
|
324
|
-
${importComponentsCode}
|
|
326
|
+
${!isRscClient ? importComponentsCode : ""}
|
|
325
327
|
${importRuntimeRouterCode}
|
|
326
|
-
${rootLayoutCode}
|
|
328
|
+
${!isRscClient ? rootLayoutCode : ""}
|
|
327
329
|
${importLoadingCode}
|
|
328
330
|
${importErrorComponentsCode}
|
|
329
331
|
${importLoadersCode}
|
|
@@ -362,7 +364,7 @@ function ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext) {
|
|
|
362
364
|
}
|
|
363
365
|
return null;
|
|
364
366
|
}
|
|
365
|
-
const runtimeGlobalContext = async ({ entryName, metaName, srcDirectory, nestedRoutesEntry, internalSrcAlias, globalApp }) => {
|
|
367
|
+
const runtimeGlobalContext = async ({ entryName, metaName, srcDirectory, nestedRoutesEntry, internalSrcAlias, globalApp, rscType = false }) => {
|
|
366
368
|
const imports = [
|
|
367
369
|
`import { setGlobalContext } from '@${metaName}/runtime/context';`
|
|
368
370
|
];
|
|
@@ -407,18 +409,40 @@ const runtimeGlobalContext = async ({ entryName, metaName, srcDirectory, nestedR
|
|
|
407
409
|
} else {
|
|
408
410
|
imports.push(`let layoutApp;`);
|
|
409
411
|
}
|
|
410
|
-
|
|
412
|
+
const isClient = rscType === "client";
|
|
413
|
+
const enableRsc = Boolean(rscType);
|
|
414
|
+
if (isClient) {
|
|
415
|
+
return `${imports.join("\n")}
|
|
416
|
+
|
|
417
|
+
import { routes } from './routes';
|
|
418
|
+
|
|
419
|
+
const entryName = '${entryName}';
|
|
420
|
+
setGlobalContext({
|
|
421
|
+
entryName,
|
|
422
|
+
layoutApp,
|
|
423
|
+
routes,
|
|
424
|
+
appInit,
|
|
425
|
+
appConfig,
|
|
426
|
+
isRscClient: true,
|
|
427
|
+
enableRsc: true,
|
|
428
|
+
});
|
|
429
|
+
`;
|
|
430
|
+
} else {
|
|
431
|
+
return `${imports.join("\n")}
|
|
411
432
|
|
|
412
|
-
import { routes } from './routes';
|
|
433
|
+
import { routes } from './routes';
|
|
413
434
|
|
|
414
|
-
const entryName = '${entryName}';
|
|
415
|
-
setGlobalContext({
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
}
|
|
435
|
+
const entryName = '${entryName}';
|
|
436
|
+
setGlobalContext({
|
|
437
|
+
entryName,
|
|
438
|
+
layoutApp,
|
|
439
|
+
routes,
|
|
440
|
+
appInit,
|
|
441
|
+
appConfig,
|
|
442
|
+
enableRsc: ${enableRsc},
|
|
443
|
+
});
|
|
444
|
+
`;
|
|
445
|
+
}
|
|
422
446
|
};
|
|
423
447
|
export {
|
|
424
448
|
fileSystemRoutes,
|
|
@@ -8,11 +8,13 @@ async function handleModifyEntrypoints(isRouterV5, entrypoints) {
|
|
|
8
8
|
return modifyEntrypoints(entrypoints, isRouterV5);
|
|
9
9
|
}
|
|
10
10
|
async function handleGeneratorEntryCode(api, entrypoints, isRouterV5) {
|
|
11
|
+
var _resolvedConfig_server;
|
|
11
12
|
const appContext = api.getAppContext();
|
|
12
13
|
const { internalDirectory } = appContext;
|
|
13
14
|
const resolvedConfig = api.getNormalizedConfig();
|
|
14
|
-
const { generatorRegisterCode, generateCode } = await import("./code");
|
|
15
|
+
const { generatorRegisterCode, generateCode, generatorServerRegisterCode } = await import("./code");
|
|
15
16
|
originEntrypoints = cloneDeep(entrypoints);
|
|
17
|
+
const enableRsc = resolvedConfig === null || resolvedConfig === void 0 ? void 0 : (_resolvedConfig_server = resolvedConfig.server) === null || _resolvedConfig_server === void 0 ? void 0 : _resolvedConfig_server.rsc;
|
|
16
18
|
await generateCode(appContext, resolvedConfig, entrypoints, api, isRouterV5);
|
|
17
19
|
await Promise.all(entrypoints.map(async (entrypoint) => {
|
|
18
20
|
if (entrypoint.nestedRoutesEntry || entrypoint.pageRoutesEntry) {
|
|
@@ -23,8 +25,21 @@ async function handleGeneratorEntryCode(api, entrypoints, isRouterV5) {
|
|
|
23
25
|
srcDirectory: appContext.srcDirectory,
|
|
24
26
|
nestedRoutesEntry: entrypoint.nestedRoutesEntry,
|
|
25
27
|
internalSrcAlias: appContext.internalSrcAlias,
|
|
26
|
-
globalApp: (_entrypoint_fileSystemRoutes = entrypoint.fileSystemRoutes) === null || _entrypoint_fileSystemRoutes === void 0 ? void 0 : _entrypoint_fileSystemRoutes.globalApp
|
|
28
|
+
globalApp: (_entrypoint_fileSystemRoutes = entrypoint.fileSystemRoutes) === null || _entrypoint_fileSystemRoutes === void 0 ? void 0 : _entrypoint_fileSystemRoutes.globalApp,
|
|
29
|
+
rscType: enableRsc ? "client" : void 0
|
|
27
30
|
}));
|
|
31
|
+
if (enableRsc) {
|
|
32
|
+
var _entrypoint_fileSystemRoutes1;
|
|
33
|
+
generatorServerRegisterCode(internalDirectory, entrypoint.entryName, await templates.runtimeGlobalContext({
|
|
34
|
+
entryName: entrypoint.entryName,
|
|
35
|
+
metaName: appContext.metaName,
|
|
36
|
+
srcDirectory: appContext.srcDirectory,
|
|
37
|
+
nestedRoutesEntry: entrypoint.nestedRoutesEntry,
|
|
38
|
+
internalSrcAlias: appContext.internalSrcAlias,
|
|
39
|
+
globalApp: (_entrypoint_fileSystemRoutes1 = entrypoint.fileSystemRoutes) === null || _entrypoint_fileSystemRoutes1 === void 0 ? void 0 : _entrypoint_fileSystemRoutes1.globalApp,
|
|
40
|
+
rscType: "server"
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
28
43
|
}
|
|
29
44
|
}));
|
|
30
45
|
return entrypoints;
|
|
@@ -25,7 +25,7 @@ const routerPlugin = () => ({
|
|
|
25
25
|
if ((nestedRoutesEntry || pageRoutesEntry) && !isRouterV5) {
|
|
26
26
|
plugins.push({
|
|
27
27
|
name: "router",
|
|
28
|
-
path: `@${metaName2}/runtime/router`,
|
|
28
|
+
path: `@${metaName2}/runtime/router/internal`,
|
|
29
29
|
config: typeof routerConfig === "boolean" ? {
|
|
30
30
|
serverBase
|
|
31
31
|
} : {
|
|
@@ -52,9 +52,10 @@ const routerPlugin = () => ({
|
|
|
52
52
|
// react-router v6 is no longer support ie 11
|
|
53
53
|
// so we need to compile these packages to ensure the compatibility
|
|
54
54
|
// https://github.com/remix-run/react-router/commit/f6df0697e1b2064a2b3a12e8b39577326fdd945b
|
|
55
|
-
/node_modules
|
|
56
|
-
/node_modules
|
|
57
|
-
/node_modules
|
|
55
|
+
/[\\/]node_modules[\\/]react-router[\\/]/,
|
|
56
|
+
/[\\/]node_modules[\\/]react-router-dom[\\/]/,
|
|
57
|
+
/[\\/]node_modules[\\/]@remix-run[\\/]router[\\/]/,
|
|
58
|
+
path.resolve(__dirname, "../runtime").replace("cjs", "esm")
|
|
58
59
|
],
|
|
59
60
|
globalVars: {
|
|
60
61
|
"process.env._MODERN_ROUTER_VERSION": "v6"
|
|
@@ -75,7 +76,7 @@ const routerPlugin = () => ({
|
|
|
75
76
|
const { internalDirectory, metaName: metaName2 } = api.useAppContext();
|
|
76
77
|
const pluginsExportsUtils = createRuntimeExportsUtils(internalDirectory, "plugins");
|
|
77
78
|
if (!isRouterV5) {
|
|
78
|
-
pluginsExportsUtils.addExport(`export { default as router } from '@${metaName2}/runtime/router'`);
|
|
79
|
+
pluginsExportsUtils.addExport(`export { default as router } from '@${metaName2}/runtime/router/internal'`);
|
|
79
80
|
}
|
|
80
81
|
});
|
|
81
82
|
api.onFileChanged(async (e) => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
3
|
import { Link as RouterLink, NavLink as RouterNavLink, matchRoutes, useHref, useMatches, useResolvedPath } from "@modern-js/runtime-utils/router";
|
|
3
4
|
import React, { useContext, useMemo } from "react";
|
|
@@ -187,6 +188,5 @@ const NavLink = createPrefetchLink(RouterNavLink);
|
|
|
187
188
|
NavLink.displayName = "NavLink";
|
|
188
189
|
export {
|
|
189
190
|
Link,
|
|
190
|
-
NavLink
|
|
191
|
-
composeEventHandlers
|
|
191
|
+
NavLink
|
|
192
192
|
};
|
|
@@ -2,9 +2,9 @@ import { ROUTER_DATA_JSON_ID } from "../../core/constants";
|
|
|
2
2
|
const setupFnStr = `function s(r,e){_ROUTER_DATA.r=_ROUTER_DATA.r||{},_ROUTER_DATA.r[r]=_ROUTER_DATA.r[r]||{};return new Promise((function(A,R){_ROUTER_DATA.r[r][e]={resolve:A,reject:R}}))};`;
|
|
3
3
|
const resolveFnStr = `function r(e,r,o,A){A?_ROUTER_DATA.r[e][r].reject(A):_ROUTER_DATA.r[e][r].resolve(o)};`;
|
|
4
4
|
const preResolvedFnStr = `function p(e,r){return void 0!==r?Promise.reject(new Error(r.message)):Promise.resolve(e)};`;
|
|
5
|
-
const mergeLoaderDataStr = `function mergeLoaderData(e,n){
|
|
5
|
+
const mergeLoaderDataStr = `function mergeLoaderData(e,n){var r=n.reduce((function(e,{key:n,routerDataFnName:r,routerDataFnArgs:a}){var t=a.map((e=>{if("undefined"!==e&&null!==e)return JSON.parse(e)}));return console.info("args",t),{...e,[n]:_ROUTER_DATA[r](...t)}}),{});Object.assign(_ROUTER_DATA.loaderData[e],r)}`;
|
|
6
6
|
const initRouterDataAttrs = `_ROUTER_DATA.s = ${setupFnStr}_ROUTER_DATA.r = ${resolveFnStr}_ROUTER_DATA.p = ${preResolvedFnStr}${mergeLoaderDataStr}`;
|
|
7
|
-
const modernInline = `function runWindowFn(){window[document.currentScript.getAttribute("data-fn-name")](
|
|
7
|
+
const modernInline = `function runWindowFn(){window[document.currentScript.getAttribute("data-fn-name")].apply(window,JSON.parse(document.currentScript.getAttribute("data-fn-args")))}function runRouterDataFn(){_ROUTER_DATA[document.currentScript.getAttribute("data-fn-name")].apply(_ROUTER_DATA,JSON.parse(document.currentScript.getAttribute("data-fn-args")))}function initRouterData(e){var r=document.getElementById(e);if(r)try{_ROUTER_DATA=JSON.parse(r.textContent)}catch(r){console.error("parse ".concat(e," error"),t),_ROUTER_DATA={}}};initRouterData('${ROUTER_DATA_JSON_ID}');${initRouterDataAttrs}`;
|
|
8
8
|
const runRouterDataFnStr = `runRouterDataFn();`;
|
|
9
9
|
const runWindowFnStr = `runWindowFn();`;
|
|
10
10
|
export {
|