@modern-js/runtime 2.61.0 → 2.62.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/dist/cjs/core/server/requestHandler.js +2 -0
- package/dist/cjs/core/server/stream/afterTemplate.js +9 -5
- package/dist/cjs/core/server/string/ssrData.js +1 -1
- package/dist/cjs/core/server/utils.js +8 -0
- package/dist/cjs/document/Script.js +9 -3
- package/dist/cjs/document/cli/index.js +2 -2
- package/dist/cjs/document/constants.js +6 -0
- package/dist/cjs/router/runtime/DeferredDataScripts.node.js +40 -18
- package/dist/cjs/router/runtime/constants.js +13 -0
- package/dist/cjs/router/runtime/plugin.js +0 -7
- package/dist/cjs/router/runtime/plugin.node.js +4 -3
- package/dist/esm/core/server/requestHandler.js +3 -1
- package/dist/esm/core/server/stream/afterTemplate.js +6 -2
- package/dist/esm/core/server/string/ssrData.js +2 -2
- package/dist/esm/core/server/utils.js +8 -0
- package/dist/esm/document/Script.js +13 -5
- package/dist/esm/document/cli/index.js +4 -4
- package/dist/esm/document/constants.js +4 -0
- package/dist/esm/router/runtime/DeferredDataScripts.node.js +40 -20
- package/dist/esm/router/runtime/constants.js +9 -0
- package/dist/esm/router/runtime/plugin.js +0 -7
- package/dist/esm/router/runtime/plugin.node.js +4 -3
- package/dist/esm-node/core/server/requestHandler.js +3 -1
- package/dist/esm-node/core/server/stream/afterTemplate.js +8 -4
- package/dist/esm-node/core/server/string/ssrData.js +2 -2
- package/dist/esm-node/core/server/utils.js +7 -0
- package/dist/esm-node/document/Script.js +11 -5
- package/dist/esm-node/document/cli/index.js +3 -3
- package/dist/esm-node/document/constants.js +4 -0
- package/dist/esm-node/router/runtime/DeferredDataScripts.node.js +40 -18
- package/dist/esm-node/router/runtime/constants.js +9 -0
- package/dist/esm-node/router/runtime/plugin.js +0 -7
- package/dist/esm-node/router/runtime/plugin.node.js +4 -3
- package/dist/types/core/context/runtime.d.ts +1 -5
- package/dist/types/core/server/stream/afterTemplate.d.ts +1 -1
- package/dist/types/core/server/utils.d.ts +1 -0
- package/dist/types/core/types.d.ts +1 -0
- package/dist/types/document/Script.d.ts +5 -4
- package/dist/types/document/constants.d.ts +2 -0
- package/dist/types/router/runtime/DeferredDataScripts.node.d.ts +1 -0
- package/dist/types/router/runtime/constants.d.ts +34 -0
- package/package.json +15 -12
- package/scripts/gen-static.ts +26 -0
- package/static/modern-inline.js +1 -0
- package/static/modern-run-router-data-fn.js +1 -0
- package/static/modern-run-window-fn.js +1 -0
|
@@ -3,10 +3,12 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { serializeJson } from "@modern-js/runtime-utils/node";
|
|
4
4
|
import { Await, useAsyncError } from "@modern-js/runtime-utils/router";
|
|
5
5
|
import { Suspense, useEffect, useMemo, useRef } from "react";
|
|
6
|
-
import {
|
|
6
|
+
import { ROUTER_DATA_JSON_ID } from "../../core/constants";
|
|
7
|
+
import { modernInline, runRouterDataFnStr, runWindowFnStr } from "./constants";
|
|
7
8
|
import { serializeErrors } from "./utils";
|
|
8
9
|
var DeferredDataScripts = function(props) {
|
|
9
10
|
var staticContext = props === null || props === void 0 ? void 0 : props.context;
|
|
11
|
+
var inlineScript = props === null || props === void 0 ? void 0 : props.inlineScript;
|
|
10
12
|
var hydratedRef = useRef(false);
|
|
11
13
|
useEffect(function() {
|
|
12
14
|
hydratedRef.current = true;
|
|
@@ -20,13 +22,11 @@ var DeferredDataScripts = function(props) {
|
|
|
20
22
|
loaderData: staticContext.loaderData,
|
|
21
23
|
errors: serializeErrors(staticContext.errors)
|
|
22
24
|
};
|
|
23
|
-
var initialScript0 = "
|
|
24
|
-
var initialScript1 = [
|
|
25
|
-
"_ROUTER_DATA
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
mergeLoaderDataStr
|
|
29
|
-
].join("\n");
|
|
25
|
+
var initialScript0 = inlineScript ? "" : "".concat(serializeJson(_ROUTER_DATA));
|
|
26
|
+
var initialScript1 = inlineScript ? [
|
|
27
|
+
"_ROUTER_DATA = ".concat(serializeJson(_ROUTER_DATA), ";"),
|
|
28
|
+
modernInline
|
|
29
|
+
].join("\n") : modernInline;
|
|
30
30
|
var deferredDataScripts = [];
|
|
31
31
|
var initialScripts = Object.entries(activeDeferreds).map(function(param) {
|
|
32
32
|
var _param = _sliced_to_array(param, 2), routeId = _param[0], deferredData = _param[1];
|
|
@@ -79,10 +79,12 @@ var DeferredDataScripts = function(props) {
|
|
|
79
79
|
});
|
|
80
80
|
return {
|
|
81
81
|
fnName: "mergeLoaderData",
|
|
82
|
+
fnRun: runWindowFnStr,
|
|
82
83
|
fnArgs: [
|
|
83
84
|
routeId,
|
|
84
85
|
deferredKeyPromiseManifests
|
|
85
|
-
]
|
|
86
|
+
],
|
|
87
|
+
fnScriptSrc: "modern-run-window-fn"
|
|
86
88
|
};
|
|
87
89
|
});
|
|
88
90
|
return [
|
|
@@ -99,8 +101,9 @@ var DeferredDataScripts = function(props) {
|
|
|
99
101
|
children: [
|
|
100
102
|
!hydratedRef.current && /* @__PURE__ */ _jsxs(_Fragment, {
|
|
101
103
|
children: [
|
|
102
|
-
/* @__PURE__ */ _jsx("script", {
|
|
103
|
-
|
|
104
|
+
deferredScripts[0].length !== 0 && /* @__PURE__ */ _jsx("script", {
|
|
105
|
+
type: "application/json",
|
|
106
|
+
id: ROUTER_DATA_JSON_ID,
|
|
104
107
|
nonce: props === null || props === void 0 ? void 0 : props.nonce,
|
|
105
108
|
suppressHydrationWarning: true,
|
|
106
109
|
dangerouslySetInnerHTML: {
|
|
@@ -110,21 +113,23 @@ var DeferredDataScripts = function(props) {
|
|
|
110
113
|
/* @__PURE__ */ _jsx("script", {
|
|
111
114
|
async: true,
|
|
112
115
|
nonce: props === null || props === void 0 ? void 0 : props.nonce,
|
|
116
|
+
"data-script-src": "modern-inline",
|
|
113
117
|
suppressHydrationWarning: true,
|
|
114
118
|
dangerouslySetInnerHTML: {
|
|
115
119
|
__html: deferredScripts[1]
|
|
116
120
|
}
|
|
117
121
|
}),
|
|
118
122
|
deferredScripts[2].map(function(param) {
|
|
119
|
-
var fnName = param.fnName, fnArgs = param.fnArgs;
|
|
123
|
+
var fnName = param.fnName, fnArgs = param.fnArgs, fnRun = param.fnRun, fnScriptSrc = param.fnScriptSrc;
|
|
120
124
|
return /* @__PURE__ */ _jsx("script", {
|
|
121
125
|
async: true,
|
|
126
|
+
"data-script-src": fnScriptSrc,
|
|
127
|
+
"data-fn-name": fnName,
|
|
128
|
+
"data-fn-args": JSON.stringify(fnArgs),
|
|
122
129
|
nonce: props === null || props === void 0 ? void 0 : props.nonce,
|
|
123
130
|
suppressHydrationWarning: true,
|
|
124
131
|
dangerouslySetInnerHTML: {
|
|
125
|
-
__html:
|
|
126
|
-
return "".concat(JSON.stringify(argv));
|
|
127
|
-
}).join(","), ")")
|
|
132
|
+
__html: fnRun
|
|
128
133
|
}
|
|
129
134
|
}, fnName);
|
|
130
135
|
})
|
|
@@ -148,9 +153,16 @@ var DeferredDataScript = function(param) {
|
|
|
148
153
|
return /* @__PURE__ */ _jsx("script", {
|
|
149
154
|
async: true,
|
|
150
155
|
nonce,
|
|
156
|
+
"data-fn-name": "r",
|
|
157
|
+
"data-script-src": "modern-run-router-data-fn",
|
|
158
|
+
"data-fn-args": "".concat(JSON.stringify([
|
|
159
|
+
routeId,
|
|
160
|
+
dataKey,
|
|
161
|
+
data2
|
|
162
|
+
])),
|
|
151
163
|
suppressHydrationWarning: true,
|
|
152
164
|
dangerouslySetInnerHTML: {
|
|
153
|
-
__html:
|
|
165
|
+
__html: runRouterDataFnStr
|
|
154
166
|
}
|
|
155
167
|
});
|
|
156
168
|
}
|
|
@@ -161,13 +173,21 @@ var ErrorDeferredDataScript = function(param) {
|
|
|
161
173
|
var routeId = param.routeId, dataKey = param.dataKey, nonce = param.nonce;
|
|
162
174
|
var error = useAsyncError();
|
|
163
175
|
return /* @__PURE__ */ _jsx("script", {
|
|
176
|
+
"data-fn-name": "r",
|
|
177
|
+
"data-script-src": "modern-run-router-data-fn",
|
|
178
|
+
"data-fn-args": "".concat(JSON.stringify([
|
|
179
|
+
routeId,
|
|
180
|
+
dataKey,
|
|
181
|
+
void 0,
|
|
182
|
+
{
|
|
183
|
+
message: error.message,
|
|
184
|
+
stack: error.stack
|
|
185
|
+
}
|
|
186
|
+
])),
|
|
164
187
|
nonce,
|
|
165
188
|
suppressHydrationWarning: true,
|
|
166
189
|
dangerouslySetInnerHTML: {
|
|
167
|
-
__html:
|
|
168
|
-
message: error.message,
|
|
169
|
-
stack: error.stack
|
|
170
|
-
}), ");")
|
|
190
|
+
__html: runRouterDataFnStr
|
|
171
191
|
}
|
|
172
192
|
});
|
|
173
193
|
};
|
|
@@ -1,10 +1,19 @@
|
|
|
1
|
+
import { ROUTER_DATA_JSON_ID } from "../../core/constants";
|
|
1
2
|
var 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}}))};";
|
|
2
3
|
var resolveFnStr = "function r(e,r,o,A){A?_ROUTER_DATA.r[e][r].reject(A):_ROUTER_DATA.r[e][r].resolve(o)};";
|
|
3
4
|
var preResolvedFnStr = "function p(e,r){return void 0!==r?Promise.reject(new Error(r.message)):Promise.resolve(e)};";
|
|
4
5
|
var mergeLoaderDataStr = 'function mergeLoaderData(e,n){const r=n.reduce((function(e,{key:n,routerDataFnName:r,routerDataFnArgs:a}){const 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
|
+
var initRouterDataAttrs = "_ROUTER_DATA.s = ".concat(setupFnStr, "_ROUTER_DATA.r = ").concat(resolveFnStr, "_ROUTER_DATA.p = ").concat(preResolvedFnStr).concat(mergeLoaderDataStr);
|
|
7
|
+
var modernInline = `function runWindowFn(){window[document.currentScript.getAttribute("data-fn-name")](...JSON.parse(document.currentScript.getAttribute("data-fn-args")))}function runRouterDataFn(){_ROUTER_DATA[document.currentScript.getAttribute("data-fn-name")](...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('`.concat(ROUTER_DATA_JSON_ID, "');").concat(initRouterDataAttrs);
|
|
8
|
+
var runRouterDataFnStr = "runRouterDataFn();";
|
|
9
|
+
var runWindowFnStr = "runWindowFn();";
|
|
5
10
|
export {
|
|
11
|
+
initRouterDataAttrs,
|
|
6
12
|
mergeLoaderDataStr,
|
|
13
|
+
modernInline,
|
|
7
14
|
preResolvedFnStr,
|
|
8
15
|
resolveFnStr,
|
|
16
|
+
runRouterDataFnStr,
|
|
17
|
+
runWindowFnStr,
|
|
9
18
|
setupFnStr
|
|
10
19
|
};
|
|
@@ -102,13 +102,6 @@ var routerPlugin = function() {
|
|
|
102
102
|
};
|
|
103
103
|
return originSubscribe(wrapedListener);
|
|
104
104
|
};
|
|
105
|
-
Object.defineProperty(runtimeContext, "remixRouter", {
|
|
106
|
-
get: function get() {
|
|
107
|
-
return router;
|
|
108
|
-
},
|
|
109
|
-
configurable: true,
|
|
110
|
-
enumerable: true
|
|
111
|
-
});
|
|
112
105
|
return router;
|
|
113
106
|
}, [
|
|
114
107
|
finalRouteConfig,
|
|
@@ -103,8 +103,8 @@ var routerPlugin = function() {
|
|
|
103
103
|
throw routerContext.errors[0];
|
|
104
104
|
}
|
|
105
105
|
router = createStaticRouter(routes, routerContext);
|
|
106
|
-
context.remixRouter = router;
|
|
107
106
|
context.routerContext = routerContext;
|
|
107
|
+
context.remixRouter = router;
|
|
108
108
|
context.routes = routes;
|
|
109
109
|
return [
|
|
110
110
|
2
|
|
@@ -121,7 +121,7 @@ var routerPlugin = function() {
|
|
|
121
121
|
return function() {
|
|
122
122
|
var context = useContext(RuntimeReactContext);
|
|
123
123
|
var remixRouter = context.remixRouter, routerContext = context.routerContext, ssrContext = context.ssrContext;
|
|
124
|
-
var nonce = ssrContext.nonce, mode = ssrContext.mode;
|
|
124
|
+
var nonce = ssrContext.nonce, mode = ssrContext.mode, inlineScript = ssrContext.inlineScript;
|
|
125
125
|
var routerWrapper = /* @__PURE__ */ _jsxs(_Fragment, {
|
|
126
126
|
children: [
|
|
127
127
|
/* @__PURE__ */ _jsx(StaticRouterProvider, {
|
|
@@ -133,7 +133,8 @@ var routerPlugin = function() {
|
|
|
133
133
|
// So we can inject it only when streaming ssr
|
|
134
134
|
/* @__PURE__ */ _jsx(DeferredDataScripts, {
|
|
135
135
|
nonce,
|
|
136
|
-
context: routerContext
|
|
136
|
+
context: routerContext,
|
|
137
|
+
inlineScript
|
|
137
138
|
}),
|
|
138
139
|
mode === "stream" && JSX_SHELL_STREAM_END_MARK
|
|
139
140
|
]
|
|
@@ -5,7 +5,7 @@ import { createLoaderManager } from "../loader/loaderManager";
|
|
|
5
5
|
import { getGlobalRunner } from "../plugin/runner";
|
|
6
6
|
import { createRoot } from "../react";
|
|
7
7
|
import { CHUNK_CSS_PLACEHOLDER } from "./constants";
|
|
8
|
-
import { getSSRConfigByEntry, getSSRMode } from "./utils";
|
|
8
|
+
import { getSSRConfigByEntry, getSSRInlineScript, getSSRMode } from "./utils";
|
|
9
9
|
function createSSRContext(request, options) {
|
|
10
10
|
const { config, loaderContext, onError, onTiming, locals, resource, params, responseProxy, logger, metrics, reporter } = options;
|
|
11
11
|
const { nonce } = config;
|
|
@@ -24,6 +24,7 @@ function createSSRContext(request, options) {
|
|
|
24
24
|
}
|
|
25
25
|
const ssrConfig = getSSRConfigByEntry(entryName, config.ssr, config.ssrByEntries);
|
|
26
26
|
const ssrMode = getSSRMode(ssrConfig);
|
|
27
|
+
const inlineScript = getSSRInlineScript(ssrConfig);
|
|
27
28
|
const loaderFailureMode = typeof ssrConfig === "object" ? ssrConfig.loaderFailureMode : void 0;
|
|
28
29
|
return {
|
|
29
30
|
nonce,
|
|
@@ -56,6 +57,7 @@ function createSSRContext(request, options) {
|
|
|
56
57
|
},
|
|
57
58
|
reporter,
|
|
58
59
|
mode: ssrMode,
|
|
60
|
+
inlineScript,
|
|
59
61
|
onError,
|
|
60
62
|
onTiming,
|
|
61
63
|
loaderFailureMode
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { serializeJson } from "@modern-js/runtime-utils/node";
|
|
2
|
+
import { SSR_DATA_JSON_ID } from "../../constants";
|
|
2
3
|
import { SSR_DATA_PLACEHOLDER } from "../constants";
|
|
3
4
|
import { buildHtml } from "../shared";
|
|
4
|
-
import { attributesToString, safeReplace } from "../utils";
|
|
5
|
+
import { attributesToString, getSSRInlineScript, safeReplace } from "../utils";
|
|
5
6
|
function buildShellAfterTemplate(afterAppTemplate, options) {
|
|
6
7
|
const { request, config, ssrConfig, runtimeContext, renderLevel, entryName } = options;
|
|
7
8
|
const callbacks = [
|
|
@@ -63,9 +64,12 @@ function createReplaceSSRData(options) {
|
|
|
63
64
|
const attrsStr = attributesToString({
|
|
64
65
|
nonce
|
|
65
66
|
});
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
const inlineScript = getSSRInlineScript(ssrConfig);
|
|
68
|
+
const useInlineScript = inlineScript !== false;
|
|
69
|
+
const serializeSSRData = serializeJson(ssrData);
|
|
70
|
+
const ssrDataScript = useInlineScript ? `
|
|
71
|
+
<script${attrsStr}>window._SSR_DATA = ${serializeSSRData}</script>
|
|
72
|
+
` : `<script type="application/json" id="${SSR_DATA_JSON_ID}">${serializeSSRData}</script>`;
|
|
69
73
|
return (template) => safeReplace(template, SSR_DATA_PLACEHOLDER, ssrDataScript);
|
|
70
74
|
}
|
|
71
75
|
export {
|
|
@@ -5,7 +5,7 @@ import { _ as _class_private_method_get } from "@swc/helpers/_/_class_private_me
|
|
|
5
5
|
import { _ as _class_private_method_init } from "@swc/helpers/_/_class_private_method_init";
|
|
6
6
|
import { serializeJson } from "@modern-js/runtime-utils/node";
|
|
7
7
|
import { ROUTER_DATA_JSON_ID, SSR_DATA_JSON_ID } from "../../constants";
|
|
8
|
-
import { attributesToString, serializeErrors } from "../utils";
|
|
8
|
+
import { attributesToString, getSSRInlineScript, serializeErrors } from "../utils";
|
|
9
9
|
var _options = /* @__PURE__ */ new WeakMap(), _getSSRData = /* @__PURE__ */ new WeakSet(), _getSSRDataScripts = /* @__PURE__ */ new WeakSet();
|
|
10
10
|
class SSRDataCollector {
|
|
11
11
|
effect() {
|
|
@@ -56,7 +56,7 @@ function getSSRData() {
|
|
|
56
56
|
}
|
|
57
57
|
function getSSRDataScripts(ssrData, routerData) {
|
|
58
58
|
const { nonce, ssrConfig } = _class_private_field_get(this, _options);
|
|
59
|
-
const inlineScript =
|
|
59
|
+
const inlineScript = getSSRInlineScript(ssrConfig);
|
|
60
60
|
const useInlineScript = inlineScript !== false;
|
|
61
61
|
const serializeSSRData = serializeJson(ssrData);
|
|
62
62
|
const attrsStr = attributesToString({
|
|
@@ -47,10 +47,17 @@ function getSSRMode(ssrConfig) {
|
|
|
47
47
|
}
|
|
48
48
|
return (ssrConfig === null || ssrConfig === void 0 ? void 0 : ssrConfig.mode) === "stream" ? "stream" : "string";
|
|
49
49
|
}
|
|
50
|
+
function getSSRInlineScript(ssrConfig) {
|
|
51
|
+
if (typeof ssrConfig === "object") {
|
|
52
|
+
return ssrConfig.inlineScript === void 0 ? true : ssrConfig.inlineScript;
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
50
56
|
export {
|
|
51
57
|
attributesToString,
|
|
52
58
|
checkIsNode,
|
|
53
59
|
getSSRConfigByEntry,
|
|
60
|
+
getSSRInlineScript,
|
|
54
61
|
getSSRMode,
|
|
55
62
|
safeReplace,
|
|
56
63
|
serializeErrors
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
import { jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { renderToString } from "react-dom/server";
|
|
3
|
+
import { DOCUMENT_SCRIPT_ATTRIBUTES_END, DOCUMENT_SCRIPT_ATTRIBUTES_START, DOCUMENT_SCRIPT_PLACEHOLDER_END, DOCUMENT_SCRIPT_PLACEHOLDER_START } from "./constants";
|
|
3
4
|
function Script(props) {
|
|
4
|
-
const { content } = props;
|
|
5
|
-
const contentStr = content.toString();
|
|
6
|
-
const contentIIFE = encodeURIComponent(`(${contentStr})()`);
|
|
5
|
+
const { content, ...rests } = props;
|
|
6
|
+
const contentStr = content === null || content === void 0 ? void 0 : content.toString();
|
|
7
|
+
const contentIIFE = (contentStr === null || contentStr === void 0 ? void 0 : contentStr.length) ? encodeURIComponent(`(${contentStr})()`) : "";
|
|
8
|
+
const scriptProperties = renderToString(/* @__PURE__ */ _jsx("script", {
|
|
9
|
+
...rests
|
|
10
|
+
}));
|
|
11
|
+
const scriptpPropertiesStr = encodeURIComponent(scriptProperties.replace("<script ", "").replace("></script>", ""));
|
|
7
12
|
return /* @__PURE__ */ _jsxs(_Fragment, {
|
|
8
13
|
children: [
|
|
9
14
|
`${DOCUMENT_SCRIPT_PLACEHOLDER_START}`,
|
|
15
|
+
`${DOCUMENT_SCRIPT_ATTRIBUTES_START}${scriptpPropertiesStr}${DOCUMENT_SCRIPT_ATTRIBUTES_END}`,
|
|
10
16
|
`${contentIIFE}`,
|
|
11
17
|
`${DOCUMENT_SCRIPT_PLACEHOLDER_END}`
|
|
12
18
|
]
|
|
@@ -4,7 +4,7 @@ import { build } from "esbuild";
|
|
|
4
4
|
import React from "react";
|
|
5
5
|
import ReactDomServer from "react-dom/server";
|
|
6
6
|
import { DocumentContext } from "../DocumentContext";
|
|
7
|
-
import { BODY_PARTICALS_SEPARATOR, DOCUMENT_CHUNKSMAP_PLACEHOLDER, DOCUMENT_COMMENT_PLACEHOLDER_END, DOCUMENT_COMMENT_PLACEHOLDER_START, DOCUMENT_FILE_NAME, DOCUMENT_LINKS_PLACEHOLDER, DOCUMENT_META_PLACEHOLDER, DOCUMENT_SCRIPTS_PLACEHOLDER, DOCUMENT_SCRIPT_PLACEHOLDER_END, DOCUMENT_SCRIPT_PLACEHOLDER_START, DOCUMENT_SSRDATASCRIPT_PLACEHOLDER, DOCUMENT_SSR_PLACEHOLDER, DOCUMENT_STYLE_PLACEHOLDER_END, DOCUMENT_STYLE_PLACEHOLDER_START, DOCUMENT_TITLE_PLACEHOLDER, DOC_EXT, HEAD_PARTICALS_SEPARATOR, HTML_SEPARATOR, PLACEHOLDER_REPLACER_MAP, TOP_PARTICALS_SEPARATOR } from "../constants";
|
|
7
|
+
import { BODY_PARTICALS_SEPARATOR, DOCUMENT_CHUNKSMAP_PLACEHOLDER, DOCUMENT_COMMENT_PLACEHOLDER_END, DOCUMENT_COMMENT_PLACEHOLDER_START, DOCUMENT_FILE_NAME, DOCUMENT_LINKS_PLACEHOLDER, DOCUMENT_META_PLACEHOLDER, DOCUMENT_SCRIPTS_PLACEHOLDER, DOCUMENT_SCRIPT_ATTRIBUTES_END, DOCUMENT_SCRIPT_ATTRIBUTES_START, DOCUMENT_SCRIPT_PLACEHOLDER_END, DOCUMENT_SCRIPT_PLACEHOLDER_START, DOCUMENT_SSRDATASCRIPT_PLACEHOLDER, DOCUMENT_SSR_PLACEHOLDER, DOCUMENT_STYLE_PLACEHOLDER_END, DOCUMENT_STYLE_PLACEHOLDER_START, DOCUMENT_TITLE_PLACEHOLDER, DOC_EXT, HEAD_PARTICALS_SEPARATOR, HTML_SEPARATOR, PLACEHOLDER_REPLACER_MAP, TOP_PARTICALS_SEPARATOR } from "../constants";
|
|
8
8
|
const debug = createDebugger("html_genarate");
|
|
9
9
|
const getDocumenByEntryName = function(entrypoints, entryName, fallbackDir) {
|
|
10
10
|
var _entrypoints_find;
|
|
@@ -134,9 +134,9 @@ const documentPlugin = () => ({
|
|
|
134
134
|
].join("");
|
|
135
135
|
const titles = htmlWebpackPlugin.tags.headTags.filter((item) => item.tagName === "title").join("").replace("<title>", "").replace("</title>", "") || templateParameters.title;
|
|
136
136
|
if (html.includes(DOCUMENT_SCRIPT_PLACEHOLDER_START) && html.includes(DOCUMENT_SCRIPT_PLACEHOLDER_END)) {
|
|
137
|
-
const { nonce } = config.security;
|
|
137
|
+
const { nonce } = config.security || {};
|
|
138
138
|
const nonceAttr = nonce ? `nonce=${nonce}` : "";
|
|
139
|
-
html = html.replace(new RegExp(`${DOCUMENT_SCRIPT_PLACEHOLDER_START}(.*?)${DOCUMENT_SCRIPT_PLACEHOLDER_END}`, "g"), (_scriptStr, $1) => `<script ${nonceAttr}>${decodeURIComponent($
|
|
139
|
+
html = html.replace(new RegExp(`${DOCUMENT_SCRIPT_PLACEHOLDER_START}${DOCUMENT_SCRIPT_ATTRIBUTES_START}(.*)${DOCUMENT_SCRIPT_ATTRIBUTES_END}(.*?)${DOCUMENT_SCRIPT_PLACEHOLDER_END}`, "g"), (_scriptStr, $1, $2) => `<script ${decodeURIComponent($1)} ${nonceAttr}>${decodeURIComponent($2)}</script>`);
|
|
140
140
|
}
|
|
141
141
|
if (html.includes(DOCUMENT_STYLE_PLACEHOLDER_START) && html.includes(DOCUMENT_STYLE_PLACEHOLDER_END)) {
|
|
142
142
|
html = html.replace(new RegExp(`${DOCUMENT_STYLE_PLACEHOLDER_START}(.*?)${DOCUMENT_STYLE_PLACEHOLDER_END}`, "g"), (_styleStr, $1) => `<style>${decodeURIComponent($1)}</style>`);
|
|
@@ -20,6 +20,8 @@ const DOCUMENT_SCRIPTS_PLACEHOLDER = encodeURIComponent("<!-- chunk scripts plac
|
|
|
20
20
|
const DOCUMENT_LINKS_PLACEHOLDER = encodeURIComponent("<!-- chunk links placeholder -->");
|
|
21
21
|
const DOCUMENT_SCRIPT_PLACEHOLDER_START = encodeURIComponent("<!-- script-start -->");
|
|
22
22
|
const DOCUMENT_SCRIPT_PLACEHOLDER_END = encodeURIComponent("<!-- script-end -->");
|
|
23
|
+
const DOCUMENT_SCRIPT_ATTRIBUTES_START = encodeURIComponent("<!-- script-scriptpProperties-start -->");
|
|
24
|
+
const DOCUMENT_SCRIPT_ATTRIBUTES_END = encodeURIComponent("<!-- script-scriptpProperties-end -->");
|
|
23
25
|
const DOCUMENT_STYLE_PLACEHOLDER_START = encodeURIComponent("<!-- style-start -->");
|
|
24
26
|
const DOCUMENT_STYLE_PLACEHOLDER_END = encodeURIComponent("<!-- style-end -->");
|
|
25
27
|
const DOCUMENT_COMMENT_PLACEHOLDER_START = encodeURIComponent("<!-- comment-start -->");
|
|
@@ -38,6 +40,8 @@ export {
|
|
|
38
40
|
DOCUMENT_LINKS_PLACEHOLDER,
|
|
39
41
|
DOCUMENT_META_PLACEHOLDER,
|
|
40
42
|
DOCUMENT_SCRIPTS_PLACEHOLDER,
|
|
43
|
+
DOCUMENT_SCRIPT_ATTRIBUTES_END,
|
|
44
|
+
DOCUMENT_SCRIPT_ATTRIBUTES_START,
|
|
41
45
|
DOCUMENT_SCRIPT_PLACEHOLDER_END,
|
|
42
46
|
DOCUMENT_SCRIPT_PLACEHOLDER_START,
|
|
43
47
|
DOCUMENT_SSRDATASCRIPT_PLACEHOLDER,
|
|
@@ -2,10 +2,12 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { serializeJson } from "@modern-js/runtime-utils/node";
|
|
3
3
|
import { Await, useAsyncError } from "@modern-js/runtime-utils/router";
|
|
4
4
|
import { Suspense, useEffect, useMemo, useRef } from "react";
|
|
5
|
-
import {
|
|
5
|
+
import { ROUTER_DATA_JSON_ID } from "../../core/constants";
|
|
6
|
+
import { modernInline, runRouterDataFnStr, runWindowFnStr } from "./constants";
|
|
6
7
|
import { serializeErrors } from "./utils";
|
|
7
8
|
const DeferredDataScripts = (props) => {
|
|
8
9
|
const staticContext = props === null || props === void 0 ? void 0 : props.context;
|
|
10
|
+
const inlineScript = props === null || props === void 0 ? void 0 : props.inlineScript;
|
|
9
11
|
const hydratedRef = useRef(false);
|
|
10
12
|
useEffect(() => {
|
|
11
13
|
hydratedRef.current = true;
|
|
@@ -19,13 +21,11 @@ const DeferredDataScripts = (props) => {
|
|
|
19
21
|
loaderData: staticContext.loaderData,
|
|
20
22
|
errors: serializeErrors(staticContext.errors)
|
|
21
23
|
};
|
|
22
|
-
const initialScript0 =
|
|
23
|
-
const initialScript1 = [
|
|
24
|
-
`_ROUTER_DATA
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
mergeLoaderDataStr
|
|
28
|
-
].join("\n");
|
|
24
|
+
const initialScript0 = inlineScript ? "" : `${serializeJson(_ROUTER_DATA)}`;
|
|
25
|
+
const initialScript1 = inlineScript ? [
|
|
26
|
+
`_ROUTER_DATA = ${serializeJson(_ROUTER_DATA)};`,
|
|
27
|
+
modernInline
|
|
28
|
+
].join("\n") : modernInline;
|
|
29
29
|
const deferredDataScripts = [];
|
|
30
30
|
const initialScripts = Object.entries(activeDeferreds).map(([routeId, deferredData]) => {
|
|
31
31
|
const pendingKeys = new Set(deferredData.pendingKeys);
|
|
@@ -77,10 +77,12 @@ const DeferredDataScripts = (props) => {
|
|
|
77
77
|
});
|
|
78
78
|
return {
|
|
79
79
|
fnName: `mergeLoaderData`,
|
|
80
|
+
fnRun: runWindowFnStr,
|
|
80
81
|
fnArgs: [
|
|
81
82
|
routeId,
|
|
82
83
|
deferredKeyPromiseManifests
|
|
83
|
-
]
|
|
84
|
+
],
|
|
85
|
+
fnScriptSrc: "modern-run-window-fn"
|
|
84
86
|
};
|
|
85
87
|
});
|
|
86
88
|
return [
|
|
@@ -97,8 +99,9 @@ const DeferredDataScripts = (props) => {
|
|
|
97
99
|
children: [
|
|
98
100
|
!hydratedRef.current && /* @__PURE__ */ _jsxs(_Fragment, {
|
|
99
101
|
children: [
|
|
100
|
-
/* @__PURE__ */ _jsx("script", {
|
|
101
|
-
|
|
102
|
+
deferredScripts[0].length !== 0 && /* @__PURE__ */ _jsx("script", {
|
|
103
|
+
type: "application/json",
|
|
104
|
+
id: ROUTER_DATA_JSON_ID,
|
|
102
105
|
nonce: props === null || props === void 0 ? void 0 : props.nonce,
|
|
103
106
|
suppressHydrationWarning: true,
|
|
104
107
|
dangerouslySetInnerHTML: {
|
|
@@ -108,17 +111,21 @@ const DeferredDataScripts = (props) => {
|
|
|
108
111
|
/* @__PURE__ */ _jsx("script", {
|
|
109
112
|
async: true,
|
|
110
113
|
nonce: props === null || props === void 0 ? void 0 : props.nonce,
|
|
114
|
+
"data-script-src": "modern-inline",
|
|
111
115
|
suppressHydrationWarning: true,
|
|
112
116
|
dangerouslySetInnerHTML: {
|
|
113
117
|
__html: deferredScripts[1]
|
|
114
118
|
}
|
|
115
119
|
}),
|
|
116
|
-
deferredScripts[2].map(({ fnName, fnArgs }) => /* @__PURE__ */ _jsx("script", {
|
|
120
|
+
deferredScripts[2].map(({ fnName, fnArgs, fnRun, fnScriptSrc }) => /* @__PURE__ */ _jsx("script", {
|
|
117
121
|
async: true,
|
|
122
|
+
"data-script-src": fnScriptSrc,
|
|
123
|
+
"data-fn-name": fnName,
|
|
124
|
+
"data-fn-args": JSON.stringify(fnArgs),
|
|
118
125
|
nonce: props === null || props === void 0 ? void 0 : props.nonce,
|
|
119
126
|
suppressHydrationWarning: true,
|
|
120
127
|
dangerouslySetInnerHTML: {
|
|
121
|
-
__html:
|
|
128
|
+
__html: fnRun
|
|
122
129
|
}
|
|
123
130
|
}, fnName))
|
|
124
131
|
]
|
|
@@ -139,9 +146,16 @@ const DeferredDataScript = ({ data, routeId, dataKey, nonce }) => {
|
|
|
139
146
|
children: (data2) => /* @__PURE__ */ _jsx("script", {
|
|
140
147
|
async: true,
|
|
141
148
|
nonce,
|
|
149
|
+
"data-fn-name": "r",
|
|
150
|
+
"data-script-src": "modern-run-router-data-fn",
|
|
151
|
+
"data-fn-args": `${JSON.stringify([
|
|
152
|
+
routeId,
|
|
153
|
+
dataKey,
|
|
154
|
+
data2
|
|
155
|
+
])}`,
|
|
142
156
|
suppressHydrationWarning: true,
|
|
143
157
|
dangerouslySetInnerHTML: {
|
|
144
|
-
__html:
|
|
158
|
+
__html: runRouterDataFnStr
|
|
145
159
|
}
|
|
146
160
|
})
|
|
147
161
|
}) : null
|
|
@@ -150,13 +164,21 @@ const DeferredDataScript = ({ data, routeId, dataKey, nonce }) => {
|
|
|
150
164
|
const ErrorDeferredDataScript = ({ routeId, dataKey, nonce }) => {
|
|
151
165
|
const error = useAsyncError();
|
|
152
166
|
return /* @__PURE__ */ _jsx("script", {
|
|
167
|
+
"data-fn-name": "r",
|
|
168
|
+
"data-script-src": "modern-run-router-data-fn",
|
|
169
|
+
"data-fn-args": `${JSON.stringify([
|
|
170
|
+
routeId,
|
|
171
|
+
dataKey,
|
|
172
|
+
void 0,
|
|
173
|
+
{
|
|
174
|
+
message: error.message,
|
|
175
|
+
stack: error.stack
|
|
176
|
+
}
|
|
177
|
+
])}`,
|
|
153
178
|
nonce,
|
|
154
179
|
suppressHydrationWarning: true,
|
|
155
180
|
dangerouslySetInnerHTML: {
|
|
156
|
-
__html:
|
|
157
|
-
message: error.message,
|
|
158
|
-
stack: error.stack
|
|
159
|
-
})});`
|
|
181
|
+
__html: runRouterDataFnStr
|
|
160
182
|
}
|
|
161
183
|
});
|
|
162
184
|
};
|
|
@@ -1,10 +1,19 @@
|
|
|
1
|
+
import { ROUTER_DATA_JSON_ID } from "../../core/constants";
|
|
1
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}}))};`;
|
|
2
3
|
const resolveFnStr = `function r(e,r,o,A){A?_ROUTER_DATA.r[e][r].reject(A):_ROUTER_DATA.r[e][r].resolve(o)};`;
|
|
3
4
|
const preResolvedFnStr = `function p(e,r){return void 0!==r?Promise.reject(new Error(r.message)):Promise.resolve(e)};`;
|
|
4
5
|
const mergeLoaderDataStr = `function mergeLoaderData(e,n){const r=n.reduce((function(e,{key:n,routerDataFnName:r,routerDataFnArgs:a}){const 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
|
+
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")](...JSON.parse(document.currentScript.getAttribute("data-fn-args")))}function runRouterDataFn(){_ROUTER_DATA[document.currentScript.getAttribute("data-fn-name")](...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
|
+
const runRouterDataFnStr = `runRouterDataFn();`;
|
|
9
|
+
const runWindowFnStr = `runWindowFn();`;
|
|
5
10
|
export {
|
|
11
|
+
initRouterDataAttrs,
|
|
6
12
|
mergeLoaderDataStr,
|
|
13
|
+
modernInline,
|
|
7
14
|
preResolvedFnStr,
|
|
8
15
|
resolveFnStr,
|
|
16
|
+
runRouterDataFnStr,
|
|
17
|
+
runWindowFnStr,
|
|
9
18
|
setupFnStr
|
|
10
19
|
};
|
|
@@ -93,13 +93,6 @@ const routerPlugin = (userConfig = {}) => {
|
|
|
93
93
|
};
|
|
94
94
|
return originSubscribe(wrapedListener);
|
|
95
95
|
};
|
|
96
|
-
Object.defineProperty(runtimeContext, "remixRouter", {
|
|
97
|
-
get() {
|
|
98
|
-
return router;
|
|
99
|
-
},
|
|
100
|
-
configurable: true,
|
|
101
|
-
enumerable: true
|
|
102
|
-
});
|
|
103
96
|
return router;
|
|
104
97
|
}, [
|
|
105
98
|
finalRouteConfig,
|
|
@@ -80,8 +80,8 @@ const routerPlugin = (userConfig = {}) => {
|
|
|
80
80
|
throw routerContext.errors[0];
|
|
81
81
|
}
|
|
82
82
|
const router = createStaticRouter(routes, routerContext);
|
|
83
|
-
context.remixRouter = router;
|
|
84
83
|
context.routerContext = routerContext;
|
|
84
|
+
context.remixRouter = router;
|
|
85
85
|
context.routes = routes;
|
|
86
86
|
},
|
|
87
87
|
wrapRoot: (App) => {
|
|
@@ -92,7 +92,7 @@ const routerPlugin = (userConfig = {}) => {
|
|
|
92
92
|
return () => {
|
|
93
93
|
const context = useContext(RuntimeReactContext);
|
|
94
94
|
const { remixRouter, routerContext, ssrContext } = context;
|
|
95
|
-
const { nonce, mode } = ssrContext;
|
|
95
|
+
const { nonce, mode, inlineScript } = ssrContext;
|
|
96
96
|
const routerWrapper = /* @__PURE__ */ _jsxs(_Fragment, {
|
|
97
97
|
children: [
|
|
98
98
|
/* @__PURE__ */ _jsx(StaticRouterProvider, {
|
|
@@ -104,7 +104,8 @@ const routerPlugin = (userConfig = {}) => {
|
|
|
104
104
|
// So we can inject it only when streaming ssr
|
|
105
105
|
/* @__PURE__ */ _jsx(DeferredDataScripts, {
|
|
106
106
|
nonce,
|
|
107
|
-
context: routerContext
|
|
107
|
+
context: routerContext,
|
|
108
|
+
inlineScript
|
|
108
109
|
}),
|
|
109
110
|
mode === "stream" && JSX_SHELL_STREAM_END_MARK
|
|
110
111
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { Store } from '@modern-js-reduck/store';
|
|
3
|
-
import type {
|
|
3
|
+
import type { StaticHandlerContext } from '@modern-js/runtime-utils/remix-router';
|
|
4
4
|
import type { RouteManifest } from '../../router/runtime/types';
|
|
5
5
|
import { createLoaderManager } from '../loader/loaderManager';
|
|
6
6
|
import type { PluginRunner, runtime } from '../plugin';
|
|
@@ -14,10 +14,6 @@ interface BaseRuntimeContext {
|
|
|
14
14
|
store?: Store;
|
|
15
15
|
routeManifest: RouteManifest;
|
|
16
16
|
routerContext?: StaticHandlerContext;
|
|
17
|
-
/**
|
|
18
|
-
* private method
|
|
19
|
-
*/
|
|
20
|
-
remixRouter?: Router;
|
|
21
17
|
/**
|
|
22
18
|
* private
|
|
23
19
|
*/
|
|
@@ -17,3 +17,4 @@ export declare function checkIsNode(): boolean;
|
|
|
17
17
|
export declare function serializeErrors(errors: StaticHandlerContext['errors']): StaticHandlerContext['errors'];
|
|
18
18
|
export declare function getSSRConfigByEntry(entryName: string, ssr?: ServerUserConfig['ssr'], ssrByEntries?: ServerUserConfig['ssrByEntries']): import("@modern-js/app-tools").SSR;
|
|
19
19
|
export declare function getSSRMode(ssrConfig?: SSRConfig): 'string' | 'stream' | false;
|
|
20
|
+
export declare function getSSRInlineScript(ssrConfig?: SSRConfig): boolean;
|
|
@@ -52,6 +52,7 @@ export type SSRServerContext = Pick<BaseSSRServerContext, 'redirection' | 'respo
|
|
|
52
52
|
loaderFailureMode?: 'clientRender' | 'errorBoundary';
|
|
53
53
|
onError?: (e: unknown) => void;
|
|
54
54
|
onTiming?: (name: string, dur: number) => void;
|
|
55
|
+
inlineScript?: boolean;
|
|
55
56
|
};
|
|
56
57
|
interface TSSRBaseContext {
|
|
57
58
|
request: BaseSSRServerContext['request'] & {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export declare function Script(props:
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare function Script(props: DocumentScriptProps): import("react").JSX.Element;
|
|
3
|
+
export interface DocumentScriptProps extends Omit<React.ScriptHTMLAttributes<HTMLScriptElement>, 'content'> {
|
|
4
|
+
content?: () => void;
|
|
5
|
+
}
|
|
@@ -14,6 +14,8 @@ export declare const DOCUMENT_SCRIPTS_PLACEHOLDER: string;
|
|
|
14
14
|
export declare const DOCUMENT_LINKS_PLACEHOLDER: string;
|
|
15
15
|
export declare const DOCUMENT_SCRIPT_PLACEHOLDER_START: string;
|
|
16
16
|
export declare const DOCUMENT_SCRIPT_PLACEHOLDER_END: string;
|
|
17
|
+
export declare const DOCUMENT_SCRIPT_ATTRIBUTES_START: string;
|
|
18
|
+
export declare const DOCUMENT_SCRIPT_ATTRIBUTES_END: string;
|
|
17
19
|
export declare const DOCUMENT_STYLE_PLACEHOLDER_START: string;
|
|
18
20
|
export declare const DOCUMENT_STYLE_PLACEHOLDER_END: string;
|
|
19
21
|
export declare const DOCUMENT_COMMENT_PLACEHOLDER_START: string;
|
|
@@ -6,6 +6,7 @@ import type { StaticHandlerContext } from '@modern-js/runtime-utils/remix-router
|
|
|
6
6
|
*/
|
|
7
7
|
declare const DeferredDataScripts: (props?: {
|
|
8
8
|
nonce?: string;
|
|
9
|
+
inlineScript?: boolean;
|
|
9
10
|
context: StaticHandlerContext;
|
|
10
11
|
}) => import("react").JSX.Element | null;
|
|
11
12
|
export default DeferredDataScripts;
|