@modern-js/runtime 2.28.0 → 2.29.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/CHANGELOG.md +24 -0
- package/dist/cjs/document/cli/index.js +1 -0
- package/dist/cjs/router/runtime/plugin.js +6 -0
- package/dist/cjs/ssr/serverRender/constants.js +16 -0
- package/dist/cjs/ssr/serverRender/renderToStream/index.js +1 -1
- package/dist/cjs/ssr/serverRender/renderToString/entry.js +18 -3
- package/dist/cjs/ssr/serverRender/renderToString/index.js +4 -1
- package/dist/cjs/ssr/serverRender/reporter.js +27 -0
- package/dist/esm/document/cli/index.js +1 -0
- package/dist/esm/router/runtime/plugin.js +6 -0
- package/dist/esm/ssr/serverRender/constants.js +6 -0
- package/dist/esm/ssr/serverRender/renderToStream/index.js +1 -1
- package/dist/esm/ssr/serverRender/renderToString/entry.js +19 -4
- package/dist/esm/ssr/serverRender/renderToString/index.js +4 -1
- package/dist/esm/ssr/serverRender/reporter.js +17 -0
- package/dist/esm-node/document/cli/index.js +1 -0
- package/dist/esm-node/router/runtime/plugin.js +6 -0
- package/dist/esm-node/ssr/serverRender/constants.js +6 -0
- package/dist/esm-node/ssr/serverRender/renderToStream/index.js +1 -1
- package/dist/esm-node/ssr/serverRender/renderToString/entry.js +18 -3
- package/dist/esm-node/ssr/serverRender/renderToString/index.js +4 -1
- package/dist/esm-node/ssr/serverRender/reporter.js +17 -0
- package/dist/types/router/runtime/types.d.ts +4 -0
- package/dist/types/ssr/serverRender/constants.d.ts +5 -0
- package/dist/types/ssr/serverRender/renderToString/entry.d.ts +3 -0
- package/dist/types/ssr/serverRender/reporter.d.ts +8 -0
- package/package.json +9 -9
- package/dist/cjs/ssr/serverRender/time.js +0 -20
- package/dist/cjs/ssr/serverRender/time.worker.js +0 -38
- package/dist/esm/ssr/serverRender/time.js +0 -11
- package/dist/esm/ssr/serverRender/time.worker.js +0 -29
- package/dist/esm-node/ssr/serverRender/time.js +0 -10
- package/dist/esm-node/ssr/serverRender/time.worker.js +0 -28
- package/dist/types/ssr/serverRender/time.d.ts +0 -1
- package/dist/types/ssr/serverRender/time.worker.d.ts +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @modern-js/runtime
|
|
2
2
|
|
|
3
|
+
## 2.29.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- cba7675: feat: add a server reporter that report server cost, logger about error, info etc.
|
|
8
|
+
feat: 添加一个 server 端 reporter,来报告 server 端耗时,报错等
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- 600bb0a: fix: fix remixRouter not existed in conventional routes
|
|
13
|
+
fix: 修复 remixRouter 在约定式路由下不存在问题
|
|
14
|
+
- fd3e71c: fix: if a route dont has component, should be as a no-layout route
|
|
15
|
+
fix: 如果路由对象没有组件属性,应该被看做无布局路由
|
|
16
|
+
- 9a81e31: fix(plugin-runtime): ssr reporter some problems
|
|
17
|
+
fix(plugin-runtime): ssr reporter 小问题
|
|
18
|
+
- Updated dependencies [e6b5355]
|
|
19
|
+
- Updated dependencies [93db783]
|
|
20
|
+
- Updated dependencies [cba7675]
|
|
21
|
+
- Updated dependencies [99052ea]
|
|
22
|
+
- Updated dependencies [1d71d2e]
|
|
23
|
+
- @modern-js/utils@2.29.0
|
|
24
|
+
- @modern-js/types@2.29.0
|
|
25
|
+
- @modern-js/plugin@2.29.0
|
|
26
|
+
|
|
3
27
|
## 2.28.0
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -175,6 +175,7 @@ const documentPlugin = () => ({
|
|
|
175
175
|
);
|
|
176
176
|
const documentHtmlOptions = templateContent ? {
|
|
177
177
|
templateContent,
|
|
178
|
+
// Note: the behavior of inject/modify tags in afterTemplateExecution hook will not take effect
|
|
178
179
|
inject: false
|
|
179
180
|
} : {};
|
|
180
181
|
return {
|
|
@@ -148,6 +148,12 @@ const routerPlugin = ({ serverBase = [], supportHtml5History = true, basename =
|
|
|
148
148
|
},
|
|
149
149
|
pickContext: ({ context, pickedContext }, next) => {
|
|
150
150
|
const { remixRouter } = context;
|
|
151
|
+
if (!remixRouter) {
|
|
152
|
+
return next({
|
|
153
|
+
context,
|
|
154
|
+
pickedContext
|
|
155
|
+
});
|
|
156
|
+
}
|
|
151
157
|
const router = {
|
|
152
158
|
navigate: remixRouter.navigate,
|
|
153
159
|
get location() {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "ServerTimingNames", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return ServerTimingNames;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
var ServerTimingNames;
|
|
12
|
+
(function(ServerTimingNames2) {
|
|
13
|
+
ServerTimingNames2["SSR_RENDER_TOTAL"] = "ssr-render-total";
|
|
14
|
+
ServerTimingNames2["SSR_PREFETCH"] = "ssr-prefetch";
|
|
15
|
+
ServerTimingNames2["SSR_RENDER_HTML"] = "ssr-render-html";
|
|
16
|
+
})(ServerTimingNames || (ServerTimingNames = {}));
|
|
@@ -11,8 +11,8 @@ Object.defineProperty(exports, "render", {
|
|
|
11
11
|
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
|
|
12
12
|
const _react = require("react");
|
|
13
13
|
const _runtimenode = require("@modern-js/utils/runtime-node");
|
|
14
|
+
const _time = require("@modern-js/utils/universal/time");
|
|
14
15
|
const _prerender = require("../../react/prerender");
|
|
15
|
-
const _time = require("../time");
|
|
16
16
|
const _renderToPipe = /* @__PURE__ */ _interop_require_default._(require("./renderToPipe"));
|
|
17
17
|
const render = ({ App, context }) => {
|
|
18
18
|
const { ssrContext } = context;
|
|
@@ -15,17 +15,19 @@ const _react = /* @__PURE__ */ _interop_require_default._(require("react"));
|
|
|
15
15
|
const _server = /* @__PURE__ */ _interop_require_default._(require("react-dom/server"));
|
|
16
16
|
const _runtimenode = require("@modern-js/utils/runtime-node");
|
|
17
17
|
const _reacthelmet = /* @__PURE__ */ _interop_require_default._(require("react-helmet"));
|
|
18
|
+
const _time = require("@modern-js/utils/universal/time");
|
|
18
19
|
const _utils = require("../../../router/runtime/utils");
|
|
19
20
|
const _helmet = /* @__PURE__ */ _interop_require_default._(require("../helmet"));
|
|
20
21
|
const _types = require("../types");
|
|
21
|
-
const _time = require("../time");
|
|
22
22
|
const _prefetch = /* @__PURE__ */ _interop_require_default._(require("../../prefetch"));
|
|
23
23
|
const _utils1 = require("../utils");
|
|
24
|
+
const _reporter = require("../reporter");
|
|
25
|
+
const _constants = require("../constants");
|
|
24
26
|
const _template = require("./template");
|
|
25
27
|
const _reduce = require("./reduce");
|
|
26
28
|
const _loadable = /* @__PURE__ */ _interop_require_wildcard._(require("./loadable"));
|
|
27
29
|
const _styledComponent = /* @__PURE__ */ _interop_require_wildcard._(require("./styledComponent"));
|
|
28
|
-
const buildTemplateData = (context, data, renderLevel) => {
|
|
30
|
+
const buildTemplateData = (context, data, renderLevel, reporter) => {
|
|
29
31
|
const { request, enableUnsafeCtx } = context;
|
|
30
32
|
const unsafeContext = {
|
|
31
33
|
headers: request.headers
|
|
@@ -40,6 +42,9 @@ const buildTemplateData = (context, data, renderLevel) => {
|
|
|
40
42
|
host: request.host,
|
|
41
43
|
url: request.url,
|
|
42
44
|
...enableUnsafeCtx ? unsafeContext : {}
|
|
45
|
+
},
|
|
46
|
+
reporter: {
|
|
47
|
+
sessionId: reporter.sessionId
|
|
43
48
|
}
|
|
44
49
|
},
|
|
45
50
|
renderLevel
|
|
@@ -68,7 +73,7 @@ class Entry {
|
|
|
68
73
|
errors: (0, _utils.serializeErrors)(routerContext.errors)
|
|
69
74
|
} : void 0;
|
|
70
75
|
let html = "";
|
|
71
|
-
const templateData = buildTemplateData(ssrContext, prefetchData, this.result.renderLevel);
|
|
76
|
+
const templateData = buildTemplateData(ssrContext, prefetchData, this.result.renderLevel, this.reporter);
|
|
72
77
|
const SSRData = this.getSSRDataScript(templateData, routerData);
|
|
73
78
|
for (const fragment of this.fragments) {
|
|
74
79
|
if (fragment.isVariable && fragment.content === "SSRDataScript") {
|
|
@@ -89,9 +94,12 @@ class Entry {
|
|
|
89
94
|
const prefetchCost = end();
|
|
90
95
|
this.logger.debug(`App Prefetch cost = %d ms`, prefetchCost);
|
|
91
96
|
this.metrics.emitTimer("app.prefetch.cost", prefetchCost);
|
|
97
|
+
this.reporter.reportTime("app_prefetch_cost", prefetchCost);
|
|
98
|
+
this.severTiming.addServeTiming(_constants.ServerTimingNames.SSR_PREFETCH, prefetchCost);
|
|
92
99
|
} catch (e) {
|
|
93
100
|
this.result.renderLevel = _types.RenderLevel.CLIENT_RENDER;
|
|
94
101
|
this.logger.error("App Prefetch Render", e);
|
|
102
|
+
this.reporter.reportError("App Prefetch Render", e);
|
|
95
103
|
this.metrics.emitCounter("app.prefetch.render.error", 1);
|
|
96
104
|
}
|
|
97
105
|
return prefetchData || {};
|
|
@@ -123,9 +131,12 @@ class Entry {
|
|
|
123
131
|
const cost = end();
|
|
124
132
|
this.logger.debug("App Render To HTML cost = %d ms", cost);
|
|
125
133
|
this.metrics.emitTimer("app.render.html.cost", cost);
|
|
134
|
+
this.reporter.reportTime("app_render_html_cost", cost);
|
|
135
|
+
this.severTiming.addServeTiming(_constants.ServerTimingNames.SSR_RENDER_HTML, cost);
|
|
126
136
|
this.result.renderLevel = _types.RenderLevel.SERVER_RENDER;
|
|
127
137
|
} catch (e) {
|
|
128
138
|
this.logger.error("App Render To HTML", e);
|
|
139
|
+
this.reporter.reportError("App Render To HTML", e);
|
|
129
140
|
this.metrics.emitCounter("app.render.html.error", 1);
|
|
130
141
|
}
|
|
131
142
|
return html;
|
|
@@ -152,6 +163,8 @@ class Entry {
|
|
|
152
163
|
_define_property._(this, "result", void 0);
|
|
153
164
|
_define_property._(this, "metrics", void 0);
|
|
154
165
|
_define_property._(this, "logger", void 0);
|
|
166
|
+
_define_property._(this, "severTiming", void 0);
|
|
167
|
+
_define_property._(this, "reporter", void 0);
|
|
155
168
|
_define_property._(this, "template", void 0);
|
|
156
169
|
_define_property._(this, "App", void 0);
|
|
157
170
|
_define_property._(this, "fragments", void 0);
|
|
@@ -166,6 +179,8 @@ class Entry {
|
|
|
166
179
|
this.host = host;
|
|
167
180
|
this.App = options.App;
|
|
168
181
|
this.pluginConfig = config;
|
|
182
|
+
this.reporter = (0, _reporter.createSSRReporter)(ctx.reporter);
|
|
183
|
+
this.severTiming = ctx.serverTiming;
|
|
169
184
|
this.metrics = ctx.metrics;
|
|
170
185
|
this.logger = ctx.logger;
|
|
171
186
|
this.nonce = nonce;
|
|
@@ -10,8 +10,9 @@ Object.defineProperty(exports, "render", {
|
|
|
10
10
|
});
|
|
11
11
|
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
|
|
12
12
|
const _runtimenode = require("@modern-js/utils/runtime-node");
|
|
13
|
+
const _time = require("@modern-js/utils/universal/time");
|
|
13
14
|
const _prerender = require("../../react/prerender");
|
|
14
|
-
const
|
|
15
|
+
const _constants = require("../constants");
|
|
15
16
|
const _entry = /* @__PURE__ */ _interop_require_default._(require("./entry"));
|
|
16
17
|
const render = ({ App, context, config }) => {
|
|
17
18
|
const ssrContext = context.ssrContext;
|
|
@@ -27,6 +28,8 @@ const render = ({ App, context, config }) => {
|
|
|
27
28
|
const cost = end();
|
|
28
29
|
entry.logger.info("App Render Total cost = %d ms", cost);
|
|
29
30
|
entry.metrics.emitTimer("app.render.cost", cost);
|
|
31
|
+
entry.reporter.reportTime("app_render_cost", cost);
|
|
32
|
+
entry.severTiming.addServeTiming(_constants.ServerTimingNames.SSR_RENDER_TOTAL, cost);
|
|
30
33
|
const cacheConfig = _prerender.PreRender.config();
|
|
31
34
|
if (cacheConfig) {
|
|
32
35
|
context.ssrContext.cacheConfig = cacheConfig;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "createSSRReporter", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return createSSRReporter;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
function createSSRReporter(reporter) {
|
|
12
|
+
const _reporter = {
|
|
13
|
+
get sessionId() {
|
|
14
|
+
return reporter.sessionId;
|
|
15
|
+
},
|
|
16
|
+
get userId() {
|
|
17
|
+
return reporter.userId;
|
|
18
|
+
},
|
|
19
|
+
reportError(content, e) {
|
|
20
|
+
reporter.reportError(`SSR Error - ${content}`, e);
|
|
21
|
+
},
|
|
22
|
+
reportTime(name, cost) {
|
|
23
|
+
reporter.reportTiming(`ssr_${name}`, cost);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
return _reporter;
|
|
27
|
+
}
|
|
@@ -219,6 +219,7 @@ export var documentPlugin = function() {
|
|
|
219
219
|
);
|
|
220
220
|
var documentHtmlOptions = templateContent ? {
|
|
221
221
|
templateContent: templateContent,
|
|
222
|
+
// Note: the behavior of inject/modify tags in afterTemplateExecution hook will not take effect
|
|
222
223
|
inject: false
|
|
223
224
|
} : {};
|
|
224
225
|
return _object_spread({}, options, documentHtmlOptions);
|
|
@@ -133,6 +133,12 @@ export var routerPlugin = function(param) {
|
|
|
133
133
|
pickContext: function(param2, next) {
|
|
134
134
|
var context = param2.context, pickedContext = param2.pickedContext;
|
|
135
135
|
var remixRouter = context.remixRouter;
|
|
136
|
+
if (!remixRouter) {
|
|
137
|
+
return next({
|
|
138
|
+
context: context,
|
|
139
|
+
pickedContext: pickedContext
|
|
140
|
+
});
|
|
141
|
+
}
|
|
136
142
|
var router = {
|
|
137
143
|
navigate: remixRouter.navigate,
|
|
138
144
|
get location() {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export var ServerTimingNames;
|
|
2
|
+
(function(ServerTimingNames2) {
|
|
3
|
+
ServerTimingNames2["SSR_RENDER_TOTAL"] = "ssr-render-total";
|
|
4
|
+
ServerTimingNames2["SSR_PREFETCH"] = "ssr-prefetch";
|
|
5
|
+
ServerTimingNames2["SSR_RENDER_HTML"] = "ssr-render-html";
|
|
6
|
+
})(ServerTimingNames || (ServerTimingNames = {}));
|
|
@@ -2,8 +2,8 @@ import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
|
|
|
2
2
|
import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
|
|
3
3
|
import { createElement } from "react";
|
|
4
4
|
import { run } from "@modern-js/utils/runtime-node";
|
|
5
|
+
import { time } from "@modern-js/utils/universal/time";
|
|
5
6
|
import { PreRender } from "../../react/prerender";
|
|
6
|
-
import { time } from "../time";
|
|
7
7
|
import renderToPipe from "./renderToPipe";
|
|
8
8
|
export var render = function(param) {
|
|
9
9
|
var App = param.App, context = param.context;
|
|
@@ -8,17 +8,19 @@ import React from "react";
|
|
|
8
8
|
import ReactDomServer from "react-dom/server";
|
|
9
9
|
import { serializeJson } from "@modern-js/utils/runtime-node";
|
|
10
10
|
import ReactHelmet from "react-helmet";
|
|
11
|
+
import { time } from "@modern-js/utils/universal/time";
|
|
11
12
|
import { serializeErrors } from "../../../router/runtime/utils";
|
|
12
13
|
import helmetReplace from "../helmet";
|
|
13
14
|
import { RenderLevel } from "../types";
|
|
14
|
-
import { time } from "../time";
|
|
15
15
|
import prefetch from "../../prefetch";
|
|
16
16
|
import { ROUTER_DATA_JSON_ID, SSR_DATA_JSON_ID, attributesToString } from "../utils";
|
|
17
|
+
import { createSSRReporter } from "../reporter";
|
|
18
|
+
import { ServerTimingNames } from "../constants";
|
|
17
19
|
import { toFragments } from "./template";
|
|
18
20
|
import { reduce } from "./reduce";
|
|
19
21
|
import * as loadableRenderer from "./loadable";
|
|
20
22
|
import * as styledComponentRenderer from "./styledComponent";
|
|
21
|
-
var buildTemplateData = function(context, data, renderLevel) {
|
|
23
|
+
var buildTemplateData = function(context, data, renderLevel, reporter) {
|
|
22
24
|
var request = context.request, enableUnsafeCtx = context.enableUnsafeCtx;
|
|
23
25
|
var unsafeContext = {
|
|
24
26
|
headers: request.headers
|
|
@@ -32,7 +34,10 @@ var buildTemplateData = function(context, data, renderLevel) {
|
|
|
32
34
|
pathname: request.pathname,
|
|
33
35
|
host: request.host,
|
|
34
36
|
url: request.url
|
|
35
|
-
}, enableUnsafeCtx ? unsafeContext : {})
|
|
37
|
+
}, enableUnsafeCtx ? unsafeContext : {}),
|
|
38
|
+
reporter: {
|
|
39
|
+
sessionId: reporter.sessionId
|
|
40
|
+
}
|
|
36
41
|
},
|
|
37
42
|
renderLevel: renderLevel
|
|
38
43
|
};
|
|
@@ -45,6 +50,8 @@ var Entry = /* @__PURE__ */ function() {
|
|
|
45
50
|
_define_property(this, "result", void 0);
|
|
46
51
|
_define_property(this, "metrics", void 0);
|
|
47
52
|
_define_property(this, "logger", void 0);
|
|
53
|
+
_define_property(this, "severTiming", void 0);
|
|
54
|
+
_define_property(this, "reporter", void 0);
|
|
48
55
|
_define_property(this, "template", void 0);
|
|
49
56
|
_define_property(this, "App", void 0);
|
|
50
57
|
_define_property(this, "fragments", void 0);
|
|
@@ -59,6 +66,8 @@ var Entry = /* @__PURE__ */ function() {
|
|
|
59
66
|
this.host = host;
|
|
60
67
|
this.App = options.App;
|
|
61
68
|
this.pluginConfig = config;
|
|
69
|
+
this.reporter = createSSRReporter(ctx.reporter);
|
|
70
|
+
this.severTiming = ctx.serverTiming;
|
|
62
71
|
this.metrics = ctx.metrics;
|
|
63
72
|
this.logger = ctx.logger;
|
|
64
73
|
this.nonce = nonce;
|
|
@@ -115,7 +124,7 @@ var Entry = /* @__PURE__ */ function() {
|
|
|
115
124
|
errors: serializeErrors(routerContext.errors)
|
|
116
125
|
} : void 0;
|
|
117
126
|
html = "";
|
|
118
|
-
templateData = buildTemplateData(ssrContext, prefetchData, _this.result.renderLevel);
|
|
127
|
+
templateData = buildTemplateData(ssrContext, prefetchData, _this.result.renderLevel, _this.reporter);
|
|
119
128
|
SSRData = _this.getSSRDataScript(templateData, routerData);
|
|
120
129
|
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
121
130
|
try {
|
|
@@ -179,6 +188,8 @@ var Entry = /* @__PURE__ */ function() {
|
|
|
179
188
|
prefetchCost = end();
|
|
180
189
|
_this.logger.debug("App Prefetch cost = %d ms", prefetchCost);
|
|
181
190
|
_this.metrics.emitTimer("app.prefetch.cost", prefetchCost);
|
|
191
|
+
_this.reporter.reportTime("app_prefetch_cost", prefetchCost);
|
|
192
|
+
_this.severTiming.addServeTiming(ServerTimingNames.SSR_PREFETCH, prefetchCost);
|
|
182
193
|
return [
|
|
183
194
|
3,
|
|
184
195
|
4
|
|
@@ -187,6 +198,7 @@ var Entry = /* @__PURE__ */ function() {
|
|
|
187
198
|
e = _state.sent();
|
|
188
199
|
_this.result.renderLevel = RenderLevel.CLIENT_RENDER;
|
|
189
200
|
_this.logger.error("App Prefetch Render", e);
|
|
201
|
+
_this.reporter.reportError("App Prefetch Render", e);
|
|
190
202
|
_this.metrics.emitCounter("app.prefetch.render.error", 1);
|
|
191
203
|
return [
|
|
192
204
|
3,
|
|
@@ -233,9 +245,12 @@ var Entry = /* @__PURE__ */ function() {
|
|
|
233
245
|
var cost = end();
|
|
234
246
|
this.logger.debug("App Render To HTML cost = %d ms", cost);
|
|
235
247
|
this.metrics.emitTimer("app.render.html.cost", cost);
|
|
248
|
+
this.reporter.reportTime("app_render_html_cost", cost);
|
|
249
|
+
this.severTiming.addServeTiming(ServerTimingNames.SSR_RENDER_HTML, cost);
|
|
236
250
|
this.result.renderLevel = RenderLevel.SERVER_RENDER;
|
|
237
251
|
} catch (e) {
|
|
238
252
|
this.logger.error("App Render To HTML", e);
|
|
253
|
+
this.reporter.reportError("App Render To HTML", e);
|
|
239
254
|
this.metrics.emitCounter("app.render.html.error", 1);
|
|
240
255
|
}
|
|
241
256
|
return html;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
|
|
2
2
|
import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
|
|
3
3
|
import { run } from "@modern-js/utils/runtime-node";
|
|
4
|
+
import { time } from "@modern-js/utils/universal/time";
|
|
4
5
|
import { PreRender } from "../../react/prerender";
|
|
5
|
-
import {
|
|
6
|
+
import { ServerTimingNames } from "../constants";
|
|
6
7
|
import SSREntry from "./entry";
|
|
7
8
|
export var render = function(param) {
|
|
8
9
|
var App = param.App, context = param.context, config = param.config;
|
|
@@ -28,6 +29,8 @@ export var render = function(param) {
|
|
|
28
29
|
cost = end();
|
|
29
30
|
entry.logger.info("App Render Total cost = %d ms", cost);
|
|
30
31
|
entry.metrics.emitTimer("app.render.cost", cost);
|
|
32
|
+
entry.reporter.reportTime("app_render_cost", cost);
|
|
33
|
+
entry.severTiming.addServeTiming(ServerTimingNames.SSR_RENDER_TOTAL, cost);
|
|
31
34
|
cacheConfig = PreRender.config();
|
|
32
35
|
if (cacheConfig) {
|
|
33
36
|
context.ssrContext.cacheConfig = cacheConfig;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function createSSRReporter(reporter) {
|
|
2
|
+
var _reporter = {
|
|
3
|
+
get sessionId() {
|
|
4
|
+
return reporter.sessionId;
|
|
5
|
+
},
|
|
6
|
+
get userId() {
|
|
7
|
+
return reporter.userId;
|
|
8
|
+
},
|
|
9
|
+
reportError: function reportError(content, e) {
|
|
10
|
+
reporter.reportError("SSR Error - ".concat(content), e);
|
|
11
|
+
},
|
|
12
|
+
reportTime: function reportTime(name, cost) {
|
|
13
|
+
reporter.reportTiming("ssr_".concat(name), cost);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
return _reporter;
|
|
17
|
+
}
|
|
@@ -152,6 +152,7 @@ export const documentPlugin = () => ({
|
|
|
152
152
|
);
|
|
153
153
|
const documentHtmlOptions = templateContent ? {
|
|
154
154
|
templateContent,
|
|
155
|
+
// Note: the behavior of inject/modify tags in afterTemplateExecution hook will not take effect
|
|
155
156
|
inject: false
|
|
156
157
|
} : {};
|
|
157
158
|
return {
|
|
@@ -121,6 +121,12 @@ export const routerPlugin = ({ serverBase = [], supportHtml5History = true, base
|
|
|
121
121
|
},
|
|
122
122
|
pickContext: ({ context, pickedContext }, next) => {
|
|
123
123
|
const { remixRouter } = context;
|
|
124
|
+
if (!remixRouter) {
|
|
125
|
+
return next({
|
|
126
|
+
context,
|
|
127
|
+
pickedContext
|
|
128
|
+
});
|
|
129
|
+
}
|
|
124
130
|
const router = {
|
|
125
131
|
navigate: remixRouter.navigate,
|
|
126
132
|
get location() {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export var ServerTimingNames;
|
|
2
|
+
(function(ServerTimingNames2) {
|
|
3
|
+
ServerTimingNames2["SSR_RENDER_TOTAL"] = "ssr-render-total";
|
|
4
|
+
ServerTimingNames2["SSR_PREFETCH"] = "ssr-prefetch";
|
|
5
|
+
ServerTimingNames2["SSR_RENDER_HTML"] = "ssr-render-html";
|
|
6
|
+
})(ServerTimingNames || (ServerTimingNames = {}));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createElement } from "react";
|
|
2
2
|
import { run } from "@modern-js/utils/runtime-node";
|
|
3
|
+
import { time } from "@modern-js/utils/universal/time";
|
|
3
4
|
import { PreRender } from "../../react/prerender";
|
|
4
|
-
import { time } from "../time";
|
|
5
5
|
import renderToPipe from "./renderToPipe";
|
|
6
6
|
export const render = ({ App, context }) => {
|
|
7
7
|
const { ssrContext } = context;
|
|
@@ -3,17 +3,19 @@ import React from "react";
|
|
|
3
3
|
import ReactDomServer from "react-dom/server";
|
|
4
4
|
import { serializeJson } from "@modern-js/utils/runtime-node";
|
|
5
5
|
import ReactHelmet from "react-helmet";
|
|
6
|
+
import { time } from "@modern-js/utils/universal/time";
|
|
6
7
|
import { serializeErrors } from "../../../router/runtime/utils";
|
|
7
8
|
import helmetReplace from "../helmet";
|
|
8
9
|
import { RenderLevel } from "../types";
|
|
9
|
-
import { time } from "../time";
|
|
10
10
|
import prefetch from "../../prefetch";
|
|
11
11
|
import { ROUTER_DATA_JSON_ID, SSR_DATA_JSON_ID, attributesToString } from "../utils";
|
|
12
|
+
import { createSSRReporter } from "../reporter";
|
|
13
|
+
import { ServerTimingNames } from "../constants";
|
|
12
14
|
import { toFragments } from "./template";
|
|
13
15
|
import { reduce } from "./reduce";
|
|
14
16
|
import * as loadableRenderer from "./loadable";
|
|
15
17
|
import * as styledComponentRenderer from "./styledComponent";
|
|
16
|
-
const buildTemplateData = (context, data, renderLevel) => {
|
|
18
|
+
const buildTemplateData = (context, data, renderLevel, reporter) => {
|
|
17
19
|
const { request, enableUnsafeCtx } = context;
|
|
18
20
|
const unsafeContext = {
|
|
19
21
|
headers: request.headers
|
|
@@ -28,6 +30,9 @@ const buildTemplateData = (context, data, renderLevel) => {
|
|
|
28
30
|
host: request.host,
|
|
29
31
|
url: request.url,
|
|
30
32
|
...enableUnsafeCtx ? unsafeContext : {}
|
|
33
|
+
},
|
|
34
|
+
reporter: {
|
|
35
|
+
sessionId: reporter.sessionId
|
|
31
36
|
}
|
|
32
37
|
},
|
|
33
38
|
renderLevel
|
|
@@ -56,7 +61,7 @@ class Entry {
|
|
|
56
61
|
errors: serializeErrors(routerContext.errors)
|
|
57
62
|
} : void 0;
|
|
58
63
|
let html = "";
|
|
59
|
-
const templateData = buildTemplateData(ssrContext, prefetchData, this.result.renderLevel);
|
|
64
|
+
const templateData = buildTemplateData(ssrContext, prefetchData, this.result.renderLevel, this.reporter);
|
|
60
65
|
const SSRData = this.getSSRDataScript(templateData, routerData);
|
|
61
66
|
for (const fragment of this.fragments) {
|
|
62
67
|
if (fragment.isVariable && fragment.content === "SSRDataScript") {
|
|
@@ -77,9 +82,12 @@ class Entry {
|
|
|
77
82
|
const prefetchCost = end();
|
|
78
83
|
this.logger.debug(`App Prefetch cost = %d ms`, prefetchCost);
|
|
79
84
|
this.metrics.emitTimer("app.prefetch.cost", prefetchCost);
|
|
85
|
+
this.reporter.reportTime("app_prefetch_cost", prefetchCost);
|
|
86
|
+
this.severTiming.addServeTiming(ServerTimingNames.SSR_PREFETCH, prefetchCost);
|
|
80
87
|
} catch (e) {
|
|
81
88
|
this.result.renderLevel = RenderLevel.CLIENT_RENDER;
|
|
82
89
|
this.logger.error("App Prefetch Render", e);
|
|
90
|
+
this.reporter.reportError("App Prefetch Render", e);
|
|
83
91
|
this.metrics.emitCounter("app.prefetch.render.error", 1);
|
|
84
92
|
}
|
|
85
93
|
return prefetchData || {};
|
|
@@ -111,9 +119,12 @@ class Entry {
|
|
|
111
119
|
const cost = end();
|
|
112
120
|
this.logger.debug("App Render To HTML cost = %d ms", cost);
|
|
113
121
|
this.metrics.emitTimer("app.render.html.cost", cost);
|
|
122
|
+
this.reporter.reportTime("app_render_html_cost", cost);
|
|
123
|
+
this.severTiming.addServeTiming(ServerTimingNames.SSR_RENDER_HTML, cost);
|
|
114
124
|
this.result.renderLevel = RenderLevel.SERVER_RENDER;
|
|
115
125
|
} catch (e) {
|
|
116
126
|
this.logger.error("App Render To HTML", e);
|
|
127
|
+
this.reporter.reportError("App Render To HTML", e);
|
|
117
128
|
this.metrics.emitCounter("app.render.html.error", 1);
|
|
118
129
|
}
|
|
119
130
|
return html;
|
|
@@ -140,6 +151,8 @@ class Entry {
|
|
|
140
151
|
_define_property(this, "result", void 0);
|
|
141
152
|
_define_property(this, "metrics", void 0);
|
|
142
153
|
_define_property(this, "logger", void 0);
|
|
154
|
+
_define_property(this, "severTiming", void 0);
|
|
155
|
+
_define_property(this, "reporter", void 0);
|
|
143
156
|
_define_property(this, "template", void 0);
|
|
144
157
|
_define_property(this, "App", void 0);
|
|
145
158
|
_define_property(this, "fragments", void 0);
|
|
@@ -154,6 +167,8 @@ class Entry {
|
|
|
154
167
|
this.host = host;
|
|
155
168
|
this.App = options.App;
|
|
156
169
|
this.pluginConfig = config;
|
|
170
|
+
this.reporter = createSSRReporter(ctx.reporter);
|
|
171
|
+
this.severTiming = ctx.serverTiming;
|
|
157
172
|
this.metrics = ctx.metrics;
|
|
158
173
|
this.logger = ctx.logger;
|
|
159
174
|
this.nonce = nonce;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { run } from "@modern-js/utils/runtime-node";
|
|
2
|
+
import { time } from "@modern-js/utils/universal/time";
|
|
2
3
|
import { PreRender } from "../../react/prerender";
|
|
3
|
-
import {
|
|
4
|
+
import { ServerTimingNames } from "../constants";
|
|
4
5
|
import SSREntry from "./entry";
|
|
5
6
|
export const render = ({ App, context, config }) => {
|
|
6
7
|
const ssrContext = context.ssrContext;
|
|
@@ -16,6 +17,8 @@ export const render = ({ App, context, config }) => {
|
|
|
16
17
|
const cost = end();
|
|
17
18
|
entry.logger.info("App Render Total cost = %d ms", cost);
|
|
18
19
|
entry.metrics.emitTimer("app.render.cost", cost);
|
|
20
|
+
entry.reporter.reportTime("app_render_cost", cost);
|
|
21
|
+
entry.severTiming.addServeTiming(ServerTimingNames.SSR_RENDER_TOTAL, cost);
|
|
19
22
|
const cacheConfig = PreRender.config();
|
|
20
23
|
if (cacheConfig) {
|
|
21
24
|
context.ssrContext.cacheConfig = cacheConfig;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function createSSRReporter(reporter) {
|
|
2
|
+
const _reporter = {
|
|
3
|
+
get sessionId() {
|
|
4
|
+
return reporter.sessionId;
|
|
5
|
+
},
|
|
6
|
+
get userId() {
|
|
7
|
+
return reporter.userId;
|
|
8
|
+
},
|
|
9
|
+
reportError(content, e) {
|
|
10
|
+
reporter.reportError(`SSR Error - ${content}`, e);
|
|
11
|
+
},
|
|
12
|
+
reportTime(name, cost) {
|
|
13
|
+
reporter.reportTiming(`ssr_${name}`, cost);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
return _reporter;
|
|
17
|
+
}
|
|
@@ -30,6 +30,10 @@ export type RouterConfig = {
|
|
|
30
30
|
globalApp?: React.ComponentType<any>;
|
|
31
31
|
routes: (NestedRoute | PageRoute)[];
|
|
32
32
|
};
|
|
33
|
+
/**
|
|
34
|
+
* You should not use it
|
|
35
|
+
*/
|
|
36
|
+
oldVersion?: boolean;
|
|
33
37
|
serverBase?: string[];
|
|
34
38
|
supportHtml5History?: boolean;
|
|
35
39
|
basename?: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RuntimeContext, ModernSSRReactComponent, SSRPluginConfig } from '../types';
|
|
2
|
+
import { SSRReporter } from '../reporter';
|
|
2
3
|
import { SSRServerContext, RenderResult } from './type';
|
|
3
4
|
type EntryOptions = {
|
|
4
5
|
ctx: SSRServerContext;
|
|
@@ -10,6 +11,8 @@ export default class Entry {
|
|
|
10
11
|
result: RenderResult;
|
|
11
12
|
metrics: SSRServerContext['metrics'];
|
|
12
13
|
logger: SSRServerContext['logger'];
|
|
14
|
+
severTiming: SSRServerContext['serverTiming'];
|
|
15
|
+
reporter: SSRReporter;
|
|
13
16
|
private readonly template;
|
|
14
17
|
private readonly App;
|
|
15
18
|
private readonly fragments;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SSRServerContext } from './types';
|
|
2
|
+
export type SSRReporter = ReturnType<typeof createSSRReporter>;
|
|
3
|
+
export declare function createSSRReporter(reporter: SSRServerContext['reporter']): {
|
|
4
|
+
readonly sessionId: string | undefined;
|
|
5
|
+
readonly userId: string | undefined;
|
|
6
|
+
reportError(content: string, e: Error): void;
|
|
7
|
+
reportTime(name: string, cost: number): void;
|
|
8
|
+
};
|
package/package.json
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"modern",
|
|
16
16
|
"modern.js"
|
|
17
17
|
],
|
|
18
|
-
"version": "2.
|
|
18
|
+
"version": "2.29.0",
|
|
19
19
|
"engines": {
|
|
20
20
|
"node": ">=14.17.6"
|
|
21
21
|
},
|
|
@@ -173,9 +173,9 @@
|
|
|
173
173
|
"redux-logger": "^3.0.6",
|
|
174
174
|
"styled-components": "^5.3.1",
|
|
175
175
|
"@swc/helpers": "0.5.1",
|
|
176
|
-
"@modern-js/plugin": "2.
|
|
177
|
-
"@modern-js/types": "2.
|
|
178
|
-
"@modern-js/utils": "2.
|
|
176
|
+
"@modern-js/plugin": "2.29.0",
|
|
177
|
+
"@modern-js/types": "2.29.0",
|
|
178
|
+
"@modern-js/utils": "2.29.0"
|
|
179
179
|
},
|
|
180
180
|
"peerDependencies": {
|
|
181
181
|
"react": ">=17",
|
|
@@ -196,11 +196,11 @@
|
|
|
196
196
|
"ts-jest": "^29.1.0",
|
|
197
197
|
"typescript": "^5",
|
|
198
198
|
"webpack": "^5.88.1",
|
|
199
|
-
"@modern-js/app-tools": "2.
|
|
200
|
-
"@modern-js/core": "2.
|
|
201
|
-
"@modern-js/server-core": "2.
|
|
202
|
-
"@scripts/
|
|
203
|
-
"@scripts/
|
|
199
|
+
"@modern-js/app-tools": "2.29.0",
|
|
200
|
+
"@modern-js/core": "2.29.0",
|
|
201
|
+
"@modern-js/server-core": "2.29.0",
|
|
202
|
+
"@scripts/build": "2.29.0",
|
|
203
|
+
"@scripts/jest-config": "2.29.0"
|
|
204
204
|
},
|
|
205
205
|
"sideEffects": false,
|
|
206
206
|
"publishConfig": {
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
Object.defineProperty(exports, "time", {
|
|
6
|
-
enumerable: true,
|
|
7
|
-
get: function() {
|
|
8
|
-
return time;
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
const getLatency = (hrtime) => {
|
|
12
|
-
const [s, ns] = process.hrtime(hrtime);
|
|
13
|
-
return s * 1e3 + ns / 1e6;
|
|
14
|
-
};
|
|
15
|
-
const time = () => {
|
|
16
|
-
const hrtime = process.hrtime();
|
|
17
|
-
return () => {
|
|
18
|
-
return getLatency(hrtime);
|
|
19
|
-
};
|
|
20
|
-
};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
Object.defineProperty(exports, "time", {
|
|
6
|
-
enumerable: true,
|
|
7
|
-
get: function() {
|
|
8
|
-
return time;
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
function processHrtime(previousTimestamp) {
|
|
12
|
-
const now = (/* @__PURE__ */ new Date()).getTime();
|
|
13
|
-
const clocktime = now * 1e-3;
|
|
14
|
-
let seconds = Math.floor(clocktime);
|
|
15
|
-
let nanoseconds = Math.floor(clocktime % 1 * 1e9);
|
|
16
|
-
if (previousTimestamp) {
|
|
17
|
-
seconds -= previousTimestamp[0];
|
|
18
|
-
nanoseconds -= previousTimestamp[1];
|
|
19
|
-
if (nanoseconds < 0) {
|
|
20
|
-
seconds--;
|
|
21
|
-
nanoseconds += 1e9;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return [
|
|
25
|
-
seconds,
|
|
26
|
-
nanoseconds
|
|
27
|
-
];
|
|
28
|
-
}
|
|
29
|
-
const getLatency = (hrtime) => {
|
|
30
|
-
const [s, ns] = processHrtime(hrtime);
|
|
31
|
-
return s * 1e3 + ns / 1e6;
|
|
32
|
-
};
|
|
33
|
-
const time = () => {
|
|
34
|
-
const hrtime = processHrtime();
|
|
35
|
-
return () => {
|
|
36
|
-
return getLatency(hrtime);
|
|
37
|
-
};
|
|
38
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
|
|
2
|
-
var getLatency = function(hrtime) {
|
|
3
|
-
var _process_hrtime = _sliced_to_array(process.hrtime(hrtime), 2), s = _process_hrtime[0], ns = _process_hrtime[1];
|
|
4
|
-
return s * 1e3 + ns / 1e6;
|
|
5
|
-
};
|
|
6
|
-
export var time = function() {
|
|
7
|
-
var hrtime = process.hrtime();
|
|
8
|
-
return function() {
|
|
9
|
-
return getLatency(hrtime);
|
|
10
|
-
};
|
|
11
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
|
|
2
|
-
function processHrtime(previousTimestamp) {
|
|
3
|
-
var now = (/* @__PURE__ */ new Date()).getTime();
|
|
4
|
-
var clocktime = now * 1e-3;
|
|
5
|
-
var seconds = Math.floor(clocktime);
|
|
6
|
-
var nanoseconds = Math.floor(clocktime % 1 * 1e9);
|
|
7
|
-
if (previousTimestamp) {
|
|
8
|
-
seconds -= previousTimestamp[0];
|
|
9
|
-
nanoseconds -= previousTimestamp[1];
|
|
10
|
-
if (nanoseconds < 0) {
|
|
11
|
-
seconds--;
|
|
12
|
-
nanoseconds += 1e9;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
return [
|
|
16
|
-
seconds,
|
|
17
|
-
nanoseconds
|
|
18
|
-
];
|
|
19
|
-
}
|
|
20
|
-
var getLatency = function(hrtime) {
|
|
21
|
-
var _processHrtime = _sliced_to_array(processHrtime(hrtime), 2), s = _processHrtime[0], ns = _processHrtime[1];
|
|
22
|
-
return s * 1e3 + ns / 1e6;
|
|
23
|
-
};
|
|
24
|
-
export var time = function() {
|
|
25
|
-
var hrtime = processHrtime();
|
|
26
|
-
return function() {
|
|
27
|
-
return getLatency(hrtime);
|
|
28
|
-
};
|
|
29
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
function processHrtime(previousTimestamp) {
|
|
2
|
-
const now = (/* @__PURE__ */ new Date()).getTime();
|
|
3
|
-
const clocktime = now * 1e-3;
|
|
4
|
-
let seconds = Math.floor(clocktime);
|
|
5
|
-
let nanoseconds = Math.floor(clocktime % 1 * 1e9);
|
|
6
|
-
if (previousTimestamp) {
|
|
7
|
-
seconds -= previousTimestamp[0];
|
|
8
|
-
nanoseconds -= previousTimestamp[1];
|
|
9
|
-
if (nanoseconds < 0) {
|
|
10
|
-
seconds--;
|
|
11
|
-
nanoseconds += 1e9;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
return [
|
|
15
|
-
seconds,
|
|
16
|
-
nanoseconds
|
|
17
|
-
];
|
|
18
|
-
}
|
|
19
|
-
const getLatency = (hrtime) => {
|
|
20
|
-
const [s, ns] = processHrtime(hrtime);
|
|
21
|
-
return s * 1e3 + ns / 1e6;
|
|
22
|
-
};
|
|
23
|
-
export const time = () => {
|
|
24
|
-
const hrtime = processHrtime();
|
|
25
|
-
return () => {
|
|
26
|
-
return getLatency(hrtime);
|
|
27
|
-
};
|
|
28
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const time: () => () => number;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const time: () => () => number;
|