@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.
Files changed (35) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cjs/document/cli/index.js +1 -0
  3. package/dist/cjs/router/runtime/plugin.js +6 -0
  4. package/dist/cjs/ssr/serverRender/constants.js +16 -0
  5. package/dist/cjs/ssr/serverRender/renderToStream/index.js +1 -1
  6. package/dist/cjs/ssr/serverRender/renderToString/entry.js +18 -3
  7. package/dist/cjs/ssr/serverRender/renderToString/index.js +4 -1
  8. package/dist/cjs/ssr/serverRender/reporter.js +27 -0
  9. package/dist/esm/document/cli/index.js +1 -0
  10. package/dist/esm/router/runtime/plugin.js +6 -0
  11. package/dist/esm/ssr/serverRender/constants.js +6 -0
  12. package/dist/esm/ssr/serverRender/renderToStream/index.js +1 -1
  13. package/dist/esm/ssr/serverRender/renderToString/entry.js +19 -4
  14. package/dist/esm/ssr/serverRender/renderToString/index.js +4 -1
  15. package/dist/esm/ssr/serverRender/reporter.js +17 -0
  16. package/dist/esm-node/document/cli/index.js +1 -0
  17. package/dist/esm-node/router/runtime/plugin.js +6 -0
  18. package/dist/esm-node/ssr/serverRender/constants.js +6 -0
  19. package/dist/esm-node/ssr/serverRender/renderToStream/index.js +1 -1
  20. package/dist/esm-node/ssr/serverRender/renderToString/entry.js +18 -3
  21. package/dist/esm-node/ssr/serverRender/renderToString/index.js +4 -1
  22. package/dist/esm-node/ssr/serverRender/reporter.js +17 -0
  23. package/dist/types/router/runtime/types.d.ts +4 -0
  24. package/dist/types/ssr/serverRender/constants.d.ts +5 -0
  25. package/dist/types/ssr/serverRender/renderToString/entry.d.ts +3 -0
  26. package/dist/types/ssr/serverRender/reporter.d.ts +8 -0
  27. package/package.json +9 -9
  28. package/dist/cjs/ssr/serverRender/time.js +0 -20
  29. package/dist/cjs/ssr/serverRender/time.worker.js +0 -38
  30. package/dist/esm/ssr/serverRender/time.js +0 -11
  31. package/dist/esm/ssr/serverRender/time.worker.js +0 -29
  32. package/dist/esm-node/ssr/serverRender/time.js +0 -10
  33. package/dist/esm-node/ssr/serverRender/time.worker.js +0 -28
  34. package/dist/types/ssr/serverRender/time.d.ts +0 -1
  35. 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 _time = require("../time");
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 { time } from "../time";
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 { time } from "../time";
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;
@@ -0,0 +1,5 @@
1
+ export declare enum ServerTimingNames {
2
+ SSR_RENDER_TOTAL = "ssr-render-total",
3
+ SSR_PREFETCH = "ssr-prefetch",
4
+ SSR_RENDER_HTML = "ssr-render-html",
5
+ }
@@ -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.28.0",
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.28.0",
177
- "@modern-js/types": "2.28.0",
178
- "@modern-js/utils": "2.28.0"
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.28.0",
200
- "@modern-js/core": "2.28.0",
201
- "@modern-js/server-core": "2.28.0",
202
- "@scripts/jest-config": "2.28.0",
203
- "@scripts/build": "2.28.0"
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,10 +0,0 @@
1
- const getLatency = (hrtime) => {
2
- const [s, ns] = process.hrtime(hrtime);
3
- return s * 1e3 + ns / 1e6;
4
- };
5
- export const time = () => {
6
- const hrtime = process.hrtime();
7
- return () => {
8
- return getLatency(hrtime);
9
- };
10
- };
@@ -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;