@modern-js/runtime 2.32.1 → 2.33.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 (54) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cjs/document/cli/index.js +9 -4
  3. package/dist/cjs/ssr/index.node.js +3 -0
  4. package/dist/cjs/ssr/serverRender/renderToString/buildHtml.js +47 -0
  5. package/dist/cjs/ssr/serverRender/renderToString/entry.js +18 -31
  6. package/dist/cjs/ssr/serverRender/renderToString/loadable.js +57 -40
  7. package/dist/cjs/ssr/serverRender/renderToString/render.js +35 -0
  8. package/dist/cjs/ssr/serverRender/renderToString/styledComponent.js +20 -9
  9. package/dist/esm/document/cli/index.js +10 -5
  10. package/dist/esm/ssr/index.node.js +3 -0
  11. package/dist/esm/ssr/serverRender/renderToString/buildHtml.js +29 -0
  12. package/dist/esm/ssr/serverRender/renderToString/entry.js +19 -50
  13. package/dist/esm/ssr/serverRender/renderToString/loadable.js +86 -56
  14. package/dist/esm/ssr/serverRender/renderToString/render.js +39 -0
  15. package/dist/esm/ssr/serverRender/renderToString/styledComponent.js +31 -7
  16. package/dist/esm-node/document/cli/index.js +9 -4
  17. package/dist/esm-node/ssr/index.node.js +3 -0
  18. package/dist/esm-node/ssr/serverRender/renderToString/buildHtml.js +19 -0
  19. package/dist/esm-node/ssr/serverRender/renderToString/entry.js +18 -30
  20. package/dist/esm-node/ssr/serverRender/renderToString/loadable.js +55 -38
  21. package/dist/esm-node/ssr/serverRender/renderToString/render.js +24 -0
  22. package/dist/esm-node/ssr/serverRender/renderToString/styledComponent.js +18 -7
  23. package/dist/types/ssr/serverRender/renderToStream/template.d.ts +4 -1
  24. package/dist/types/ssr/serverRender/renderToString/buildHtml.d.ts +6 -0
  25. package/dist/types/ssr/serverRender/renderToString/entry.d.ts +1 -2
  26. package/dist/types/ssr/serverRender/renderToString/loadable.d.ts +21 -2
  27. package/dist/types/ssr/serverRender/renderToString/render.d.ts +14 -0
  28. package/dist/types/ssr/serverRender/renderToString/styledComponent.d.ts +15 -2
  29. package/dist/types/ssr/serverRender/renderToString/type.d.ts +2 -12
  30. package/package.json +9 -9
  31. package/dist/cjs/ssr/serverRender/constants.js +0 -16
  32. package/dist/cjs/ssr/serverRender/renderToStream/loadable.js +0 -30
  33. package/dist/cjs/ssr/serverRender/renderToStream/styledComponent.js +0 -19
  34. package/dist/cjs/ssr/serverRender/renderToStream/type.js +0 -4
  35. package/dist/cjs/ssr/serverRender/renderToString/reduce.js +0 -17
  36. package/dist/cjs/ssr/serverRender/renderToString/template.js +0 -79
  37. package/dist/esm/ssr/serverRender/constants.js +0 -6
  38. package/dist/esm/ssr/serverRender/renderToStream/loadable.js +0 -21
  39. package/dist/esm/ssr/serverRender/renderToStream/styledComponent.js +0 -10
  40. package/dist/esm/ssr/serverRender/renderToStream/type.js +0 -1
  41. package/dist/esm/ssr/serverRender/renderToString/reduce.js +0 -9
  42. package/dist/esm/ssr/serverRender/renderToString/template.js +0 -81
  43. package/dist/esm-node/ssr/serverRender/constants.js +0 -6
  44. package/dist/esm-node/ssr/serverRender/renderToStream/loadable.js +0 -20
  45. package/dist/esm-node/ssr/serverRender/renderToStream/styledComponent.js +0 -9
  46. package/dist/esm-node/ssr/serverRender/renderToStream/type.js +0 -1
  47. package/dist/esm-node/ssr/serverRender/renderToString/reduce.js +0 -5
  48. package/dist/esm-node/ssr/serverRender/renderToString/template.js +0 -60
  49. package/dist/types/ssr/serverRender/constants.d.ts +0 -5
  50. package/dist/types/ssr/serverRender/renderToStream/loadable.d.ts +0 -16
  51. package/dist/types/ssr/serverRender/renderToStream/styledComponent.d.ts +0 -12
  52. package/dist/types/ssr/serverRender/renderToStream/type.d.ts +0 -4
  53. package/dist/types/ssr/serverRender/renderToString/reduce.d.ts +0 -3
  54. package/dist/types/ssr/serverRender/renderToString/template.d.ts +0 -14
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @modern-js/runtime
2
2
 
3
+ ## 2.33.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 2bcff4f: feat(plugin-runtime): support ssr html modifiers
8
+ feat(plugin-runtime): 支持 ssr html 修改者
9
+
10
+ ### Patch Changes
11
+
12
+ - 6ea89ab: fix: html has placeholder when not set partials
13
+ fix: html 在没有设置 partials 的时候,会多出占位符
14
+ - ae35c65: fix: ssr htmlModifiers
15
+ fix: ssr htmlModifiers 赋值问题
16
+ - 44da57b: refactor: runtime server ssr
17
+ refactor: 重构 runtime server ssr
18
+ - Updated dependencies [fd82137]
19
+ - Updated dependencies [bc1f8da]
20
+ - @modern-js/utils@2.33.0
21
+ - @modern-js/plugin@2.33.0
22
+ - @modern-js/types@2.33.0
23
+
3
24
  ## 2.32.1
4
25
 
5
26
  ### Patch Changes
@@ -138,12 +138,17 @@ const documentPlugin = () => ({
138
138
  htmlWebpackPlugin.tags.headTags.filter((item) => item.tagName === "script").join(""),
139
139
  htmlWebpackPlugin.tags.bodyTags.toString()
140
140
  ].join("");
141
+ const partialsContent = {
142
+ partialsTop: "",
143
+ partialsHead: "",
144
+ partialsBody: ""
145
+ };
141
146
  if ((_partialsByEntrypoint = partialsByEntrypoint) === null || _partialsByEntrypoint === void 0 ? void 0 : _partialsByEntrypoint[entryName]) {
142
- const partialsTop = partialsByEntrypoint[entryName].top.join("\n");
143
- const partialsHead = partialsByEntrypoint[entryName].head.join("\n");
144
- const partialsBody = partialsByEntrypoint[entryName].body.join("\n");
145
- html = html.replace(_constants.TOP_PARTICALS_SEPARATOR, partialsTop).replace(_constants.HEAD_PARTICALS_SEPARATOR, partialsHead).replace(_constants.BODY_PARTICALS_SEPARATOR, partialsBody);
147
+ partialsContent.partialsTop = partialsByEntrypoint[entryName].top.join("\n");
148
+ partialsContent.partialsHead = partialsByEntrypoint[entryName].head.join("\n");
149
+ partialsContent.partialsBody = partialsByEntrypoint[entryName].body.join("\n");
146
150
  }
151
+ html = html.replace(_constants.TOP_PARTICALS_SEPARATOR, partialsContent.partialsTop).replace(_constants.HEAD_PARTICALS_SEPARATOR, partialsContent.partialsHead).replace(_constants.BODY_PARTICALS_SEPARATOR, partialsContent.partialsBody);
147
152
  const links = [
148
153
  htmlWebpackPlugin.tags.headTags.filter((item) => item.tagName === "link").join("")
149
154
  ].join("");
@@ -38,6 +38,9 @@ const ssr = (config = {}) => ({
38
38
  const { request } = context.ssrContext;
39
39
  context.ssrContext.request = (0, _utils.formatServer)(request);
40
40
  context.ssrContext.mode = config.mode;
41
+ if (!context.ssrContext.htmlModifiers) {
42
+ context.ssrContext.htmlModifiers = [];
43
+ }
41
44
  return next({
42
45
  context
43
46
  });
@@ -0,0 +1,47 @@
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
+ buildHtml: function() {
14
+ return buildHtml;
15
+ },
16
+ createReplaceHtml: function() {
17
+ return createReplaceHtml;
18
+ },
19
+ createReplaceSSRDataScript: function() {
20
+ return createReplaceSSRDataScript;
21
+ },
22
+ createReplaceChunkJs: function() {
23
+ return createReplaceChunkJs;
24
+ },
25
+ createReplaceChunkCss: function() {
26
+ return createReplaceChunkCss;
27
+ }
28
+ });
29
+ function buildHtml(template, callbacks) {
30
+ return callbacks.reduce((tmp, cb) => cb(tmp), template);
31
+ }
32
+ function createReplaceHtml(html) {
33
+ const HTML_REG = /<!--<\?-\s*html\s*\?>-->/;
34
+ return (template) => template.replace(HTML_REG, html);
35
+ }
36
+ function createReplaceSSRDataScript(data) {
37
+ const SSR_DATA_REG = /<!--<\?-\s*SSRDataScript\s*\?>-->/;
38
+ return (template) => template.replace(SSR_DATA_REG, data);
39
+ }
40
+ function createReplaceChunkJs(js) {
41
+ const CHUNK_JS_REG = /<!--<\?-\s*chunksMap\.js\s*\?>-->/;
42
+ return (template) => template.replace(CHUNK_JS_REG, js);
43
+ }
44
+ function createReplaceChunkCss(css) {
45
+ const CHUNK_CSS_REG = /<!--<\?-\s*chunksMap\.css\s*\?>-->/;
46
+ return (template) => template.replace(CHUNK_CSS_REG, css);
47
+ }
@@ -10,9 +10,7 @@ Object.defineProperty(exports, "default", {
10
10
  });
11
11
  const _define_property = require("@swc/helpers/_/_define_property");
12
12
  const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
13
- const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
14
13
  const _react = /* @__PURE__ */ _interop_require_default._(require("react"));
15
- const _server = /* @__PURE__ */ _interop_require_default._(require("react-dom/server"));
16
14
  const _runtimenode = require("@modern-js/utils/runtime-node");
17
15
  const _reacthelmet = /* @__PURE__ */ _interop_require_default._(require("react-helmet"));
18
16
  const _time = require("@modern-js/utils/universal/time");
@@ -22,10 +20,10 @@ const _types = require("../types");
22
20
  const _prefetch = /* @__PURE__ */ _interop_require_default._(require("../../prefetch"));
23
21
  const _utils1 = require("../utils");
24
22
  const _tracker = require("../tracker");
25
- const _template = require("./template");
26
- const _reduce = require("./reduce");
27
- const _loadable = /* @__PURE__ */ _interop_require_wildcard._(require("./loadable"));
28
- const _styledComponent = /* @__PURE__ */ _interop_require_wildcard._(require("./styledComponent"));
23
+ const _loadable = require("./loadable");
24
+ const _render = require("./render");
25
+ const _styledComponent = require("./styledComponent");
26
+ const _buildHtml = require("./buildHtml");
29
27
  const buildTemplateData = (context, data, renderLevel, tracker) => {
30
28
  const { request, enableUnsafeCtx } = context;
31
29
  const unsafeContext = {
@@ -71,16 +69,15 @@ class Entry {
71
69
  loaderData: routerContext.loaderData,
72
70
  errors: (0, _utils.serializeErrors)(routerContext.errors)
73
71
  } : void 0;
74
- let html = "";
75
72
  const templateData = buildTemplateData(ssrContext, prefetchData, this.result.renderLevel, this.tracker);
76
- const SSRData = this.getSSRDataScript(templateData, routerData);
77
- for (const fragment of this.fragments) {
78
- if (fragment.isVariable && fragment.content === "SSRDataScript") {
79
- html += fragment.getValue(SSRData);
80
- } else {
81
- html += fragment.getValue(this.result);
82
- }
83
- }
73
+ const ssrDataScripts = this.getSSRDataScript(templateData, routerData);
74
+ const html = (0, _buildHtml.buildHtml)(this.template, [
75
+ (0, _buildHtml.createReplaceChunkCss)(this.result.chunksMap.css),
76
+ (0, _buildHtml.createReplaceChunkJs)(this.result.chunksMap.js),
77
+ (0, _buildHtml.createReplaceHtml)(this.result.html || ""),
78
+ (0, _buildHtml.createReplaceSSRDataScript)(ssrDataScripts),
79
+ ...this.htmlModifiers
80
+ ]);
84
81
  const helmetData = _reacthelmet.default.renderStatic();
85
82
  return helmetData ? (0, _helmet.default)(html, helmetData) : html;
86
83
  }
@@ -108,20 +105,14 @@ class Entry {
108
105
  ssr: true
109
106
  })
110
107
  });
111
- const renderContext = {
108
+ html = (0, _render.createRender)(App).addCollector((0, _styledComponent.createStyledCollector)(this.result)).addCollector((0, _loadable.createLoadableCollector)({
112
109
  stats: ssrContext.loadableStats,
113
- host: this.host,
114
110
  result: this.result,
115
111
  entryName: this.entryName,
116
112
  config: this.pluginConfig,
117
113
  nonce: this.nonce,
118
114
  template: this.template
119
- };
120
- html = (0, _reduce.reduce)(App, renderContext, [
121
- _styledComponent.toHtml,
122
- _loadable.toHtml,
123
- (jsx) => _server.default.renderToString(jsx)
124
- ]);
115
+ })).finish();
125
116
  const cost = end();
126
117
  this.tracker.trackTiming(_tracker.SSRTimings.SSR_RENDER_HTML, cost);
127
118
  this.result.renderLevel = _types.RenderLevel.SERVER_RENDER;
@@ -143,9 +134,7 @@ class Entry {
143
134
  <script${attrsStr}>window._ROUTER_DATA = ${serializedRouterData}</script>` : `
144
135
  <script type="application/json" id="${_utils1.ROUTER_DATA_JSON_ID}">${serializedRouterData}</script>`;
145
136
  }
146
- return {
147
- SSRDataScript: ssrDataScripts
148
- };
137
+ return ssrDataScripts;
149
138
  }
150
139
  constructor(options) {
151
140
  _define_property._(this, "entryName", void 0);
@@ -154,20 +143,18 @@ class Entry {
154
143
  _define_property._(this, "tracker", void 0);
155
144
  _define_property._(this, "template", void 0);
156
145
  _define_property._(this, "App", void 0);
157
- _define_property._(this, "fragments", void 0);
158
146
  _define_property._(this, "pluginConfig", void 0);
159
- _define_property._(this, "host", void 0);
147
+ _define_property._(this, "htmlModifiers", void 0);
160
148
  _define_property._(this, "nonce", void 0);
161
149
  const { ctx, config } = options;
162
- const { entryName, template, request: { host }, nonce } = ctx;
163
- this.fragments = (0, _template.toFragments)(template, entryName);
150
+ const { entryName, template, nonce } = ctx;
164
151
  this.template = template;
165
152
  this.entryName = entryName;
166
- this.host = host;
167
153
  this.App = options.App;
168
154
  this.pluginConfig = config;
169
155
  this.tracker = (0, _tracker.createSSRTracker)(ctx);
170
156
  this.metrics = ctx.metrics;
157
+ this.htmlModifiers = ctx.htmlModifiers;
171
158
  this.nonce = nonce;
172
159
  this.result = {
173
160
  renderLevel: _types.RenderLevel.CLIENT_RENDER,
@@ -2,12 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "toHtml", {
5
+ Object.defineProperty(exports, "createLoadableCollector", {
6
6
  enumerable: true,
7
7
  get: function() {
8
- return toHtml;
8
+ return createLoadableCollector;
9
9
  }
10
10
  });
11
+ const _define_property = require("@swc/helpers/_/_define_property");
11
12
  const _server = require("@loadable/server");
12
13
  const _utils = require("../utils");
13
14
  const extname = (uri) => {
@@ -17,47 +18,63 @@ const extname = (uri) => {
17
18
  }
18
19
  return `.${(_uri = uri) === null || _uri === void 0 ? void 0 : _uri.split(".").pop()}` || "";
19
20
  };
20
- const toHtml = (jsx, renderer, next) => {
21
- const { stats, result: { chunksMap }, config = {}, nonce } = renderer;
22
- if (!stats || chunksMap.js) {
23
- return next(jsx);
24
- }
25
- const extractor = new _server.ChunkExtractor({
26
- stats,
27
- entrypoints: [
28
- renderer.entryName
29
- ]
30
- });
31
- const html = next(extractor.collectChunks(jsx));
32
- const chunks = extractor.getChunkAssets(extractor.chunks);
33
- chunksMap.js = (chunksMap.js || "") + (0, _utils.getLoadableScripts)(extractor);
34
- for (const v of chunks) {
35
- const fileType = extname(v.url).slice(1);
36
- const attributes = {};
37
- const { crossorigin, scriptLoading = "defer" } = config;
38
- if (crossorigin) {
39
- attributes.crossorigin = crossorigin === true ? "anonymous" : crossorigin;
21
+ class LoadableCollector {
22
+ collect(comopnent) {
23
+ const { stats, entryName } = this.options;
24
+ if (!stats) {
25
+ return comopnent;
40
26
  }
41
- switch (scriptLoading) {
42
- case "defer":
43
- attributes.defer = true;
44
- break;
45
- case "module":
46
- attributes.type = "module";
47
- break;
48
- default:
27
+ this.extractor = new _server.ChunkExtractor({
28
+ stats,
29
+ entrypoints: [
30
+ entryName
31
+ ]
32
+ });
33
+ return this.extractor.collectChunks(comopnent);
34
+ }
35
+ effect() {
36
+ if (!this.extractor) {
37
+ return;
49
38
  }
50
- if (fileType === "js") {
51
- const jsChunkReg = new RegExp(`<script .*src="${v.url}".*>`);
52
- if (!jsChunkReg.test(renderer.template)) {
53
- attributes.nonce = nonce;
39
+ const { result: { chunksMap }, config, template, nonce } = this.options;
40
+ const { extractor } = this;
41
+ const chunks = extractor.getChunkAssets(extractor.chunks);
42
+ chunksMap.js = (chunksMap.js || "") + (0, _utils.getLoadableScripts)(extractor);
43
+ for (const v of chunks) {
44
+ const fileType = extname(v.url).slice(1);
45
+ const attributes = {};
46
+ const { crossorigin, scriptLoading = "defer" } = config;
47
+ if (crossorigin) {
48
+ attributes.crossorigin = crossorigin === true ? "anonymous" : crossorigin;
49
+ }
50
+ switch (scriptLoading) {
51
+ case "defer":
52
+ attributes.defer = true;
53
+ break;
54
+ case "module":
55
+ attributes.type = "module";
56
+ break;
57
+ default:
58
+ }
59
+ if (fileType === "js") {
60
+ const jsChunkReg = new RegExp(`<script .*src="${v.url}".*>`);
61
+ if (!jsChunkReg.test(template)) {
62
+ attributes.nonce = nonce;
63
+ const attrsStr = (0, _utils.attributesToString)(attributes);
64
+ chunksMap[fileType] += `<script${attrsStr} src="${v.url}"></script>`;
65
+ }
66
+ } else if (fileType === "css") {
54
67
  const attrsStr = (0, _utils.attributesToString)(attributes);
55
- chunksMap[fileType] += `<script${attrsStr} src="${v.url}"></script>`;
68
+ chunksMap[fileType] += `<link${attrsStr} href="${v.url}" rel="stylesheet" />`;
56
69
  }
57
- } else if (fileType === "css") {
58
- const attrsStr = (0, _utils.attributesToString)(attributes);
59
- chunksMap[fileType] += `<link${attrsStr} href="${v.url}" rel="stylesheet" />`;
60
70
  }
61
71
  }
62
- return html;
63
- };
72
+ constructor(options) {
73
+ _define_property._(this, "options", void 0);
74
+ _define_property._(this, "extractor", void 0);
75
+ this.options = options;
76
+ }
77
+ }
78
+ function createLoadableCollector(options) {
79
+ return new LoadableCollector(options);
80
+ }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "createRender", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return createRender;
9
+ }
10
+ });
11
+ const _define_property = require("@swc/helpers/_/_define_property");
12
+ const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
13
+ const _server = /* @__PURE__ */ _interop_require_default._(require("react-dom/server"));
14
+ class Render {
15
+ addCollector(collector) {
16
+ this.collectors.push(collector);
17
+ return this;
18
+ }
19
+ finish() {
20
+ const App = this.collectors.reduce((pre, collector) => collector.collect(pre), this.App);
21
+ const html = _server.default.renderToString(App);
22
+ this.collectors.forEach((component) => {
23
+ component.effect();
24
+ });
25
+ return html;
26
+ }
27
+ constructor(App) {
28
+ _define_property._(this, "App", void 0);
29
+ _define_property._(this, "collectors", []);
30
+ this.App = App;
31
+ }
32
+ }
33
+ function createRender(App) {
34
+ return new Render(App);
35
+ }
@@ -2,17 +2,28 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "toHtml", {
5
+ Object.defineProperty(exports, "createStyledCollector", {
6
6
  enumerable: true,
7
7
  get: function() {
8
- return toHtml;
8
+ return createStyledCollector;
9
9
  }
10
10
  });
11
+ const _define_property = require("@swc/helpers/_/_define_property");
11
12
  const _styledcomponents = require("styled-components");
12
- const toHtml = (jsx, renderer, next) => {
13
- const sheet = new _styledcomponents.ServerStyleSheet();
14
- const html = next(sheet.collectStyles(jsx));
15
- const css = sheet.getStyleTags();
16
- renderer.result.chunksMap.css += css;
17
- return html;
18
- };
13
+ class StyledCollector {
14
+ collect(comopnent) {
15
+ return this.sheet.collectStyles(comopnent);
16
+ }
17
+ effect() {
18
+ const css = this.sheet.getStyleTags();
19
+ this.result.chunksMap.css += css;
20
+ }
21
+ constructor(result) {
22
+ _define_property._(this, "sheet", new _styledcomponents.ServerStyleSheet());
23
+ _define_property._(this, "result", void 0);
24
+ this.result = result;
25
+ }
26
+ }
27
+ function createStyledCollector(result) {
28
+ return new StyledCollector(result);
29
+ }
@@ -57,7 +57,7 @@ export var documentPlugin = function() {
57
57
  }
58
58
  return function() {
59
59
  var _ref2 = _async_to_generator(function(param) {
60
- var htmlWebpackPlugin, _tsConfig, _partialsByEntrypoint, config, documentParams, tempTsConfigFile, userTsConfigFilePath, tsConfig, err, htmlOutputFile, Document, HTMLElement, html, partialsByEntrypoint, scripts, partialsTop, partialsHead, partialsBody, links, metas, nonce, nonceAttr, finalHtml;
60
+ var htmlWebpackPlugin, _tsConfig, _partialsByEntrypoint, config, documentParams, tempTsConfigFile, userTsConfigFilePath, tsConfig, err, htmlOutputFile, Document, HTMLElement, html, partialsByEntrypoint, scripts, partialsContent, links, metas, nonce, nonceAttr, finalHtml;
61
61
  return _ts_generator(this, function(_state2) {
62
62
  switch (_state2.label) {
63
63
  case 0:
@@ -163,12 +163,17 @@ export var documentPlugin = function() {
163
163
  }).join(""),
164
164
  htmlWebpackPlugin.tags.bodyTags.toString()
165
165
  ].join("");
166
+ partialsContent = {
167
+ partialsTop: "",
168
+ partialsHead: "",
169
+ partialsBody: ""
170
+ };
166
171
  if ((_partialsByEntrypoint = partialsByEntrypoint) === null || _partialsByEntrypoint === void 0 ? void 0 : _partialsByEntrypoint[entryName]) {
167
- partialsTop = partialsByEntrypoint[entryName].top.join("\n");
168
- partialsHead = partialsByEntrypoint[entryName].head.join("\n");
169
- partialsBody = partialsByEntrypoint[entryName].body.join("\n");
170
- html = html.replace(TOP_PARTICALS_SEPARATOR, partialsTop).replace(HEAD_PARTICALS_SEPARATOR, partialsHead).replace(BODY_PARTICALS_SEPARATOR, partialsBody);
172
+ partialsContent.partialsTop = partialsByEntrypoint[entryName].top.join("\n");
173
+ partialsContent.partialsHead = partialsByEntrypoint[entryName].head.join("\n");
174
+ partialsContent.partialsBody = partialsByEntrypoint[entryName].body.join("\n");
171
175
  }
176
+ html = html.replace(TOP_PARTICALS_SEPARATOR, partialsContent.partialsTop).replace(HEAD_PARTICALS_SEPARATOR, partialsContent.partialsHead).replace(BODY_PARTICALS_SEPARATOR, partialsContent.partialsBody);
172
177
  links = [
173
178
  htmlWebpackPlugin.tags.headTags.filter(function(item) {
174
179
  return item.tagName === "link";
@@ -43,6 +43,9 @@ export var ssr = function() {
43
43
  var request = context.ssrContext.request;
44
44
  context.ssrContext.request = formatServer(request);
45
45
  context.ssrContext.mode = config.mode;
46
+ if (!context.ssrContext.htmlModifiers) {
47
+ context.ssrContext.htmlModifiers = [];
48
+ }
46
49
  return next({
47
50
  context: context
48
51
  });
@@ -0,0 +1,29 @@
1
+ export function buildHtml(template, callbacks) {
2
+ return callbacks.reduce(function(tmp, cb) {
3
+ return cb(tmp);
4
+ }, template);
5
+ }
6
+ export function createReplaceHtml(html) {
7
+ var HTML_REG = /<!--<\?-\s*html\s*\?>-->/;
8
+ return function(template) {
9
+ return template.replace(HTML_REG, html);
10
+ };
11
+ }
12
+ export function createReplaceSSRDataScript(data) {
13
+ var SSR_DATA_REG = /<!--<\?-\s*SSRDataScript\s*\?>-->/;
14
+ return function(template) {
15
+ return template.replace(SSR_DATA_REG, data);
16
+ };
17
+ }
18
+ export function createReplaceChunkJs(js) {
19
+ var CHUNK_JS_REG = /<!--<\?-\s*chunksMap\.js\s*\?>-->/;
20
+ return function(template) {
21
+ return template.replace(CHUNK_JS_REG, js);
22
+ };
23
+ }
24
+ export function createReplaceChunkCss(css) {
25
+ var CHUNK_CSS_REG = /<!--<\?-\s*chunksMap\.css\s*\?>-->/;
26
+ return function(template) {
27
+ return template.replace(CHUNK_CSS_REG, css);
28
+ };
29
+ }
@@ -3,9 +3,9 @@ import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
3
3
  import { _ as _create_class } from "@swc/helpers/_/_create_class";
4
4
  import { _ as _define_property } from "@swc/helpers/_/_define_property";
5
5
  import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
6
+ import { _ as _to_consumable_array } from "@swc/helpers/_/_to_consumable_array";
6
7
  import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
7
8
  import React from "react";
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
11
  import { time } from "@modern-js/utils/universal/time";
@@ -15,10 +15,10 @@ import { RenderLevel } from "../types";
15
15
  import prefetch from "../../prefetch";
16
16
  import { ROUTER_DATA_JSON_ID, SSR_DATA_JSON_ID, attributesToString } from "../utils";
17
17
  import { SSRErrors, SSRTimings, createSSRTracker } from "../tracker";
18
- import { toFragments } from "./template";
19
- import { reduce } from "./reduce";
20
- import * as loadableRenderer from "./loadable";
21
- import * as styledComponentRenderer from "./styledComponent";
18
+ import { createLoadableCollector } from "./loadable";
19
+ import { createRender } from "./render";
20
+ import { createStyledCollector } from "./styledComponent";
21
+ import { buildHtml, createReplaceChunkCss, createReplaceChunkJs, createReplaceHtml, createReplaceSSRDataScript } from "./buildHtml";
22
22
  var buildTemplateData = function(context, data, renderLevel, tracker) {
23
23
  var request = context.request, enableUnsafeCtx = context.enableUnsafeCtx;
24
24
  var unsafeContext = {
@@ -51,20 +51,18 @@ var Entry = /* @__PURE__ */ function() {
51
51
  _define_property(this, "tracker", void 0);
52
52
  _define_property(this, "template", void 0);
53
53
  _define_property(this, "App", void 0);
54
- _define_property(this, "fragments", void 0);
55
54
  _define_property(this, "pluginConfig", void 0);
56
- _define_property(this, "host", void 0);
55
+ _define_property(this, "htmlModifiers", void 0);
57
56
  _define_property(this, "nonce", void 0);
58
57
  var ctx = options.ctx, config = options.config;
59
- var entryName = ctx.entryName, template = ctx.template, host = ctx.request.host, nonce = ctx.nonce;
60
- this.fragments = toFragments(template, entryName);
58
+ var entryName = ctx.entryName, template = ctx.template, nonce = ctx.nonce;
61
59
  this.template = template;
62
60
  this.entryName = entryName;
63
- this.host = host;
64
61
  this.App = options.App;
65
62
  this.pluginConfig = config;
66
63
  this.tracker = createSSRTracker(ctx);
67
64
  this.metrics = ctx.metrics;
65
+ this.htmlModifiers = ctx.htmlModifiers;
68
66
  this.nonce = nonce;
69
67
  this.result = {
70
68
  renderLevel: RenderLevel.CLIENT_RENDER,
@@ -81,7 +79,7 @@ var Entry = /* @__PURE__ */ function() {
81
79
  value: function renderToHtml(context) {
82
80
  var _this = this;
83
81
  return _async_to_generator(function() {
84
- var _ssrContext_redirection, _ssrContext_redirection1, _ssrContext_redirection2, ssrContext, prefetchData, routerContext, routerData, html, templateData, SSRData, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, fragment, helmetData;
82
+ var _ssrContext_redirection, _ssrContext_redirection1, _ssrContext_redirection2, ssrContext, prefetchData, routerContext, routerData, templateData, ssrDataScripts, html, helmetData;
85
83
  return _ts_generator(this, function(_state) {
86
84
  switch (_state.label) {
87
85
  case 0:
@@ -118,33 +116,14 @@ var Entry = /* @__PURE__ */ function() {
118
116
  loaderData: routerContext.loaderData,
119
117
  errors: serializeErrors(routerContext.errors)
120
118
  } : void 0;
121
- html = "";
122
119
  templateData = buildTemplateData(ssrContext, prefetchData, _this.result.renderLevel, _this.tracker);
123
- SSRData = _this.getSSRDataScript(templateData, routerData);
124
- _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
125
- try {
126
- for (_iterator = _this.fragments[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
127
- fragment = _step.value;
128
- if (fragment.isVariable && fragment.content === "SSRDataScript") {
129
- html += fragment.getValue(SSRData);
130
- } else {
131
- html += fragment.getValue(_this.result);
132
- }
133
- }
134
- } catch (err) {
135
- _didIteratorError = true;
136
- _iteratorError = err;
137
- } finally {
138
- try {
139
- if (!_iteratorNormalCompletion && _iterator.return != null) {
140
- _iterator.return();
141
- }
142
- } finally {
143
- if (_didIteratorError) {
144
- throw _iteratorError;
145
- }
146
- }
147
- }
120
+ ssrDataScripts = _this.getSSRDataScript(templateData, routerData);
121
+ html = buildHtml(_this.template, [
122
+ createReplaceChunkCss(_this.result.chunksMap.css),
123
+ createReplaceChunkJs(_this.result.chunksMap.js),
124
+ createReplaceHtml(_this.result.html || ""),
125
+ createReplaceSSRDataScript(ssrDataScripts)
126
+ ].concat(_to_consumable_array(_this.htmlModifiers)));
148
127
  helmetData = ReactHelmet.renderStatic();
149
128
  return [
150
129
  2,
@@ -216,22 +195,14 @@ var Entry = /* @__PURE__ */ function() {
216
195
  ssr: true
217
196
  })
218
197
  });
219
- var renderContext = {
198
+ html = createRender(App).addCollector(createStyledCollector(this.result)).addCollector(createLoadableCollector({
220
199
  stats: ssrContext.loadableStats,
221
- host: this.host,
222
200
  result: this.result,
223
201
  entryName: this.entryName,
224
202
  config: this.pluginConfig,
225
203
  nonce: this.nonce,
226
204
  template: this.template
227
- };
228
- html = reduce(App, renderContext, [
229
- styledComponentRenderer.toHtml,
230
- loadableRenderer.toHtml,
231
- function(jsx) {
232
- return ReactDomServer.renderToString(jsx);
233
- }
234
- ]);
205
+ })).finish();
235
206
  var cost = end();
236
207
  this.tracker.trackTiming(SSRTimings.SSR_RENDER_HTML, cost);
237
208
  this.result.renderLevel = RenderLevel.SERVER_RENDER;
@@ -254,9 +225,7 @@ var Entry = /* @__PURE__ */ function() {
254
225
  var serializedRouterData = serializeJson(routerData);
255
226
  ssrDataScripts += useInlineScript ? "\n<script".concat(attrsStr, ">window._ROUTER_DATA = ").concat(serializedRouterData, "</script>") : '\n<script type="application/json" id="'.concat(ROUTER_DATA_JSON_ID, '">').concat(serializedRouterData, "</script>");
256
227
  }
257
- return {
258
- SSRDataScript: ssrDataScripts
259
- };
228
+ return ssrDataScripts;
260
229
  }
261
230
  }
262
231
  ]);