@modern-js/runtime 2.32.0 → 2.32.2-alpha.1

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 (53) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/cjs/document/cli/index.js +9 -4
  3. package/dist/cjs/ssr/serverRender/renderToString/buildHtml.js +47 -0
  4. package/dist/cjs/ssr/serverRender/renderToString/entry.js +14 -28
  5. package/dist/cjs/ssr/serverRender/renderToString/loadable.js +57 -40
  6. package/dist/cjs/ssr/serverRender/renderToString/render.js +35 -0
  7. package/dist/cjs/ssr/serverRender/renderToString/styledComponent.js +20 -9
  8. package/dist/esm/document/cli/index.js +10 -5
  9. package/dist/esm/ssr/serverRender/renderToString/buildHtml.js +29 -0
  10. package/dist/esm/ssr/serverRender/renderToString/entry.js +15 -47
  11. package/dist/esm/ssr/serverRender/renderToString/loadable.js +86 -56
  12. package/dist/esm/ssr/serverRender/renderToString/render.js +39 -0
  13. package/dist/esm/ssr/serverRender/renderToString/styledComponent.js +31 -7
  14. package/dist/esm-node/document/cli/index.js +9 -4
  15. package/dist/esm-node/ssr/cli/loadable-bundler-plugin.js +2 -2
  16. package/dist/esm-node/ssr/serverRender/renderToString/buildHtml.js +19 -0
  17. package/dist/esm-node/ssr/serverRender/renderToString/entry.js +14 -27
  18. package/dist/esm-node/ssr/serverRender/renderToString/loadable.js +55 -38
  19. package/dist/esm-node/ssr/serverRender/renderToString/render.js +24 -0
  20. package/dist/esm-node/ssr/serverRender/renderToString/styledComponent.js +18 -7
  21. package/dist/types/ssr/serverRender/renderToStream/template.d.ts +4 -1
  22. package/dist/types/ssr/serverRender/renderToString/buildHtml.d.ts +6 -0
  23. package/dist/types/ssr/serverRender/renderToString/entry.d.ts +0 -1
  24. package/dist/types/ssr/serverRender/renderToString/loadable.d.ts +21 -2
  25. package/dist/types/ssr/serverRender/renderToString/render.d.ts +14 -0
  26. package/dist/types/ssr/serverRender/renderToString/styledComponent.d.ts +15 -2
  27. package/dist/types/ssr/serverRender/renderToString/type.d.ts +0 -12
  28. package/dist/types/state/types.d.ts +1 -1
  29. package/package.json +9 -9
  30. package/dist/cjs/ssr/serverRender/constants.js +0 -16
  31. package/dist/cjs/ssr/serverRender/renderToStream/loadable.js +0 -30
  32. package/dist/cjs/ssr/serverRender/renderToStream/styledComponent.js +0 -19
  33. package/dist/cjs/ssr/serverRender/renderToStream/type.js +0 -4
  34. package/dist/cjs/ssr/serverRender/renderToString/reduce.js +0 -17
  35. package/dist/cjs/ssr/serverRender/renderToString/template.js +0 -79
  36. package/dist/esm/ssr/serverRender/constants.js +0 -6
  37. package/dist/esm/ssr/serverRender/renderToStream/loadable.js +0 -21
  38. package/dist/esm/ssr/serverRender/renderToStream/styledComponent.js +0 -10
  39. package/dist/esm/ssr/serverRender/renderToStream/type.js +0 -1
  40. package/dist/esm/ssr/serverRender/renderToString/reduce.js +0 -9
  41. package/dist/esm/ssr/serverRender/renderToString/template.js +0 -81
  42. package/dist/esm-node/ssr/serverRender/constants.js +0 -6
  43. package/dist/esm-node/ssr/serverRender/renderToStream/loadable.js +0 -20
  44. package/dist/esm-node/ssr/serverRender/renderToStream/styledComponent.js +0 -9
  45. package/dist/esm-node/ssr/serverRender/renderToStream/type.js +0 -1
  46. package/dist/esm-node/ssr/serverRender/renderToString/reduce.js +0 -5
  47. package/dist/esm-node/ssr/serverRender/renderToString/template.js +0 -60
  48. package/dist/types/ssr/serverRender/constants.d.ts +0 -5
  49. package/dist/types/ssr/serverRender/renderToStream/loadable.d.ts +0 -16
  50. package/dist/types/ssr/serverRender/renderToStream/styledComponent.d.ts +0 -12
  51. package/dist/types/ssr/serverRender/renderToStream/type.d.ts +0 -4
  52. package/dist/types/ssr/serverRender/renderToString/reduce.d.ts +0 -3
  53. package/dist/types/ssr/serverRender/renderToString/template.d.ts +0 -14
@@ -1,3 +1,6 @@
1
+ import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
2
+ import { _ as _create_class } from "@swc/helpers/_/_create_class";
3
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
1
4
  import { ChunkExtractor } from "@loadable/server";
2
5
  import { attributesToString, getLoadableScripts } from "../utils";
3
6
  var extname = function(uri) {
@@ -7,64 +10,91 @@ var extname = function(uri) {
7
10
  }
8
11
  return ".".concat((_uri = uri) === null || _uri === void 0 ? void 0 : _uri.split(".").pop()) || "";
9
12
  };
10
- export var toHtml = function(jsx, renderer, next) {
11
- var stats = renderer.stats, chunksMap = renderer.result.chunksMap, _renderer_config = renderer.config, config = _renderer_config === void 0 ? {} : _renderer_config, nonce = renderer.nonce;
12
- if (!stats || chunksMap.js) {
13
- return next(jsx);
13
+ var LoadableCollector = /* @__PURE__ */ function() {
14
+ "use strict";
15
+ function LoadableCollector2(options) {
16
+ _class_call_check(this, LoadableCollector2);
17
+ _define_property(this, "options", void 0);
18
+ _define_property(this, "extractor", void 0);
19
+ this.options = options;
14
20
  }
15
- var extractor = new ChunkExtractor({
16
- stats: stats,
17
- entrypoints: [
18
- renderer.entryName
19
- ]
20
- });
21
- var html = next(extractor.collectChunks(jsx));
22
- var chunks = extractor.getChunkAssets(extractor.chunks);
23
- chunksMap.js = (chunksMap.js || "") + getLoadableScripts(extractor);
24
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
25
- try {
26
- for (var _iterator = chunks[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
27
- var v = _step.value;
28
- var fileType = extname(v.url).slice(1);
29
- var attributes = {};
30
- var crossorigin = config.crossorigin, _config_scriptLoading = config.scriptLoading, scriptLoading = _config_scriptLoading === void 0 ? "defer" : _config_scriptLoading;
31
- if (crossorigin) {
32
- attributes.crossorigin = crossorigin === true ? "anonymous" : crossorigin;
33
- }
34
- switch (scriptLoading) {
35
- case "defer":
36
- attributes.defer = true;
37
- break;
38
- case "module":
39
- attributes.type = "module";
40
- break;
41
- default:
42
- }
43
- if (fileType === "js") {
44
- var jsChunkReg = new RegExp('<script .*src="'.concat(v.url, '".*>'));
45
- if (!jsChunkReg.test(renderer.template)) {
46
- attributes.nonce = nonce;
47
- var attrsStr = attributesToString(attributes);
48
- chunksMap[fileType] += "<script".concat(attrsStr, ' src="').concat(v.url, '"></script>');
21
+ _create_class(LoadableCollector2, [
22
+ {
23
+ key: "collect",
24
+ value: function collect(comopnent) {
25
+ var _this_options = this.options, stats = _this_options.stats, entryName = _this_options.entryName;
26
+ if (!stats) {
27
+ return comopnent;
49
28
  }
50
- } else if (fileType === "css") {
51
- var attrsStr1 = attributesToString(attributes);
52
- chunksMap[fileType] += "<link".concat(attrsStr1, ' href="').concat(v.url, '" rel="stylesheet" />');
53
- }
54
- }
55
- } catch (err) {
56
- _didIteratorError = true;
57
- _iteratorError = err;
58
- } finally {
59
- try {
60
- if (!_iteratorNormalCompletion && _iterator.return != null) {
61
- _iterator.return();
29
+ this.extractor = new ChunkExtractor({
30
+ stats: stats,
31
+ entrypoints: [
32
+ entryName
33
+ ]
34
+ });
35
+ return this.extractor.collectChunks(comopnent);
62
36
  }
63
- } finally {
64
- if (_didIteratorError) {
65
- throw _iteratorError;
37
+ },
38
+ {
39
+ key: "effect",
40
+ value: function effect() {
41
+ if (!this.extractor) {
42
+ return;
43
+ }
44
+ var _this_options = this.options, chunksMap = _this_options.result.chunksMap, config = _this_options.config, template = _this_options.template, nonce = _this_options.nonce;
45
+ var extractor = this.extractor;
46
+ var chunks = extractor.getChunkAssets(extractor.chunks);
47
+ chunksMap.js = (chunksMap.js || "") + getLoadableScripts(extractor);
48
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
49
+ try {
50
+ for (var _iterator = chunks[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
51
+ var v = _step.value;
52
+ var fileType = extname(v.url).slice(1);
53
+ var attributes = {};
54
+ var crossorigin = config.crossorigin, _config_scriptLoading = config.scriptLoading, scriptLoading = _config_scriptLoading === void 0 ? "defer" : _config_scriptLoading;
55
+ if (crossorigin) {
56
+ attributes.crossorigin = crossorigin === true ? "anonymous" : crossorigin;
57
+ }
58
+ switch (scriptLoading) {
59
+ case "defer":
60
+ attributes.defer = true;
61
+ break;
62
+ case "module":
63
+ attributes.type = "module";
64
+ break;
65
+ default:
66
+ }
67
+ if (fileType === "js") {
68
+ var jsChunkReg = new RegExp('<script .*src="'.concat(v.url, '".*>'));
69
+ if (!jsChunkReg.test(template)) {
70
+ attributes.nonce = nonce;
71
+ var attrsStr = attributesToString(attributes);
72
+ chunksMap[fileType] += "<script".concat(attrsStr, ' src="').concat(v.url, '"></script>');
73
+ }
74
+ } else if (fileType === "css") {
75
+ var attrsStr1 = attributesToString(attributes);
76
+ chunksMap[fileType] += "<link".concat(attrsStr1, ' href="').concat(v.url, '" rel="stylesheet" />');
77
+ }
78
+ }
79
+ } catch (err) {
80
+ _didIteratorError = true;
81
+ _iteratorError = err;
82
+ } finally {
83
+ try {
84
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
85
+ _iterator.return();
86
+ }
87
+ } finally {
88
+ if (_didIteratorError) {
89
+ throw _iteratorError;
90
+ }
91
+ }
92
+ }
66
93
  }
67
94
  }
68
- }
69
- return html;
70
- };
95
+ ]);
96
+ return LoadableCollector2;
97
+ }();
98
+ export function createLoadableCollector(options) {
99
+ return new LoadableCollector(options);
100
+ }
@@ -0,0 +1,39 @@
1
+ import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
2
+ import { _ as _create_class } from "@swc/helpers/_/_create_class";
3
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
4
+ import ReactDomServer from "react-dom/server";
5
+ var Render = /* @__PURE__ */ function() {
6
+ "use strict";
7
+ function Render2(App) {
8
+ _class_call_check(this, Render2);
9
+ _define_property(this, "App", void 0);
10
+ _define_property(this, "collectors", []);
11
+ this.App = App;
12
+ }
13
+ _create_class(Render2, [
14
+ {
15
+ key: "addCollector",
16
+ value: function addCollector(collector) {
17
+ this.collectors.push(collector);
18
+ return this;
19
+ }
20
+ },
21
+ {
22
+ key: "finish",
23
+ value: function finish() {
24
+ var App = this.collectors.reduce(function(pre, collector) {
25
+ return collector.collect(pre);
26
+ }, this.App);
27
+ var html = ReactDomServer.renderToString(App);
28
+ this.collectors.forEach(function(component) {
29
+ component.effect();
30
+ });
31
+ return html;
32
+ }
33
+ }
34
+ ]);
35
+ return Render2;
36
+ }();
37
+ export function createRender(App) {
38
+ return new Render(App);
39
+ }
@@ -1,8 +1,32 @@
1
+ import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
2
+ import { _ as _create_class } from "@swc/helpers/_/_create_class";
3
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
1
4
  import { ServerStyleSheet } from "styled-components";
2
- export var toHtml = function(jsx, renderer, next) {
3
- var sheet = new ServerStyleSheet();
4
- var html = next(sheet.collectStyles(jsx));
5
- var css = sheet.getStyleTags();
6
- renderer.result.chunksMap.css += css;
7
- return html;
8
- };
5
+ var StyledCollector = /* @__PURE__ */ function() {
6
+ "use strict";
7
+ function StyledCollector2(result) {
8
+ _class_call_check(this, StyledCollector2);
9
+ _define_property(this, "sheet", new ServerStyleSheet());
10
+ _define_property(this, "result", void 0);
11
+ this.result = result;
12
+ }
13
+ _create_class(StyledCollector2, [
14
+ {
15
+ key: "collect",
16
+ value: function collect(comopnent) {
17
+ return this.sheet.collectStyles(comopnent);
18
+ }
19
+ },
20
+ {
21
+ key: "effect",
22
+ value: function effect() {
23
+ var css = this.sheet.getStyleTags();
24
+ this.result.chunksMap.css += css;
25
+ }
26
+ }
27
+ ]);
28
+ return StyledCollector2;
29
+ }();
30
+ export function createStyledCollector(result) {
31
+ return new StyledCollector(result);
32
+ }
@@ -115,12 +115,17 @@ export const documentPlugin = () => ({
115
115
  htmlWebpackPlugin.tags.headTags.filter((item) => item.tagName === "script").join(""),
116
116
  htmlWebpackPlugin.tags.bodyTags.toString()
117
117
  ].join("");
118
+ const partialsContent = {
119
+ partialsTop: "",
120
+ partialsHead: "",
121
+ partialsBody: ""
122
+ };
118
123
  if ((_partialsByEntrypoint = partialsByEntrypoint) === null || _partialsByEntrypoint === void 0 ? void 0 : _partialsByEntrypoint[entryName]) {
119
- const partialsTop = partialsByEntrypoint[entryName].top.join("\n");
120
- const partialsHead = partialsByEntrypoint[entryName].head.join("\n");
121
- const partialsBody = partialsByEntrypoint[entryName].body.join("\n");
122
- html = html.replace(TOP_PARTICALS_SEPARATOR, partialsTop).replace(HEAD_PARTICALS_SEPARATOR, partialsHead).replace(BODY_PARTICALS_SEPARATOR, partialsBody);
124
+ partialsContent.partialsTop = partialsByEntrypoint[entryName].top.join("\n");
125
+ partialsContent.partialsHead = partialsByEntrypoint[entryName].head.join("\n");
126
+ partialsContent.partialsBody = partialsByEntrypoint[entryName].body.join("\n");
123
127
  }
128
+ html = html.replace(TOP_PARTICALS_SEPARATOR, partialsContent.partialsTop).replace(HEAD_PARTICALS_SEPARATOR, partialsContent.partialsHead).replace(BODY_PARTICALS_SEPARATOR, partialsContent.partialsBody);
124
129
  const links = [
125
130
  htmlWebpackPlugin.tags.headTags.filter((item) => item.tagName === "link").join("")
126
131
  ].join("");
@@ -71,7 +71,7 @@ class LoadablePlugin {
71
71
  const outputFile = path.resolve(outputFolder || "", this.opts.filename);
72
72
  fs.outputFileSync(outputFile, manifest);
73
73
  }
74
- constructor({ filename = "loadable-stats.json", path: path1, writeToDisk, outputAsset = true, chunkLoadingGlobal = "__LOADABLE_LOADED_CHUNKS__" } = {
74
+ constructor({ filename = "loadable-stats.json", path: path2, writeToDisk, outputAsset = true, chunkLoadingGlobal = "__LOADABLE_LOADED_CHUNKS__" } = {
75
75
  filename: "loadable-stats.json",
76
76
  outputAsset: true,
77
77
  chunkLoadingGlobal: "__LOADABLE_LOADED_CHUNKS__"
@@ -80,7 +80,7 @@ class LoadablePlugin {
80
80
  _define_property(this, "compiler", void 0);
81
81
  this.opts = {
82
82
  filename,
83
- path: path1,
83
+ path: path2,
84
84
  writeToDisk,
85
85
  outputAsset,
86
86
  chunkLoadingGlobal
@@ -0,0 +1,19 @@
1
+ export function buildHtml(template, callbacks) {
2
+ return callbacks.reduce((tmp, cb) => cb(tmp), template);
3
+ }
4
+ export function createReplaceHtml(html) {
5
+ const HTML_REG = /<!--<\?-\s*html\s*\?>-->/;
6
+ return (template) => template.replace(HTML_REG, html);
7
+ }
8
+ export function createReplaceSSRDataScript(data) {
9
+ const SSR_DATA_REG = /<!--<\?-\s*SSRDataScript\s*\?>-->/;
10
+ return (template) => template.replace(SSR_DATA_REG, data);
11
+ }
12
+ export function createReplaceChunkJs(js) {
13
+ const CHUNK_JS_REG = /<!--<\?-\s*chunksMap\.js\s*\?>-->/;
14
+ return (template) => template.replace(CHUNK_JS_REG, js);
15
+ }
16
+ export function createReplaceChunkCss(css) {
17
+ const CHUNK_CSS_REG = /<!--<\?-\s*chunksMap\.css\s*\?>-->/;
18
+ return (template) => template.replace(CHUNK_CSS_REG, css);
19
+ }
@@ -1,6 +1,5 @@
1
1
  import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
2
  import React from "react";
3
- import ReactDomServer from "react-dom/server";
4
3
  import { serializeJson } from "@modern-js/utils/runtime-node";
5
4
  import ReactHelmet from "react-helmet";
6
5
  import { time } from "@modern-js/utils/universal/time";
@@ -10,10 +9,10 @@ import { RenderLevel } from "../types";
10
9
  import prefetch from "../../prefetch";
11
10
  import { ROUTER_DATA_JSON_ID, SSR_DATA_JSON_ID, attributesToString } from "../utils";
12
11
  import { SSRErrors, SSRTimings, createSSRTracker } from "../tracker";
13
- import { toFragments } from "./template";
14
- import { reduce } from "./reduce";
15
- import * as loadableRenderer from "./loadable";
16
- import * as styledComponentRenderer from "./styledComponent";
12
+ import { createLoadableCollector } from "./loadable";
13
+ import { createRender } from "./render";
14
+ import { createStyledCollector } from "./styledComponent";
15
+ import { buildHtml, createReplaceChunkCss, createReplaceChunkJs, createReplaceHtml, createReplaceSSRDataScript } from "./buildHtml";
17
16
  const buildTemplateData = (context, data, renderLevel, tracker) => {
18
17
  const { request, enableUnsafeCtx } = context;
19
18
  const unsafeContext = {
@@ -59,16 +58,14 @@ class Entry {
59
58
  loaderData: routerContext.loaderData,
60
59
  errors: serializeErrors(routerContext.errors)
61
60
  } : void 0;
62
- let html = "";
63
61
  const templateData = buildTemplateData(ssrContext, prefetchData, this.result.renderLevel, this.tracker);
64
- const SSRData = this.getSSRDataScript(templateData, routerData);
65
- for (const fragment of this.fragments) {
66
- if (fragment.isVariable && fragment.content === "SSRDataScript") {
67
- html += fragment.getValue(SSRData);
68
- } else {
69
- html += fragment.getValue(this.result);
70
- }
71
- }
62
+ const ssrDataScripts = this.getSSRDataScript(templateData, routerData);
63
+ const html = buildHtml(this.template, [
64
+ createReplaceChunkCss(this.result.chunksMap.css),
65
+ createReplaceChunkJs(this.result.chunksMap.js),
66
+ createReplaceHtml(this.result.html || ""),
67
+ createReplaceSSRDataScript(ssrDataScripts)
68
+ ]);
72
69
  const helmetData = ReactHelmet.renderStatic();
73
70
  return helmetData ? helmetReplace(html, helmetData) : html;
74
71
  }
@@ -96,20 +93,14 @@ class Entry {
96
93
  ssr: true
97
94
  })
98
95
  });
99
- const renderContext = {
96
+ html = createRender(App).addCollector(createStyledCollector(this.result)).addCollector(createLoadableCollector({
100
97
  stats: ssrContext.loadableStats,
101
- host: this.host,
102
98
  result: this.result,
103
99
  entryName: this.entryName,
104
100
  config: this.pluginConfig,
105
101
  nonce: this.nonce,
106
102
  template: this.template
107
- };
108
- html = reduce(App, renderContext, [
109
- styledComponentRenderer.toHtml,
110
- loadableRenderer.toHtml,
111
- (jsx) => ReactDomServer.renderToString(jsx)
112
- ]);
103
+ })).finish();
113
104
  const cost = end();
114
105
  this.tracker.trackTiming(SSRTimings.SSR_RENDER_HTML, cost);
115
106
  this.result.renderLevel = RenderLevel.SERVER_RENDER;
@@ -131,9 +122,7 @@ class Entry {
131
122
  <script${attrsStr}>window._ROUTER_DATA = ${serializedRouterData}</script>` : `
132
123
  <script type="application/json" id="${ROUTER_DATA_JSON_ID}">${serializedRouterData}</script>`;
133
124
  }
134
- return {
135
- SSRDataScript: ssrDataScripts
136
- };
125
+ return ssrDataScripts;
137
126
  }
138
127
  constructor(options) {
139
128
  _define_property(this, "entryName", void 0);
@@ -142,13 +131,11 @@ class Entry {
142
131
  _define_property(this, "tracker", void 0);
143
132
  _define_property(this, "template", void 0);
144
133
  _define_property(this, "App", void 0);
145
- _define_property(this, "fragments", void 0);
146
134
  _define_property(this, "pluginConfig", void 0);
147
135
  _define_property(this, "host", void 0);
148
136
  _define_property(this, "nonce", void 0);
149
137
  const { ctx, config } = options;
150
138
  const { entryName, template, request: { host }, nonce } = ctx;
151
- this.fragments = toFragments(template, entryName);
152
139
  this.template = template;
153
140
  this.entryName = entryName;
154
141
  this.host = host;
@@ -1,3 +1,4 @@
1
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
1
2
  import { ChunkExtractor } from "@loadable/server";
2
3
  import { attributesToString, getLoadableScripts } from "../utils";
3
4
  const extname = (uri) => {
@@ -7,47 +8,63 @@ const extname = (uri) => {
7
8
  }
8
9
  return `.${(_uri = uri) === null || _uri === void 0 ? void 0 : _uri.split(".").pop()}` || "";
9
10
  };
10
- export const toHtml = (jsx, renderer, next) => {
11
- const { stats, result: { chunksMap }, config = {}, nonce } = renderer;
12
- if (!stats || chunksMap.js) {
13
- return next(jsx);
14
- }
15
- const extractor = new ChunkExtractor({
16
- stats,
17
- entrypoints: [
18
- renderer.entryName
19
- ]
20
- });
21
- const html = next(extractor.collectChunks(jsx));
22
- const chunks = extractor.getChunkAssets(extractor.chunks);
23
- chunksMap.js = (chunksMap.js || "") + getLoadableScripts(extractor);
24
- for (const v of chunks) {
25
- const fileType = extname(v.url).slice(1);
26
- const attributes = {};
27
- const { crossorigin, scriptLoading = "defer" } = config;
28
- if (crossorigin) {
29
- attributes.crossorigin = crossorigin === true ? "anonymous" : crossorigin;
11
+ class LoadableCollector {
12
+ collect(comopnent) {
13
+ const { stats, entryName } = this.options;
14
+ if (!stats) {
15
+ return comopnent;
30
16
  }
31
- switch (scriptLoading) {
32
- case "defer":
33
- attributes.defer = true;
34
- break;
35
- case "module":
36
- attributes.type = "module";
37
- break;
38
- default:
17
+ this.extractor = new ChunkExtractor({
18
+ stats,
19
+ entrypoints: [
20
+ entryName
21
+ ]
22
+ });
23
+ return this.extractor.collectChunks(comopnent);
24
+ }
25
+ effect() {
26
+ if (!this.extractor) {
27
+ return;
39
28
  }
40
- if (fileType === "js") {
41
- const jsChunkReg = new RegExp(`<script .*src="${v.url}".*>`);
42
- if (!jsChunkReg.test(renderer.template)) {
43
- attributes.nonce = nonce;
29
+ const { result: { chunksMap }, config, template, nonce } = this.options;
30
+ const { extractor } = this;
31
+ const chunks = extractor.getChunkAssets(extractor.chunks);
32
+ chunksMap.js = (chunksMap.js || "") + getLoadableScripts(extractor);
33
+ for (const v of chunks) {
34
+ const fileType = extname(v.url).slice(1);
35
+ const attributes = {};
36
+ const { crossorigin, scriptLoading = "defer" } = config;
37
+ if (crossorigin) {
38
+ attributes.crossorigin = crossorigin === true ? "anonymous" : crossorigin;
39
+ }
40
+ switch (scriptLoading) {
41
+ case "defer":
42
+ attributes.defer = true;
43
+ break;
44
+ case "module":
45
+ attributes.type = "module";
46
+ break;
47
+ default:
48
+ }
49
+ if (fileType === "js") {
50
+ const jsChunkReg = new RegExp(`<script .*src="${v.url}".*>`);
51
+ if (!jsChunkReg.test(template)) {
52
+ attributes.nonce = nonce;
53
+ const attrsStr = attributesToString(attributes);
54
+ chunksMap[fileType] += `<script${attrsStr} src="${v.url}"></script>`;
55
+ }
56
+ } else if (fileType === "css") {
44
57
  const attrsStr = attributesToString(attributes);
45
- chunksMap[fileType] += `<script${attrsStr} src="${v.url}"></script>`;
58
+ chunksMap[fileType] += `<link${attrsStr} href="${v.url}" rel="stylesheet" />`;
46
59
  }
47
- } else if (fileType === "css") {
48
- const attrsStr = attributesToString(attributes);
49
- chunksMap[fileType] += `<link${attrsStr} href="${v.url}" rel="stylesheet" />`;
50
60
  }
51
61
  }
52
- return html;
53
- };
62
+ constructor(options) {
63
+ _define_property(this, "options", void 0);
64
+ _define_property(this, "extractor", void 0);
65
+ this.options = options;
66
+ }
67
+ }
68
+ export function createLoadableCollector(options) {
69
+ return new LoadableCollector(options);
70
+ }
@@ -0,0 +1,24 @@
1
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
+ import ReactDomServer from "react-dom/server";
3
+ class Render {
4
+ addCollector(collector) {
5
+ this.collectors.push(collector);
6
+ return this;
7
+ }
8
+ finish() {
9
+ const App = this.collectors.reduce((pre, collector) => collector.collect(pre), this.App);
10
+ const html = ReactDomServer.renderToString(App);
11
+ this.collectors.forEach((component) => {
12
+ component.effect();
13
+ });
14
+ return html;
15
+ }
16
+ constructor(App) {
17
+ _define_property(this, "App", void 0);
18
+ _define_property(this, "collectors", []);
19
+ this.App = App;
20
+ }
21
+ }
22
+ export function createRender(App) {
23
+ return new Render(App);
24
+ }
@@ -1,8 +1,19 @@
1
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
1
2
  import { ServerStyleSheet } from "styled-components";
2
- export const toHtml = (jsx, renderer, next) => {
3
- const sheet = new ServerStyleSheet();
4
- const html = next(sheet.collectStyles(jsx));
5
- const css = sheet.getStyleTags();
6
- renderer.result.chunksMap.css += css;
7
- return html;
8
- };
3
+ class StyledCollector {
4
+ collect(comopnent) {
5
+ return this.sheet.collectStyles(comopnent);
6
+ }
7
+ effect() {
8
+ const css = this.sheet.getStyleTags();
9
+ this.result.chunksMap.css += css;
10
+ }
11
+ constructor(result) {
12
+ _define_property(this, "sheet", new ServerStyleSheet());
13
+ _define_property(this, "result", void 0);
14
+ this.result = result;
15
+ }
16
+ }
17
+ export function createStyledCollector(result) {
18
+ return new StyledCollector(result);
19
+ }
@@ -1,3 +1,6 @@
1
1
  import { RenderLevel, RuntimeContext } from '../types';
2
- import { InjectTemplate } from './type';
2
+ export type InjectTemplate = {
3
+ shellBefore: string;
4
+ shellAfter: string;
5
+ };
3
6
  export declare const getTemplates: (context: RuntimeContext, renderLevel: RenderLevel) => InjectTemplate;
@@ -0,0 +1,6 @@
1
+ export type BuildHtmlCb = (tempalte: string) => string;
2
+ export declare function buildHtml(template: string, callbacks: BuildHtmlCb[]): string;
3
+ export declare function createReplaceHtml(html: string): BuildHtmlCb;
4
+ export declare function createReplaceSSRDataScript(data: string): BuildHtmlCb;
5
+ export declare function createReplaceChunkJs(js: string): BuildHtmlCb;
6
+ export declare function createReplaceChunkCss(css: string): BuildHtmlCb;
@@ -13,7 +13,6 @@ export default class Entry {
13
13
  tracker: SSRTracker;
14
14
  private readonly template;
15
15
  private readonly App;
16
- private readonly fragments;
17
16
  private readonly pluginConfig;
18
17
  private readonly host;
19
18
  private readonly nonce?;
@@ -1,2 +1,21 @@
1
- import { RenderHandler } from './type';
2
- export declare const toHtml: RenderHandler;
1
+ import { ReactElement } from 'react';
2
+ import { SSRPluginConfig } from '../types';
3
+ import { RenderResult } from './type';
4
+ import type { Collector } from './render';
5
+ declare class LoadableCollector implements Collector {
6
+ private options;
7
+ private extractor?;
8
+ constructor(options: LoadableCollectorOptions);
9
+ collect(comopnent: ReactElement): ReactElement;
10
+ effect(): void;
11
+ }
12
+ export interface LoadableCollectorOptions {
13
+ nonce?: string;
14
+ stats?: Record<string, any>;
15
+ template: string;
16
+ config: SSRPluginConfig;
17
+ entryName: string;
18
+ result: RenderResult;
19
+ }
20
+ export declare function createLoadableCollector(options: LoadableCollectorOptions): LoadableCollector;
21
+ export {};
@@ -0,0 +1,14 @@
1
+ import type { ReactElement } from 'react';
2
+ export interface Collector {
3
+ collect: (comopnent: ReactElement) => ReactElement;
4
+ effect: () => void;
5
+ }
6
+ declare class Render {
7
+ private App;
8
+ private collectors;
9
+ constructor(App: ReactElement);
10
+ addCollector(collector: Collector): this;
11
+ finish(): string;
12
+ }
13
+ export declare function createRender(App: ReactElement): Render;
14
+ export {};
@@ -1,2 +1,15 @@
1
- import { RenderHandler } from './type';
2
- export declare const toHtml: RenderHandler;
1
+ import { ServerStyleSheet } from 'styled-components';
2
+ import { ReactElement } from 'react';
3
+ import type { RenderResult } from './type';
4
+ import type { Collector } from './render';
5
+ declare class StyledCollector implements Collector {
6
+ sheet: ServerStyleSheet;
7
+ result: RenderResult;
8
+ constructor(result: RenderResult);
9
+ collect(comopnent: ReactElement): ReactElement<{
10
+ sheet: ServerStyleSheet;
11
+ }, string | import("react").JSXElementConstructor<any>>;
12
+ effect(): void;
13
+ }
14
+ export declare function createStyledCollector(result: RenderResult): StyledCollector;
15
+ export {};
@@ -1,6 +1,4 @@
1
- /// <reference types="react" />
2
1
  import type { BaseSSRServerContext } from '@modern-js/types';
3
- import type { SSRPluginConfig } from '../types';
4
2
  export declare enum RenderLevel {
5
3
  CLIENT_RENDER = 0,
6
4
  SERVER_PREFETCH = 1,
@@ -13,16 +11,6 @@ export type SSRServerContext = BaseSSRServerContext & {
13
11
  cookieMap: Record<string, string>;
14
12
  };
15
13
  };
16
- export interface RenderEntry {
17
- entryName: string;
18
- host: string;
19
- result: RenderResult;
20
- stats: Record<string, any>;
21
- config: SSRPluginConfig;
22
- template: string;
23
- nonce?: string;
24
- }
25
- export type RenderHandler = (jsx: React.ReactElement, renderer: RenderEntry, next: (jsx: React.ReactElement) => string) => string;
26
14
  export type RenderResult = {
27
15
  renderLevel: RenderLevel;
28
16
  html?: string;