@modern-js/runtime 2.28.0 → 2.30.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 +47 -0
- package/dist/cjs/document/cli/index.js +1 -0
- package/dist/cjs/document/constants.js +0 -5
- package/dist/cjs/router/runtime/plugin.js +6 -0
- package/dist/cjs/ssr/cli/index.js +19 -13
- 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 +13 -13
- package/dist/cjs/ssr/serverRender/renderToString/index.js +3 -3
- package/dist/cjs/ssr/serverRender/tracker.js +86 -0
- package/dist/esm/document/cli/index.js +1 -0
- package/dist/esm/document/constants.js +1 -2
- package/dist/esm/router/runtime/plugin.js +6 -0
- package/dist/esm/ssr/cli/index.js +19 -13
- 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 +14 -14
- package/dist/esm/ssr/serverRender/renderToString/index.js +3 -3
- package/dist/esm/ssr/serverRender/tracker.js +61 -0
- package/dist/esm-node/document/cli/index.js +1 -0
- package/dist/esm-node/document/constants.js +0 -2
- package/dist/esm-node/router/runtime/plugin.js +6 -0
- package/dist/esm-node/ssr/cli/index.js +19 -13
- 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 +13 -13
- package/dist/esm-node/ssr/serverRender/renderToString/index.js +3 -3
- package/dist/esm-node/ssr/serverRender/tracker.js +64 -0
- package/dist/types/document/constants.d.ts +0 -1
- package/dist/types/router/runtime/types.d.ts +4 -0
- package/dist/types/ssr/index.node.d.ts +1 -1
- package/dist/types/ssr/serverRender/constants.d.ts +5 -0
- package/dist/types/ssr/serverRender/renderToString/entry.d.ts +2 -1
- package/dist/types/ssr/serverRender/tracker.d.ts +21 -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,52 @@
|
|
|
1
1
|
# @modern-js/runtime
|
|
2
2
|
|
|
3
|
+
## 2.30.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 855a61e: feat(plugin-runtime): add ssr tracker
|
|
8
|
+
feat(plugin-runtime): 新增 ssr tracker
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- a8a4fd3: fix: ssr plugin use wrong config params
|
|
13
|
+
fix: ssr 插件使用了错误的 config 参数
|
|
14
|
+
- 276ace3: chore: remove noscript tag in html template
|
|
15
|
+
chore: 移除 HTML 模板中的 noscript 标签
|
|
16
|
+
- c731bf3: fix(plugin-runtime): the output maybe undefined;
|
|
17
|
+
fix(plugin-runtime): output 可能是个 undefined
|
|
18
|
+
- 8219d55: fix(plugin-runtime): ssg need use String SSR, so we should inject loadable-component babel plugin when enable ssg
|
|
19
|
+
fix(plugin-runtime): ssg 需要使用 String SSR, 我们需要在开启 SSG 得时候注入 loadbale-compnent babel 插件
|
|
20
|
+
- Updated dependencies [a5ee81a]
|
|
21
|
+
- Updated dependencies [b6ab299]
|
|
22
|
+
- @modern-js/types@2.30.0
|
|
23
|
+
- @modern-js/utils@2.30.0
|
|
24
|
+
- @modern-js/plugin@2.30.0
|
|
25
|
+
|
|
26
|
+
## 2.29.0
|
|
27
|
+
|
|
28
|
+
### Minor Changes
|
|
29
|
+
|
|
30
|
+
- cba7675: feat: add a server reporter that report server cost, logger about error, info etc.
|
|
31
|
+
feat: 添加一个 server 端 reporter,来报告 server 端耗时,报错等
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- 600bb0a: fix: fix remixRouter not existed in conventional routes
|
|
36
|
+
fix: 修复 remixRouter 在约定式路由下不存在问题
|
|
37
|
+
- fd3e71c: fix: if a route dont has component, should be as a no-layout route
|
|
38
|
+
fix: 如果路由对象没有组件属性,应该被看做无布局路由
|
|
39
|
+
- 9a81e31: fix(plugin-runtime): ssr reporter some problems
|
|
40
|
+
fix(plugin-runtime): ssr reporter 小问题
|
|
41
|
+
- Updated dependencies [e6b5355]
|
|
42
|
+
- Updated dependencies [93db783]
|
|
43
|
+
- Updated dependencies [cba7675]
|
|
44
|
+
- Updated dependencies [99052ea]
|
|
45
|
+
- Updated dependencies [1d71d2e]
|
|
46
|
+
- @modern-js/utils@2.29.0
|
|
47
|
+
- @modern-js/types@2.29.0
|
|
48
|
+
- @modern-js/plugin@2.29.0
|
|
49
|
+
|
|
3
50
|
## 2.28.0
|
|
4
51
|
|
|
5
52
|
### 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 {
|
|
@@ -40,9 +40,6 @@ _export(exports, {
|
|
|
40
40
|
DOCUMENT_LINKS_PLACEHOLDER: function() {
|
|
41
41
|
return DOCUMENT_LINKS_PLACEHOLDER;
|
|
42
42
|
},
|
|
43
|
-
DOCUMENT_NO_SCRIPTE_PLACEHOLDER: function() {
|
|
44
|
-
return DOCUMENT_NO_SCRIPTE_PLACEHOLDER;
|
|
45
|
-
},
|
|
46
43
|
DOCUMENT_SCRIPT_PLACEHOLDER_START: function() {
|
|
47
44
|
return DOCUMENT_SCRIPT_PLACEHOLDER_START;
|
|
48
45
|
},
|
|
@@ -81,7 +78,6 @@ const DOCUMENT_SSRDATASCRIPT_PLACEHOLDER = encodeURIComponent(HTML_SSRDATASCRIPT
|
|
|
81
78
|
const DOCUMENT_FILE_NAME = "Document";
|
|
82
79
|
const DOCUMENT_SCRIPTS_PLACEHOLDER = encodeURIComponent("<!-- chunk scripts placeholder -->");
|
|
83
80
|
const DOCUMENT_LINKS_PLACEHOLDER = encodeURIComponent("<!-- chunk links placeholder -->");
|
|
84
|
-
const DOCUMENT_NO_SCRIPTE_PLACEHOLDER = encodeURIComponent("<!-- no-script -->");
|
|
85
81
|
const DOCUMENT_SCRIPT_PLACEHOLDER_START = encodeURIComponent("<!-- script-start -->");
|
|
86
82
|
const DOCUMENT_SCRIPT_PLACEHOLDER_END = encodeURIComponent("<!-- script-end -->");
|
|
87
83
|
const DOCUMENT_STYLE_PLACEHOLDER_START = encodeURIComponent("<!-- style-start -->");
|
|
@@ -89,7 +85,6 @@ const DOCUMENT_STYLE_PLACEHOLDER_END = encodeURIComponent("<!-- style-end -->");
|
|
|
89
85
|
const DOCUMENT_COMMENT_PLACEHOLDER_START = encodeURIComponent("<!-- comment-start -->");
|
|
90
86
|
const DOCUMENT_COMMENT_PLACEHOLDER_END = encodeURIComponent("<!-- comment-end -->");
|
|
91
87
|
const PLACEHOLDER_REPLACER_MAP = {
|
|
92
|
-
[DOCUMENT_NO_SCRIPTE_PLACEHOLDER]: `We're sorry but react app doesn't work properly without JavaScript enabled. Please enable it to continue.`,
|
|
93
88
|
[DOCUMENT_SSR_PLACEHOLDER]: HTML_SEPARATOR,
|
|
94
89
|
[DOCUMENT_CHUNKSMAP_PLACEHOLDER]: _constants.HTML_CHUNKSMAP_SEPARATOR,
|
|
95
90
|
[DOCUMENT_SSRDATASCRIPT_PLACEHOLDER]: HTML_SSRDATASCRIPT_SEPARATOR
|
|
@@ -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() {
|
|
@@ -24,8 +24,8 @@ const PLUGIN_IDENTIFIER = "ssr";
|
|
|
24
24
|
const hasStringSSREntry = (userConfig) => {
|
|
25
25
|
var _server, _server1;
|
|
26
26
|
const isStreaming = (ssr) => ssr && typeof ssr === "object" && ssr.mode === "stream";
|
|
27
|
-
const { server } = userConfig;
|
|
28
|
-
if (((_server = server) === null || _server === void 0 ? void 0 : _server.ssr) && !isStreaming(server.ssr)) {
|
|
27
|
+
const { server, output } = userConfig;
|
|
28
|
+
if ((((_server = server) === null || _server === void 0 ? void 0 : _server.ssr) || output.ssg) && !isStreaming(server.ssr)) {
|
|
29
29
|
return true;
|
|
30
30
|
}
|
|
31
31
|
if (((_server1 = server) === null || _server1 === void 0 ? void 0 : _server1.ssrByEntries) && typeof server.ssrByEntries === "object") {
|
|
@@ -37,6 +37,11 @@ const hasStringSSREntry = (userConfig) => {
|
|
|
37
37
|
}
|
|
38
38
|
return false;
|
|
39
39
|
};
|
|
40
|
+
const checkUseStringSSR = (config) => {
|
|
41
|
+
var _output;
|
|
42
|
+
const { output } = config;
|
|
43
|
+
return Boolean((_output = output) === null || _output === void 0 ? void 0 : _output.ssg) || hasStringSSREntry(config);
|
|
44
|
+
};
|
|
40
45
|
const ssrPlugin = () => ({
|
|
41
46
|
name: "@modern-js/plugin-ssr",
|
|
42
47
|
required: [
|
|
@@ -49,29 +54,30 @@ const ssrPlugin = () => ({
|
|
|
49
54
|
config() {
|
|
50
55
|
const appContext = api.useAppContext();
|
|
51
56
|
pluginsExportsUtils = (0, _utils.createRuntimeExportsUtils)(appContext.internalDirectory, "plugins");
|
|
52
|
-
const userConfig = api.useConfigContext();
|
|
53
57
|
const { bundlerType = "webpack" } = api.useAppContext();
|
|
54
|
-
const
|
|
58
|
+
const babelHandler = (() => {
|
|
55
59
|
if (bundlerType === "webpack") {
|
|
56
60
|
return (config) => {
|
|
57
61
|
var _config_plugins;
|
|
62
|
+
const userConfig = api.useResolvedConfigContext();
|
|
58
63
|
(_config_plugins = config.plugins) === null || _config_plugins === void 0 ? void 0 : _config_plugins.push(_path.default.join(__dirname, "./babel-plugin-ssr-loader-id"));
|
|
59
|
-
if ((0, _utils.isUseSSRBundle)(userConfig) &&
|
|
64
|
+
if ((0, _utils.isUseSSRBundle)(userConfig) && checkUseStringSSR(userConfig)) {
|
|
60
65
|
var _config_plugins1;
|
|
61
66
|
(_config_plugins1 = config.plugins) === null || _config_plugins1 === void 0 ? void 0 : _config_plugins1.push(require.resolve("@loadable/babel-plugin"));
|
|
62
67
|
}
|
|
63
68
|
};
|
|
64
69
|
} else if (bundlerType === "rspack") {
|
|
65
|
-
|
|
66
|
-
|
|
70
|
+
return (config) => {
|
|
71
|
+
const userConfig = api.useResolvedConfigContext();
|
|
72
|
+
if ((0, _utils.isUseSSRBundle)(userConfig)) {
|
|
67
73
|
var _config_plugins;
|
|
68
74
|
(_config_plugins = config.plugins) === null || _config_plugins === void 0 ? void 0 : _config_plugins.push(_path.default.join(__dirname, "./babel-plugin-ssr-loader-id"));
|
|
69
|
-
if (
|
|
75
|
+
if (checkUseStringSSR(userConfig)) {
|
|
70
76
|
var _config_plugins1;
|
|
71
77
|
(_config_plugins1 = config.plugins) === null || _config_plugins1 === void 0 ? void 0 : _config_plugins1.push(require.resolve("@loadable/babel-plugin"));
|
|
72
78
|
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
75
81
|
}
|
|
76
82
|
})();
|
|
77
83
|
return {
|
|
@@ -87,8 +93,8 @@ const ssrPlugin = () => ({
|
|
|
87
93
|
},
|
|
88
94
|
tools: {
|
|
89
95
|
bundlerChain(chain, { isServer, isServiceWorker, CHAIN_ID }) {
|
|
90
|
-
const
|
|
91
|
-
if ((0, _utils.isUseSSRBundle)(
|
|
96
|
+
const userConfig = api.useResolvedConfigContext();
|
|
97
|
+
if ((0, _utils.isUseSSRBundle)(userConfig) && !isServer && !isServiceWorker && checkUseStringSSR(userConfig)) {
|
|
92
98
|
const LoadableBundlerPlugin = require("./loadable-bundler-plugin.js");
|
|
93
99
|
chain.plugin(CHAIN_ID.PLUGIN.LOADABLE).use(LoadableBundlerPlugin, [
|
|
94
100
|
{
|
|
@@ -97,7 +103,7 @@ const ssrPlugin = () => ({
|
|
|
97
103
|
]);
|
|
98
104
|
}
|
|
99
105
|
},
|
|
100
|
-
babel:
|
|
106
|
+
babel: babelHandler
|
|
101
107
|
}
|
|
102
108
|
};
|
|
103
109
|
},
|
|
@@ -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,18 @@ 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 _tracker = require("../tracker");
|
|
24
25
|
const _template = require("./template");
|
|
25
26
|
const _reduce = require("./reduce");
|
|
26
27
|
const _loadable = /* @__PURE__ */ _interop_require_wildcard._(require("./loadable"));
|
|
27
28
|
const _styledComponent = /* @__PURE__ */ _interop_require_wildcard._(require("./styledComponent"));
|
|
28
|
-
const buildTemplateData = (context, data, renderLevel) => {
|
|
29
|
+
const buildTemplateData = (context, data, renderLevel, tracker) => {
|
|
29
30
|
const { request, enableUnsafeCtx } = context;
|
|
30
31
|
const unsafeContext = {
|
|
31
32
|
headers: request.headers
|
|
@@ -40,6 +41,9 @@ const buildTemplateData = (context, data, renderLevel) => {
|
|
|
40
41
|
host: request.host,
|
|
41
42
|
url: request.url,
|
|
42
43
|
...enableUnsafeCtx ? unsafeContext : {}
|
|
44
|
+
},
|
|
45
|
+
reporter: {
|
|
46
|
+
sessionId: tracker.sessionId
|
|
43
47
|
}
|
|
44
48
|
},
|
|
45
49
|
renderLevel
|
|
@@ -68,7 +72,7 @@ class Entry {
|
|
|
68
72
|
errors: (0, _utils.serializeErrors)(routerContext.errors)
|
|
69
73
|
} : void 0;
|
|
70
74
|
let html = "";
|
|
71
|
-
const templateData = buildTemplateData(ssrContext, prefetchData, this.result.renderLevel);
|
|
75
|
+
const templateData = buildTemplateData(ssrContext, prefetchData, this.result.renderLevel, this.tracker);
|
|
72
76
|
const SSRData = this.getSSRDataScript(templateData, routerData);
|
|
73
77
|
for (const fragment of this.fragments) {
|
|
74
78
|
if (fragment.isVariable && fragment.content === "SSRDataScript") {
|
|
@@ -87,12 +91,10 @@ class Entry {
|
|
|
87
91
|
prefetchData = await (0, _prefetch.default)(this.App, context);
|
|
88
92
|
this.result.renderLevel = _types.RenderLevel.SERVER_PREFETCH;
|
|
89
93
|
const prefetchCost = end();
|
|
90
|
-
this.
|
|
91
|
-
this.metrics.emitTimer("app.prefetch.cost", prefetchCost);
|
|
94
|
+
this.tracker.trackTiming(_tracker.SSRTimings.SSR_PREFETCH, prefetchCost);
|
|
92
95
|
} catch (e) {
|
|
93
96
|
this.result.renderLevel = _types.RenderLevel.CLIENT_RENDER;
|
|
94
|
-
this.
|
|
95
|
-
this.metrics.emitCounter("app.prefetch.render.error", 1);
|
|
97
|
+
this.tracker.trackError(_tracker.SSRErrors.PREFETCH, e);
|
|
96
98
|
}
|
|
97
99
|
return prefetchData || {};
|
|
98
100
|
}
|
|
@@ -121,12 +123,10 @@ class Entry {
|
|
|
121
123
|
(jsx) => _server.default.renderToString(jsx)
|
|
122
124
|
]);
|
|
123
125
|
const cost = end();
|
|
124
|
-
this.
|
|
125
|
-
this.metrics.emitTimer("app.render.html.cost", cost);
|
|
126
|
+
this.tracker.trackTiming(_tracker.SSRTimings.SSR_RENDER_HTML, cost);
|
|
126
127
|
this.result.renderLevel = _types.RenderLevel.SERVER_RENDER;
|
|
127
128
|
} catch (e) {
|
|
128
|
-
this.
|
|
129
|
-
this.metrics.emitCounter("app.render.html.error", 1);
|
|
129
|
+
this.tracker.trackError(_tracker.SSRErrors.RENDER_HTML, e);
|
|
130
130
|
}
|
|
131
131
|
return html;
|
|
132
132
|
}
|
|
@@ -151,7 +151,7 @@ class Entry {
|
|
|
151
151
|
_define_property._(this, "entryName", void 0);
|
|
152
152
|
_define_property._(this, "result", void 0);
|
|
153
153
|
_define_property._(this, "metrics", void 0);
|
|
154
|
-
_define_property._(this, "
|
|
154
|
+
_define_property._(this, "tracker", void 0);
|
|
155
155
|
_define_property._(this, "template", void 0);
|
|
156
156
|
_define_property._(this, "App", void 0);
|
|
157
157
|
_define_property._(this, "fragments", void 0);
|
|
@@ -166,8 +166,8 @@ class Entry {
|
|
|
166
166
|
this.host = host;
|
|
167
167
|
this.App = options.App;
|
|
168
168
|
this.pluginConfig = config;
|
|
169
|
+
this.tracker = (0, _tracker.createSSRTracker)(ctx);
|
|
169
170
|
this.metrics = ctx.metrics;
|
|
170
|
-
this.logger = ctx.logger;
|
|
171
171
|
this.nonce = nonce;
|
|
172
172
|
this.result = {
|
|
173
173
|
renderLevel: _types.RenderLevel.CLIENT_RENDER,
|
|
@@ -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 _tracker = require("../tracker");
|
|
15
16
|
const _entry = /* @__PURE__ */ _interop_require_default._(require("./entry"));
|
|
16
17
|
const render = ({ App, context, config }) => {
|
|
17
18
|
const ssrContext = context.ssrContext;
|
|
@@ -25,8 +26,7 @@ const render = ({ App, context, config }) => {
|
|
|
25
26
|
const end = (0, _time.time)();
|
|
26
27
|
const html = await entry.renderToHtml(context);
|
|
27
28
|
const cost = end();
|
|
28
|
-
entry.
|
|
29
|
-
entry.metrics.emitTimer("app.render.cost", cost);
|
|
29
|
+
entry.tracker.trackTiming(_tracker.SSRTimings.SSR_RENDER_TOTAL, cost);
|
|
30
30
|
const cacheConfig = _prerender.PreRender.config();
|
|
31
31
|
if (cacheConfig) {
|
|
32
32
|
context.ssrContext.cacheConfig = cacheConfig;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
Object.defineProperty(target, name, {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: all[name]
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
_export(exports, {
|
|
13
|
+
SSRTimings: function() {
|
|
14
|
+
return SSRTimings;
|
|
15
|
+
},
|
|
16
|
+
SSRErrors: function() {
|
|
17
|
+
return SSRErrors;
|
|
18
|
+
},
|
|
19
|
+
createSSRTracker: function() {
|
|
20
|
+
return createSSRTracker;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
var SSRTimings;
|
|
24
|
+
(function(SSRTimings2) {
|
|
25
|
+
SSRTimings2[SSRTimings2["SSR_RENDER_TOTAL"] = 0] = "SSR_RENDER_TOTAL";
|
|
26
|
+
SSRTimings2[SSRTimings2["SSR_PREFETCH"] = 1] = "SSR_PREFETCH";
|
|
27
|
+
SSRTimings2[SSRTimings2["SSR_RENDER_HTML"] = 2] = "SSR_RENDER_HTML";
|
|
28
|
+
})(SSRTimings || (SSRTimings = {}));
|
|
29
|
+
var SSRErrors;
|
|
30
|
+
(function(SSRErrors2) {
|
|
31
|
+
SSRErrors2[SSRErrors2["PREFETCH"] = 0] = "PREFETCH";
|
|
32
|
+
SSRErrors2[SSRErrors2["RENDER_HTML"] = 1] = "RENDER_HTML";
|
|
33
|
+
})(SSRErrors || (SSRErrors = {}));
|
|
34
|
+
const errors = {
|
|
35
|
+
[SSRErrors.PREFETCH]: {
|
|
36
|
+
reporter: "SSR Error - App Prefetch Render",
|
|
37
|
+
logger: "App Prefetch Render",
|
|
38
|
+
metrics: "app.prefetch.render.error"
|
|
39
|
+
},
|
|
40
|
+
[SSRErrors.RENDER_HTML]: {
|
|
41
|
+
reporter: "SSR Error - App Render To HTML",
|
|
42
|
+
logger: "App Render To HTML",
|
|
43
|
+
metrics: "app.render.html.error"
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const timings = {
|
|
47
|
+
[SSRTimings.SSR_PREFETCH]: {
|
|
48
|
+
reporter: "ssr-prefetch",
|
|
49
|
+
serverTiming: "ssr-prefetch",
|
|
50
|
+
metrics: "app.prefeth.cost",
|
|
51
|
+
logger: "App Prefetch cost = %d ms"
|
|
52
|
+
},
|
|
53
|
+
[SSRTimings.SSR_RENDER_HTML]: {
|
|
54
|
+
reporter: "ssr-render-html",
|
|
55
|
+
serverTiming: "ssr-render-html",
|
|
56
|
+
metrics: "app.render.html.cost",
|
|
57
|
+
logger: "App Render To HTML cost = %d ms"
|
|
58
|
+
},
|
|
59
|
+
[SSRTimings.SSR_RENDER_TOTAL]: {
|
|
60
|
+
reporter: "ssr-render-total",
|
|
61
|
+
serverTiming: "ssr-render-total",
|
|
62
|
+
metrics: "app.render.cost",
|
|
63
|
+
logger: "App Render Total cost = %d ms"
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
function createSSRTracker({ reporter, serverTiming, metrics, logger }) {
|
|
67
|
+
const tracker = {
|
|
68
|
+
get sessionId() {
|
|
69
|
+
return reporter.sessionId;
|
|
70
|
+
},
|
|
71
|
+
trackError(key, e) {
|
|
72
|
+
const { reporter: reporterContent, metrics: metricsContent, logger: loggerContent } = errors[key];
|
|
73
|
+
reporterContent && reporter.reportError(reporterContent, e);
|
|
74
|
+
metricsContent && metrics.emitCounter(metricsContent, 1);
|
|
75
|
+
loggerContent && logger.error(loggerContent, e);
|
|
76
|
+
},
|
|
77
|
+
trackTiming(key, cost) {
|
|
78
|
+
const { reporter: reporterName, serverTiming: serverTimingName, logger: loggerName, metrics: metricsName } = timings[key];
|
|
79
|
+
reporterName && reporter.reportTiming(reporterName, cost);
|
|
80
|
+
serverTimingName && serverTiming.addServeTiming(serverTimingName, cost);
|
|
81
|
+
metricsName && metrics.emitTimer(metricsName, cost);
|
|
82
|
+
loggerName && logger.debug(loggerName, cost);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
return tracker;
|
|
86
|
+
}
|
|
@@ -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);
|
|
@@ -15,7 +15,6 @@ export var DOCUMENT_SSRDATASCRIPT_PLACEHOLDER = encodeURIComponent(HTML_SSRDATAS
|
|
|
15
15
|
export var DOCUMENT_FILE_NAME = "Document";
|
|
16
16
|
export var DOCUMENT_SCRIPTS_PLACEHOLDER = encodeURIComponent("<!-- chunk scripts placeholder -->");
|
|
17
17
|
export var DOCUMENT_LINKS_PLACEHOLDER = encodeURIComponent("<!-- chunk links placeholder -->");
|
|
18
|
-
export var DOCUMENT_NO_SCRIPTE_PLACEHOLDER = encodeURIComponent("<!-- no-script -->");
|
|
19
18
|
export var DOCUMENT_SCRIPT_PLACEHOLDER_START = encodeURIComponent("<!-- script-start -->");
|
|
20
19
|
export var DOCUMENT_SCRIPT_PLACEHOLDER_END = encodeURIComponent("<!-- script-end -->");
|
|
21
20
|
export var DOCUMENT_STYLE_PLACEHOLDER_START = encodeURIComponent("<!-- style-start -->");
|
|
@@ -23,4 +22,4 @@ export var DOCUMENT_STYLE_PLACEHOLDER_END = encodeURIComponent("<!-- style-end -
|
|
|
23
22
|
export var DOCUMENT_COMMENT_PLACEHOLDER_START = encodeURIComponent("<!-- comment-start -->");
|
|
24
23
|
export var DOCUMENT_COMMENT_PLACEHOLDER_END = encodeURIComponent("<!-- comment-end -->");
|
|
25
24
|
var _obj;
|
|
26
|
-
export var PLACEHOLDER_REPLACER_MAP = (_obj = {}, _define_property(_obj,
|
|
25
|
+
export var PLACEHOLDER_REPLACER_MAP = (_obj = {}, _define_property(_obj, DOCUMENT_SSR_PLACEHOLDER, HTML_SEPARATOR), _define_property(_obj, DOCUMENT_CHUNKSMAP_PLACEHOLDER, HTML_CHUNKSMAP_SEPARATOR), _define_property(_obj, DOCUMENT_SSRDATASCRIPT_PLACEHOLDER, HTML_SSRDATASCRIPT_SEPARATOR), _obj);
|
|
@@ -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() {
|
|
@@ -8,8 +8,8 @@ var hasStringSSREntry = function(userConfig) {
|
|
|
8
8
|
var isStreaming = function(ssr) {
|
|
9
9
|
return ssr && typeof ssr === "object" && ssr.mode === "stream";
|
|
10
10
|
};
|
|
11
|
-
var server = userConfig.server;
|
|
12
|
-
if (((_server = server) === null || _server === void 0 ? void 0 : _server.ssr) && !isStreaming(server.ssr)) {
|
|
11
|
+
var server = userConfig.server, output = userConfig.output;
|
|
12
|
+
if ((((_server = server) === null || _server === void 0 ? void 0 : _server.ssr) || output.ssg) && !isStreaming(server.ssr)) {
|
|
13
13
|
return true;
|
|
14
14
|
}
|
|
15
15
|
if (((_server1 = server) === null || _server1 === void 0 ? void 0 : _server1.ssrByEntries) && typeof server.ssrByEntries === "object") {
|
|
@@ -38,6 +38,11 @@ var hasStringSSREntry = function(userConfig) {
|
|
|
38
38
|
}
|
|
39
39
|
return false;
|
|
40
40
|
};
|
|
41
|
+
var checkUseStringSSR = function(config) {
|
|
42
|
+
var _output;
|
|
43
|
+
var output = config.output;
|
|
44
|
+
return Boolean((_output = output) === null || _output === void 0 ? void 0 : _output.ssg) || hasStringSSREntry(config);
|
|
45
|
+
};
|
|
41
46
|
export var ssrPlugin = function() {
|
|
42
47
|
return {
|
|
43
48
|
name: "@modern-js/plugin-ssr",
|
|
@@ -51,29 +56,30 @@ export var ssrPlugin = function() {
|
|
|
51
56
|
config: function config() {
|
|
52
57
|
var appContext = api.useAppContext();
|
|
53
58
|
pluginsExportsUtils = createRuntimeExportsUtils(appContext.internalDirectory, "plugins");
|
|
54
|
-
var userConfig = api.useConfigContext();
|
|
55
59
|
var _api_useAppContext = api.useAppContext(), _api_useAppContext_bundlerType = _api_useAppContext.bundlerType, bundlerType = _api_useAppContext_bundlerType === void 0 ? "webpack" : _api_useAppContext_bundlerType;
|
|
56
|
-
var
|
|
60
|
+
var babelHandler = function() {
|
|
57
61
|
if (bundlerType === "webpack") {
|
|
58
62
|
return function(config2) {
|
|
59
63
|
var _config_plugins;
|
|
64
|
+
var userConfig = api.useResolvedConfigContext();
|
|
60
65
|
(_config_plugins = config2.plugins) === null || _config_plugins === void 0 ? void 0 : _config_plugins.push(path.join(__dirname, "./babel-plugin-ssr-loader-id"));
|
|
61
|
-
if (isUseSSRBundle(userConfig) &&
|
|
66
|
+
if (isUseSSRBundle(userConfig) && checkUseStringSSR(userConfig)) {
|
|
62
67
|
var _config_plugins1;
|
|
63
68
|
(_config_plugins1 = config2.plugins) === null || _config_plugins1 === void 0 ? void 0 : _config_plugins1.push(require.resolve("@loadable/babel-plugin"));
|
|
64
69
|
}
|
|
65
70
|
};
|
|
66
71
|
} else if (bundlerType === "rspack") {
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
return function(config2) {
|
|
73
|
+
var userConfig = api.useResolvedConfigContext();
|
|
74
|
+
if (isUseSSRBundle(userConfig)) {
|
|
69
75
|
var _config_plugins;
|
|
70
76
|
(_config_plugins = config2.plugins) === null || _config_plugins === void 0 ? void 0 : _config_plugins.push(path.join(__dirname, "./babel-plugin-ssr-loader-id"));
|
|
71
|
-
if (
|
|
77
|
+
if (checkUseStringSSR(userConfig)) {
|
|
72
78
|
var _config_plugins1;
|
|
73
79
|
(_config_plugins1 = config2.plugins) === null || _config_plugins1 === void 0 ? void 0 : _config_plugins1.push(require.resolve("@loadable/babel-plugin"));
|
|
74
80
|
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
77
83
|
}
|
|
78
84
|
}();
|
|
79
85
|
return {
|
|
@@ -91,8 +97,8 @@ export var ssrPlugin = function() {
|
|
|
91
97
|
tools: {
|
|
92
98
|
bundlerChain: function bundlerChain(chain, param) {
|
|
93
99
|
var isServer = param.isServer, isServiceWorker = param.isServiceWorker, CHAIN_ID = param.CHAIN_ID;
|
|
94
|
-
var
|
|
95
|
-
if (isUseSSRBundle(
|
|
100
|
+
var userConfig = api.useResolvedConfigContext();
|
|
101
|
+
if (isUseSSRBundle(userConfig) && !isServer && !isServiceWorker && checkUseStringSSR(userConfig)) {
|
|
96
102
|
var LoadableBundlerPlugin = require("./loadable-bundler-plugin.js");
|
|
97
103
|
chain.plugin(CHAIN_ID.PLUGIN.LOADABLE).use(LoadableBundlerPlugin, [
|
|
98
104
|
{
|
|
@@ -101,7 +107,7 @@ export var ssrPlugin = function() {
|
|
|
101
107
|
]);
|
|
102
108
|
}
|
|
103
109
|
},
|
|
104
|
-
babel:
|
|
110
|
+
babel: babelHandler
|
|
105
111
|
}
|
|
106
112
|
};
|
|
107
113
|
},
|
|
@@ -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,18 @@ 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 { SSRErrors, SSRTimings, createSSRTracker } from "../tracker";
|
|
17
18
|
import { toFragments } from "./template";
|
|
18
19
|
import { reduce } from "./reduce";
|
|
19
20
|
import * as loadableRenderer from "./loadable";
|
|
20
21
|
import * as styledComponentRenderer from "./styledComponent";
|
|
21
|
-
var buildTemplateData = function(context, data, renderLevel) {
|
|
22
|
+
var buildTemplateData = function(context, data, renderLevel, tracker) {
|
|
22
23
|
var request = context.request, enableUnsafeCtx = context.enableUnsafeCtx;
|
|
23
24
|
var unsafeContext = {
|
|
24
25
|
headers: request.headers
|
|
@@ -32,7 +33,10 @@ var buildTemplateData = function(context, data, renderLevel) {
|
|
|
32
33
|
pathname: request.pathname,
|
|
33
34
|
host: request.host,
|
|
34
35
|
url: request.url
|
|
35
|
-
}, enableUnsafeCtx ? unsafeContext : {})
|
|
36
|
+
}, enableUnsafeCtx ? unsafeContext : {}),
|
|
37
|
+
reporter: {
|
|
38
|
+
sessionId: tracker.sessionId
|
|
39
|
+
}
|
|
36
40
|
},
|
|
37
41
|
renderLevel: renderLevel
|
|
38
42
|
};
|
|
@@ -44,7 +48,7 @@ var Entry = /* @__PURE__ */ function() {
|
|
|
44
48
|
_define_property(this, "entryName", void 0);
|
|
45
49
|
_define_property(this, "result", void 0);
|
|
46
50
|
_define_property(this, "metrics", void 0);
|
|
47
|
-
_define_property(this, "
|
|
51
|
+
_define_property(this, "tracker", void 0);
|
|
48
52
|
_define_property(this, "template", void 0);
|
|
49
53
|
_define_property(this, "App", void 0);
|
|
50
54
|
_define_property(this, "fragments", void 0);
|
|
@@ -59,8 +63,8 @@ var Entry = /* @__PURE__ */ function() {
|
|
|
59
63
|
this.host = host;
|
|
60
64
|
this.App = options.App;
|
|
61
65
|
this.pluginConfig = config;
|
|
66
|
+
this.tracker = createSSRTracker(ctx);
|
|
62
67
|
this.metrics = ctx.metrics;
|
|
63
|
-
this.logger = ctx.logger;
|
|
64
68
|
this.nonce = nonce;
|
|
65
69
|
this.result = {
|
|
66
70
|
renderLevel: RenderLevel.CLIENT_RENDER,
|
|
@@ -115,7 +119,7 @@ var Entry = /* @__PURE__ */ function() {
|
|
|
115
119
|
errors: serializeErrors(routerContext.errors)
|
|
116
120
|
} : void 0;
|
|
117
121
|
html = "";
|
|
118
|
-
templateData = buildTemplateData(ssrContext, prefetchData, _this.result.renderLevel);
|
|
122
|
+
templateData = buildTemplateData(ssrContext, prefetchData, _this.result.renderLevel, _this.tracker);
|
|
119
123
|
SSRData = _this.getSSRDataScript(templateData, routerData);
|
|
120
124
|
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
121
125
|
try {
|
|
@@ -177,8 +181,7 @@ var Entry = /* @__PURE__ */ function() {
|
|
|
177
181
|
prefetchData = _state.sent();
|
|
178
182
|
_this.result.renderLevel = RenderLevel.SERVER_PREFETCH;
|
|
179
183
|
prefetchCost = end();
|
|
180
|
-
_this.
|
|
181
|
-
_this.metrics.emitTimer("app.prefetch.cost", prefetchCost);
|
|
184
|
+
_this.tracker.trackTiming(SSRTimings.SSR_PREFETCH, prefetchCost);
|
|
182
185
|
return [
|
|
183
186
|
3,
|
|
184
187
|
4
|
|
@@ -186,8 +189,7 @@ var Entry = /* @__PURE__ */ function() {
|
|
|
186
189
|
case 3:
|
|
187
190
|
e = _state.sent();
|
|
188
191
|
_this.result.renderLevel = RenderLevel.CLIENT_RENDER;
|
|
189
|
-
_this.
|
|
190
|
-
_this.metrics.emitCounter("app.prefetch.render.error", 1);
|
|
192
|
+
_this.tracker.trackError(SSRErrors.PREFETCH, e);
|
|
191
193
|
return [
|
|
192
194
|
3,
|
|
193
195
|
4
|
|
@@ -231,12 +233,10 @@ var Entry = /* @__PURE__ */ function() {
|
|
|
231
233
|
}
|
|
232
234
|
]);
|
|
233
235
|
var cost = end();
|
|
234
|
-
this.
|
|
235
|
-
this.metrics.emitTimer("app.render.html.cost", cost);
|
|
236
|
+
this.tracker.trackTiming(SSRTimings.SSR_RENDER_HTML, cost);
|
|
236
237
|
this.result.renderLevel = RenderLevel.SERVER_RENDER;
|
|
237
238
|
} catch (e) {
|
|
238
|
-
this.
|
|
239
|
-
this.metrics.emitCounter("app.render.html.error", 1);
|
|
239
|
+
this.tracker.trackError(SSRErrors.RENDER_HTML, e);
|
|
240
240
|
}
|
|
241
241
|
return html;
|
|
242
242
|
}
|