@bleedingdev/modern-js-runtime 3.2.0-ultramodern.11 → 3.2.0-ultramodern.111

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 (229) hide show
  1. package/dist/cjs/boundary-debugger/index.js +303 -0
  2. package/dist/cjs/cache/index.js +9 -5
  3. package/dist/cjs/cli/alias.js +9 -5
  4. package/dist/cjs/cli/code.js +9 -5
  5. package/dist/cjs/cli/constants.js +20 -16
  6. package/dist/cjs/cli/entry.js +9 -5
  7. package/dist/cjs/cli/index.js +9 -5
  8. package/dist/cjs/cli/ssr/index.js +14 -20
  9. package/dist/cjs/cli/ssr/loadable-bundler-plugin.js +9 -5
  10. package/dist/cjs/cli/ssr/mode.js +12 -8
  11. package/dist/cjs/cli/template.js +9 -5
  12. package/dist/cjs/cli/template.server.js +10 -5
  13. package/dist/cjs/common.js +14 -10
  14. package/dist/cjs/core/browser/hydrate.js +9 -5
  15. package/dist/cjs/core/browser/index.js +9 -5
  16. package/dist/cjs/core/browser/withCallback.js +9 -5
  17. package/dist/cjs/core/compat/hooks.js +14 -10
  18. package/dist/cjs/core/compat/index.js +9 -5
  19. package/dist/cjs/core/compat/requestContext.js +13 -9
  20. package/dist/cjs/core/config.js +12 -8
  21. package/dist/cjs/core/constants.js +15 -10
  22. package/dist/cjs/core/context/index.js +9 -5
  23. package/dist/cjs/core/context/monitors/default.js +12 -8
  24. package/dist/cjs/core/context/monitors/index.js +9 -5
  25. package/dist/cjs/core/context/monitors/index.server.js +9 -5
  26. package/dist/cjs/core/context/request/index.js +12 -8
  27. package/dist/cjs/core/context/request/index.server.js +9 -5
  28. package/dist/cjs/core/context/response/index.js +15 -11
  29. package/dist/cjs/core/context/response/index.server.js +9 -5
  30. package/dist/cjs/core/context/runtime.js +9 -5
  31. package/dist/cjs/core/context/serverPayload/index.js +13 -9
  32. package/dist/cjs/core/context/serverPayload/index.server.js +9 -5
  33. package/dist/cjs/core/index.js +9 -5
  34. package/dist/cjs/core/plugin/index.js +9 -5
  35. package/dist/cjs/core/react/index.js +9 -5
  36. package/dist/cjs/core/react/wrapper.js +18 -8
  37. package/dist/cjs/core/server/constants.js +15 -11
  38. package/dist/cjs/core/server/federatedCss.js +51 -0
  39. package/dist/cjs/core/server/helmet.js +17 -7
  40. package/dist/cjs/core/server/index.js +9 -5
  41. package/dist/cjs/core/server/react/index.js +9 -5
  42. package/dist/cjs/core/server/react/no-ssr-cache/index.js +9 -5
  43. package/dist/cjs/core/server/react/nossr/index.js +9 -5
  44. package/dist/cjs/core/server/requestHandler.js +9 -5
  45. package/dist/cjs/core/server/scriptOrder.js +63 -0
  46. package/dist/cjs/core/server/server.js +9 -5
  47. package/dist/cjs/core/server/shared.js +12 -8
  48. package/dist/cjs/core/server/stream/afterTemplate.js +22 -10
  49. package/dist/cjs/core/server/stream/beforeTemplate.js +22 -25
  50. package/dist/cjs/core/server/stream/beforeTemplate.worker.js +102 -0
  51. package/dist/cjs/core/server/stream/createReadableStream.js +16 -7
  52. package/dist/cjs/core/server/stream/createReadableStream.worker.js +13 -7
  53. package/dist/cjs/core/server/stream/deferredScript.js +9 -5
  54. package/dist/cjs/core/server/stream/index.js +9 -5
  55. package/dist/cjs/core/server/stream/shared.js +12 -6
  56. package/dist/cjs/core/server/stream/template.js +9 -5
  57. package/dist/cjs/core/server/string/index.js +25 -14
  58. package/dist/cjs/core/server/string/loadable.js +83 -15
  59. package/dist/cjs/core/server/string/ssrData.js +9 -5
  60. package/dist/cjs/core/server/tracer.js +13 -9
  61. package/dist/cjs/core/server/utils.js +9 -5
  62. package/dist/cjs/document/Body.js +9 -5
  63. package/dist/cjs/document/Comment.js +9 -5
  64. package/dist/cjs/document/DocumentContext.js +9 -5
  65. package/dist/cjs/document/DocumentStructureContext.js +9 -5
  66. package/dist/cjs/document/Head.js +9 -5
  67. package/dist/cjs/document/Html.js +9 -5
  68. package/dist/cjs/document/Links.js +9 -5
  69. package/dist/cjs/document/Root.js +9 -5
  70. package/dist/cjs/document/Script.js +9 -5
  71. package/dist/cjs/document/Scripts.js +9 -5
  72. package/dist/cjs/document/Style.js +9 -5
  73. package/dist/cjs/document/Title.js +9 -5
  74. package/dist/cjs/document/cli/index.js +12 -6
  75. package/dist/cjs/document/constants.js +9 -5
  76. package/dist/cjs/document/index.js +9 -5
  77. package/dist/cjs/exports/config-routes.js +12 -8
  78. package/dist/cjs/exports/head.js +209 -10
  79. package/dist/cjs/exports/loadable.js +51 -12
  80. package/dist/cjs/exports/tanstack-router.js +320 -59
  81. package/dist/cjs/index.js +9 -5
  82. package/dist/cjs/internal.js +9 -5
  83. package/dist/cjs/react-server.js +9 -5
  84. package/dist/cjs/router/cli/code/getClientRoutes/getRoutes.js +9 -5
  85. package/dist/cjs/router/cli/code/getClientRoutes/index.js +9 -5
  86. package/dist/cjs/router/cli/code/getClientRoutes/utils.js +9 -5
  87. package/dist/cjs/router/cli/code/index.js +9 -5
  88. package/dist/cjs/router/cli/code/inspect.js +9 -5
  89. package/dist/cjs/router/cli/code/makeLegalIdentifier.js +12 -8
  90. package/dist/cjs/router/cli/code/nestedRoutes.js +9 -5
  91. package/dist/cjs/router/cli/code/tanstackTypes.js +125 -56
  92. package/dist/cjs/router/cli/code/templates.js +24 -14
  93. package/dist/cjs/router/cli/code/utils.js +9 -5
  94. package/dist/cjs/router/cli/config-routes/converter.js +9 -5
  95. package/dist/cjs/router/cli/config-routes/parseRouteConfig.js +9 -5
  96. package/dist/cjs/router/cli/constants.js +23 -19
  97. package/dist/cjs/router/cli/entry.js +9 -5
  98. package/dist/cjs/router/cli/handler.js +9 -5
  99. package/dist/cjs/router/cli/index.js +9 -5
  100. package/dist/cjs/router/index.js +9 -5
  101. package/dist/cjs/router/internal.js +12 -8
  102. package/dist/cjs/router/runtime/CSSLinks.js +9 -5
  103. package/dist/cjs/router/runtime/DefaultNotFound.js +9 -5
  104. package/dist/cjs/router/runtime/DeferredDataScripts.js +12 -8
  105. package/dist/cjs/router/runtime/DeferredDataScripts.node.js +9 -5
  106. package/dist/cjs/router/runtime/PrefetchLink.js +162 -26
  107. package/dist/cjs/router/runtime/constants.js +9 -5
  108. package/dist/cjs/router/runtime/hooks.js +9 -5
  109. package/dist/cjs/router/runtime/index.js +15 -10
  110. package/dist/cjs/router/runtime/internal.js +9 -5
  111. package/dist/cjs/router/runtime/lifecycle.js +18 -14
  112. package/dist/cjs/router/runtime/plugin.js +9 -5
  113. package/dist/cjs/router/runtime/plugin.node.js +9 -5
  114. package/dist/cjs/router/runtime/routerHelper.js +9 -5
  115. package/dist/cjs/router/runtime/rsc-router.js +9 -5
  116. package/dist/cjs/router/runtime/rsc.js +9 -5
  117. package/dist/cjs/router/runtime/server.js +9 -5
  118. package/dist/cjs/router/runtime/tanstack/basepathRewrite.js +12 -8
  119. package/dist/cjs/router/runtime/tanstack/dataMutation.js +9 -5
  120. package/dist/cjs/router/runtime/tanstack/hydrationBoundary.js +48 -0
  121. package/dist/cjs/router/runtime/tanstack/outlet.js +58 -0
  122. package/dist/cjs/router/runtime/tanstack/plugin.js +199 -96
  123. package/dist/cjs/router/runtime/tanstack/plugin.node.js +13 -19
  124. package/dist/cjs/router/runtime/tanstack/prefetchLink.js +10 -6
  125. package/dist/cjs/router/runtime/tanstack/routeTree.js +73 -17
  126. package/dist/cjs/router/runtime/tanstack/rsc/ClientSlot.js +9 -5
  127. package/dist/cjs/router/runtime/tanstack/rsc/CompositeComponent.js +9 -5
  128. package/dist/cjs/router/runtime/tanstack/rsc/ReplayableStream.js +14 -9
  129. package/dist/cjs/router/runtime/tanstack/rsc/RscNodeRenderer.js +9 -5
  130. package/dist/cjs/router/runtime/tanstack/rsc/SlotContext.js +9 -5
  131. package/dist/cjs/router/runtime/tanstack/rsc/client.js +9 -5
  132. package/dist/cjs/router/runtime/tanstack/rsc/createRscProxy.js +9 -5
  133. package/dist/cjs/router/runtime/tanstack/rsc/index.js +9 -5
  134. package/dist/cjs/router/runtime/tanstack/rsc/server.js +9 -5
  135. package/dist/cjs/router/runtime/tanstack/rsc/slotUsageSanitizer.js +9 -5
  136. package/dist/cjs/router/runtime/tanstack/rsc/symbols.js +20 -15
  137. package/dist/cjs/router/runtime/utils.js +9 -5
  138. package/dist/cjs/router/runtime/withRouter.js +9 -5
  139. package/dist/cjs/rsc/client.js +12 -8
  140. package/dist/cjs/rsc/server.js +9 -5
  141. package/dist/cjs/rsc/server.worker.js +62 -0
  142. package/dist/cjs/ssr/index.node.js +13 -9
  143. package/dist/cjs/ssr/serverRender/renderToStream/buildTemplate.after.js +9 -5
  144. package/dist/cjs/ssr/serverRender/renderToString/entry.js +18 -13
  145. package/dist/cjs/ssr/serverRender/types.js +9 -5
  146. package/dist/esm/boundary-debugger/index.mjs +263 -0
  147. package/dist/esm/cli/ssr/index.mjs +5 -15
  148. package/dist/esm/cli/template.server.mjs +1 -0
  149. package/dist/esm/core/react/wrapper.mjs +9 -3
  150. package/dist/esm/core/server/federatedCss.mjs +13 -0
  151. package/dist/esm/core/server/helmet.mjs +5 -2
  152. package/dist/esm/core/server/scriptOrder.mjs +25 -0
  153. package/dist/esm/core/server/stream/afterTemplate.mjs +14 -6
  154. package/dist/esm/core/server/stream/beforeTemplate.mjs +14 -11
  155. package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +64 -0
  156. package/dist/esm/core/server/stream/createReadableStream.mjs +7 -2
  157. package/dist/esm/core/server/stream/createReadableStream.worker.mjs +4 -2
  158. package/dist/esm/core/server/stream/shared.mjs +3 -1
  159. package/dist/esm/core/server/string/index.mjs +17 -9
  160. package/dist/esm/core/server/string/loadable.mjs +70 -9
  161. package/dist/esm/document/cli/index.mjs +3 -1
  162. package/dist/esm/exports/head.mjs +193 -4
  163. package/dist/esm/exports/loadable.mjs +26 -3
  164. package/dist/esm/exports/tanstack-router.mjs +2 -1
  165. package/dist/esm/router/cli/code/tanstackTypes.mjs +116 -51
  166. package/dist/esm/router/cli/code/templates.mjs +15 -9
  167. package/dist/esm/router/runtime/PrefetchLink.mjs +153 -21
  168. package/dist/esm/router/runtime/tanstack/hydrationBoundary.mjs +10 -0
  169. package/dist/esm/router/runtime/tanstack/outlet.mjs +17 -0
  170. package/dist/esm/router/runtime/tanstack/plugin.mjs +193 -94
  171. package/dist/esm/router/runtime/tanstack/plugin.node.mjs +5 -15
  172. package/dist/esm/router/runtime/tanstack/prefetchLink.mjs +1 -1
  173. package/dist/esm/router/runtime/tanstack/routeTree.mjs +65 -13
  174. package/dist/esm/rsc/server.worker.mjs +1 -0
  175. package/dist/esm/ssr/serverRender/renderToString/entry.mjs +9 -6
  176. package/dist/esm-node/boundary-debugger/index.mjs +264 -0
  177. package/dist/esm-node/cli/ssr/index.mjs +5 -15
  178. package/dist/esm-node/cli/template.server.mjs +1 -0
  179. package/dist/esm-node/core/react/wrapper.mjs +9 -3
  180. package/dist/esm-node/core/server/federatedCss.mjs +14 -0
  181. package/dist/esm-node/core/server/helmet.mjs +5 -2
  182. package/dist/esm-node/core/server/scriptOrder.mjs +26 -0
  183. package/dist/esm-node/core/server/stream/afterTemplate.mjs +14 -6
  184. package/dist/esm-node/core/server/stream/beforeTemplate.mjs +14 -11
  185. package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +65 -0
  186. package/dist/esm-node/core/server/stream/createReadableStream.mjs +7 -2
  187. package/dist/esm-node/core/server/stream/createReadableStream.worker.mjs +4 -2
  188. package/dist/esm-node/core/server/stream/shared.mjs +3 -1
  189. package/dist/esm-node/core/server/string/index.mjs +17 -9
  190. package/dist/esm-node/core/server/string/loadable.mjs +70 -9
  191. package/dist/esm-node/document/cli/index.mjs +3 -1
  192. package/dist/esm-node/exports/head.mjs +193 -4
  193. package/dist/esm-node/exports/loadable.mjs +26 -3
  194. package/dist/esm-node/exports/tanstack-router.mjs +2 -1
  195. package/dist/esm-node/router/cli/code/tanstackTypes.mjs +116 -51
  196. package/dist/esm-node/router/cli/code/templates.mjs +15 -9
  197. package/dist/esm-node/router/runtime/PrefetchLink.mjs +153 -21
  198. package/dist/esm-node/router/runtime/tanstack/hydrationBoundary.mjs +11 -0
  199. package/dist/esm-node/router/runtime/tanstack/outlet.mjs +18 -0
  200. package/dist/esm-node/router/runtime/tanstack/plugin.mjs +193 -94
  201. package/dist/esm-node/router/runtime/tanstack/plugin.node.mjs +5 -15
  202. package/dist/esm-node/router/runtime/tanstack/prefetchLink.mjs +1 -1
  203. package/dist/esm-node/router/runtime/tanstack/routeTree.mjs +65 -13
  204. package/dist/esm-node/rsc/server.worker.mjs +2 -0
  205. package/dist/esm-node/ssr/serverRender/renderToString/entry.mjs +9 -6
  206. package/dist/types/boundary-debugger/index.d.ts +28 -0
  207. package/dist/types/cli/entry.d.ts +2 -2
  208. package/dist/types/core/context/response/index.server.d.ts +4 -1
  209. package/dist/types/core/context/runtime.d.ts +4 -0
  210. package/dist/types/core/plugin/index.d.ts +1 -1
  211. package/dist/types/core/server/federatedCss.d.ts +5 -0
  212. package/dist/types/core/server/helmet.d.ts +5 -3
  213. package/dist/types/core/server/scriptOrder.d.ts +1 -0
  214. package/dist/types/core/server/stream/beforeTemplate.d.ts +1 -0
  215. package/dist/types/core/server/stream/beforeTemplate.worker.d.ts +10 -0
  216. package/dist/types/core/server/stream/shared.d.ts +8 -0
  217. package/dist/types/core/server/string/loadable.d.ts +11 -0
  218. package/dist/types/core/server/utils.d.ts +11 -1
  219. package/dist/types/document/constants.d.ts +3 -1
  220. package/dist/types/exports/head.d.ts +10 -3
  221. package/dist/types/exports/loadable.d.ts +8 -1
  222. package/dist/types/exports/tanstack-router.d.ts +3 -1
  223. package/dist/types/router/cli/code/utils.d.ts +1 -1
  224. package/dist/types/router/cli/entry.d.ts +1 -1
  225. package/dist/types/router/runtime/PrefetchLink.d.ts +5 -1
  226. package/dist/types/router/runtime/tanstack/hydrationBoundary.d.ts +2 -0
  227. package/dist/types/router/runtime/tanstack/outlet.d.ts +2 -0
  228. package/dist/types/rsc/server.worker.d.ts +1 -0
  229. package/package.json +31 -25
@@ -0,0 +1,14 @@
1
+ import "node:module";
2
+ import { attributesToString } from "./utils.mjs";
3
+ const createFederatedCssLinks = (assets, options)=>{
4
+ if (void 0 === assets || 0 === assets.length) return '';
5
+ const seen = new Set(options.existingAssets || []);
6
+ const attributes = attributesToString(options.attributes || {});
7
+ const links = [];
8
+ for (const asset of assets)if (!('' === asset || seen.has(asset) || options.template.includes(asset))) {
9
+ seen.add(asset);
10
+ links.push(`<link${attributes} href="${asset}" rel="stylesheet" />`);
11
+ }
12
+ return links.join('');
13
+ };
14
+ export { createFederatedCssLinks };
@@ -1,11 +1,14 @@
1
1
  import "node:module";
2
- import { EOL } from "os";
3
2
  import { safeReplace } from "./utils.mjs";
3
+ const EOL = '\n';
4
4
  const RE_HTML_ATTR = /<html[^>]*>/;
5
5
  const RE_BODY_ATTR = /<body[^>]*>/;
6
6
  const RE_LAST_IN_HEAD = /<\/head>/;
7
7
  const RE_TITLE = /<title[^>]*>([\s\S\n\r]*?)<\/title>/;
8
8
  const TEST_TITLE_CONTENT = /(?<=<title[^>]*>)([\s\S\n\r]*?)([.|\S])([\s\S\n\r]*?)(?=<\/title>)/;
9
+ function getHelmetData(runtimeContext) {
10
+ return runtimeContext._helmetContext?.helmet ?? void 0;
11
+ }
9
12
  function createReplaceHelemt(helmetData) {
10
13
  return helmetData ? (template)=>helmetReplace(template, helmetData) : (tempalte)=>tempalte;
11
14
  }
@@ -36,4 +39,4 @@ function helmetReplace(content, helmetData) {
36
39
  ].reduce((pre, cur)=>pre + (cur.length > 0 ? ` ${cur}${EOL}` : ''), '');
37
40
  return safeReplace(result, RE_LAST_IN_HEAD, `${helmetStr}</head>`);
38
41
  }
39
- export { createReplaceHelemt, helmetReplace };
42
+ export { createReplaceHelemt, getHelmetData, helmetReplace };
@@ -0,0 +1,26 @@
1
+ import "node:module";
2
+ function getScriptTags(template) {
3
+ const scriptRegExp = /<script\b[^>]*\bsrc=(["'])(.*?)\1[^>]*><\/script>/g;
4
+ return Array.from(template.matchAll(scriptRegExp)).map((match)=>({
5
+ index: match.index ?? 0,
6
+ tag: match[0],
7
+ src: match[2]
8
+ }));
9
+ }
10
+ function getAssetBasename(src) {
11
+ const withoutQuery = src.split(/[?#]/)[0];
12
+ return withoutQuery.split('/').pop() || withoutQuery;
13
+ }
14
+ function isEntryScript(src, entryName, asyncEntry) {
15
+ const basename = getAssetBasename(src);
16
+ const prefix = asyncEntry ? `async-${entryName}` : entryName;
17
+ return basename === `${prefix}.js` || basename.startsWith(`${prefix}.`) || basename.startsWith(`${prefix}-`);
18
+ }
19
+ function injectBeforeHydrationEntryScript(template, scripts, entryName = 'index') {
20
+ if ('' === scripts) return template;
21
+ const scriptTags = getScriptTags(template);
22
+ const target = scriptTags.find((match)=>isEntryScript(match.src, entryName, false)) ?? scriptTags.find((match)=>isEntryScript(match.src, entryName, true));
23
+ if (void 0 === target) return template;
24
+ return `${template.slice(0, target.index)}${scripts}${template.slice(target.index)}`;
25
+ }
26
+ export { injectBeforeHydrationEntryScript };
@@ -1,8 +1,9 @@
1
1
  import "node:module";
2
2
  import { serializeJson } from "@modern-js/runtime-utils/node";
3
- import { getRouterHydrationScripts } from "../../../router/runtime/lifecycle.mjs";
3
+ import { getRouterHydrationScripts, getRouterMatchedRouteIds } from "../../../router/runtime/lifecycle.mjs";
4
4
  import { SSR_DATA_JSON_ID } from "../../constants.mjs";
5
5
  import { SSR_DATA_PLACEHOLDER } from "../constants.mjs";
6
+ import { injectBeforeHydrationEntryScript } from "../scriptOrder.mjs";
6
7
  import { buildHtml } from "../shared.mjs";
7
8
  import { attributesToString, safeReplace } from "../utils.mjs";
8
9
  function buildShellAfterTemplate(afterAppTemplate, options) {
@@ -23,11 +24,18 @@ function buildShellAfterTemplate(afterAppTemplate, options) {
23
24
  if (!routeManifest) return template;
24
25
  const { routeAssets } = routeManifest;
25
26
  if (!routeAssets) return template;
26
- const asyncEntry = routeAssets[`async-${entryName}`];
27
- if (asyncEntry) {
28
- const { assets } = asyncEntry;
29
- const jsChunkStr = assets?.filter((asset)=>asset.endsWith('.js'))?.map((asset)=>`<script src=${asset} nonce="${nonce}"></script>`).join(' ');
30
- if (jsChunkStr) return safeReplace(template, '<!--<?- chunksMap.js ?>-->', jsChunkStr);
27
+ const matchedRouteIds = getRouterMatchedRouteIds(runtimeContext) ?? [];
28
+ const assetEntries = [
29
+ ...matchedRouteIds.map((routeId)=>routeAssets[routeId]),
30
+ routeAssets[`async-${entryName}`]
31
+ ].filter(Boolean);
32
+ const jsAssets = Array.from(new Set(assetEntries.flatMap((entry)=>(entry.assets ?? []).filter((asset)=>asset.endsWith('.js')))));
33
+ const nonceAttr = nonce ? ` nonce="${nonce}"` : '';
34
+ const jsChunkStr = jsAssets.filter((asset)=>!template.includes(asset)).map((asset)=>`<script src=${asset}${nonceAttr}></script>`).join(' ');
35
+ if (jsChunkStr) {
36
+ const withoutPlaceholder = safeReplace(template, '<!--<?- chunksMap.js ?>-->', '');
37
+ const withEarlyScripts = injectBeforeHydrationEntryScript(withoutPlaceholder, jsChunkStr, entryName);
38
+ return withEarlyScripts !== withoutPlaceholder ? withEarlyScripts : safeReplace(template, '<!--<?- chunksMap.js ?>-->', jsChunkStr);
31
39
  }
32
40
  return template;
33
41
  }
@@ -1,9 +1,9 @@
1
1
  import "node:module";
2
2
  import { matchRoutes } from "@modern-js/runtime-utils/router";
3
- import react_helmet from "react-helmet";
4
3
  import { getRouterMatchedRouteIds } from "../../../router/runtime/lifecycle.mjs";
5
4
  import { CHUNK_CSS_PLACEHOLDER } from "../constants.mjs";
6
- import { createReplaceHelemt } from "../helmet.mjs";
5
+ import { createFederatedCssLinks } from "../federatedCss.mjs";
6
+ import { createReplaceHelemt, getHelmetData } from "../helmet.mjs";
7
7
  import { buildHtml } from "../shared.mjs";
8
8
  import { checkIsNode, safeReplace } from "../utils.mjs";
9
9
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
@@ -21,8 +21,8 @@ const checkIsInline = (chunk, enableInline)=>{
21
21
  return Boolean(enableInline);
22
22
  };
23
23
  async function buildShellBeforeTemplate(beforeAppTemplate, options) {
24
- const { config, runtimeContext, styledComponentsStyleTags, entryName } = options;
25
- const helmetData = react_helmet.renderStatic();
24
+ const { config, runtimeContext, styledComponentsStyleTags, entryName, moduleFederationCssAssets } = options;
25
+ const helmetData = getHelmetData(runtimeContext);
26
26
  const callbacks = [
27
27
  createReplaceHelemt(helmetData),
28
28
  (template)=>injectCss(template, entryName, styledComponentsStyleTags)
@@ -31,33 +31,36 @@ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
31
31
  async function injectCss(template, entryName, styledComponentsStyleTags) {
32
32
  let css = await getCssChunks();
33
33
  if (styledComponentsStyleTags) css += styledComponentsStyleTags;
34
+ css += createFederatedCssLinks(moduleFederationCssAssets, {
35
+ template,
36
+ existingAssets: css.match(/href="([^"]+)"/g)?.map((item)=>item.replace(/^href="/, '').replace(/"$/, ''))
37
+ });
34
38
  return safeReplace(template, CHUNK_CSS_PLACEHOLDER, css);
35
39
  async function getCssChunks() {
36
40
  const { routeManifest, routerContext, routes } = runtimeContext;
37
41
  if (!routeManifest) return '';
38
42
  const { routeAssets } = routeManifest;
39
- let matchedRouteManifests;
43
+ let matchedRouteManifests = [];
40
44
  const matchedRouteIds = getRouterMatchedRouteIds(runtimeContext);
41
45
  if (matchedRouteIds?.length) matchedRouteManifests = matchedRouteIds.map((routeId)=>routeAssets[routeId]).filter(Boolean);
42
- else {
43
- if (!routerContext || !routes) return '';
46
+ else if (routerContext && routes) {
44
47
  const matches = matchRoutes(routes, routerContext.location, routerContext.basename);
45
48
  matchedRouteManifests = matches?.map((match, index)=>{
46
49
  if (!index) return;
47
50
  const routeId = match.route.id;
48
51
  if (routeId) return routeAssets[routeId];
49
- }).filter(Boolean);
52
+ }).filter((routeManifest)=>void 0 !== routeManifest) ?? [];
50
53
  }
51
54
  const asyncEntry = routeAssets[`async-${entryName}`];
52
- if (asyncEntry) matchedRouteManifests?.push(asyncEntry);
53
- const cssChunks = matchedRouteManifests ? matchedRouteManifests.reduce((chunks, routeManifest)=>{
55
+ if (asyncEntry) matchedRouteManifests.push(asyncEntry);
56
+ const cssChunks = matchedRouteManifests.reduce((chunks, routeManifest)=>{
54
57
  const { referenceCssAssets = [] } = routeManifest;
55
58
  const _cssChunks = referenceCssAssets.filter((asset)=>asset?.endsWith('.css') && !template.includes(asset));
56
59
  return [
57
60
  ...chunks,
58
61
  ..._cssChunks
59
62
  ];
60
- }, []) : [];
63
+ }, []);
61
64
  const { inlineStyles } = config;
62
65
  const styles = await Promise.all(cssChunks.map(async (chunk)=>{
63
66
  const link = `<link href="${chunk}" rel="stylesheet" />`;
@@ -0,0 +1,65 @@
1
+ import "node:module";
2
+ import { matchRoutes } from "@modern-js/runtime-utils/router";
3
+ import { getRouterMatchedRouteIds } from "../../../router/runtime/lifecycle.mjs";
4
+ import { CHUNK_CSS_PLACEHOLDER } from "../constants.mjs";
5
+ import { createFederatedCssLinks } from "../federatedCss.mjs";
6
+ import { createReplaceHelemt, getHelmetData } from "../helmet.mjs";
7
+ import { buildHtml } from "../shared.mjs";
8
+ import { safeReplace } from "../utils.mjs";
9
+ const checkIsInline = (chunk, enableInline)=>{
10
+ if ('production' !== process.env.NODE_ENV) return false;
11
+ if (enableInline instanceof RegExp) return enableInline.test(chunk);
12
+ return Boolean(enableInline);
13
+ };
14
+ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
15
+ const { config, runtimeContext, styledComponentsStyleTags, entryName, moduleFederationCssAssets } = options;
16
+ const helmetData = getHelmetData(runtimeContext);
17
+ const callbacks = [
18
+ createReplaceHelemt(helmetData),
19
+ (template)=>injectCss(template, entryName, styledComponentsStyleTags)
20
+ ];
21
+ return buildHtml(beforeAppTemplate, callbacks);
22
+ async function injectCss(template, entryName, styledComponentsStyleTags) {
23
+ let css = await getCssChunks();
24
+ if (styledComponentsStyleTags) css += styledComponentsStyleTags;
25
+ css += createFederatedCssLinks(moduleFederationCssAssets, {
26
+ template,
27
+ existingAssets: css.match(/href="([^"]+)"/g)?.map((item)=>item.replace(/^href="/, '').replace(/"$/, ''))
28
+ });
29
+ return safeReplace(template, CHUNK_CSS_PLACEHOLDER, css);
30
+ async function getCssChunks() {
31
+ const { routeManifest, routerContext, routes } = runtimeContext;
32
+ if (!routeManifest) return '';
33
+ const { routeAssets } = routeManifest;
34
+ let matchedRouteManifests = [];
35
+ const matchedRouteIds = getRouterMatchedRouteIds(runtimeContext);
36
+ if (matchedRouteIds?.length) matchedRouteManifests = matchedRouteIds.map((routeId)=>routeAssets[routeId]).filter(Boolean);
37
+ else if (routerContext && routes) {
38
+ const matches = matchRoutes(routes, routerContext.location, routerContext.basename);
39
+ matchedRouteManifests = matches?.map((match, index)=>{
40
+ if (!index) return;
41
+ const routeId = match.route.id;
42
+ if (routeId) return routeAssets[routeId];
43
+ }).filter((routeManifest)=>void 0 !== routeManifest) ?? [];
44
+ }
45
+ const asyncEntry = routeAssets[`async-${entryName}`];
46
+ if (asyncEntry) matchedRouteManifests.push(asyncEntry);
47
+ const cssChunks = matchedRouteManifests.reduce((chunks, routeManifest)=>{
48
+ const { referenceCssAssets = [] } = routeManifest;
49
+ const _cssChunks = referenceCssAssets.filter((asset)=>asset?.endsWith('.css') && !template.includes(asset));
50
+ return [
51
+ ...chunks,
52
+ ..._cssChunks
53
+ ];
54
+ }, []);
55
+ const { inlineStyles } = config;
56
+ const styles = cssChunks.map((chunk)=>{
57
+ const link = `<link href="${chunk}" rel="stylesheet" />`;
58
+ checkIsInline(chunk, inlineStyles);
59
+ return link;
60
+ });
61
+ return `${styles.join('')}`;
62
+ }
63
+ }
64
+ }
65
+ export { buildShellBeforeTemplate };
@@ -16,7 +16,7 @@ const defaultExtender = {
16
16
  };
17
17
  const createReadableStreamFromElement = async (request, rootElement, options)=>{
18
18
  const { renderToPipeableStream } = await import("react-dom/server");
19
- const { runtimeContext, htmlTemplate, config, ssrConfig, entryName } = options;
19
+ const { runtimeContext, htmlTemplate, config, ssrConfig, entryName, moduleFederationCssAssets } = options;
20
20
  let shellChunkStatus = ShellChunkStatus.START;
21
21
  let renderLevel = RenderLevel.SERVER_RENDER;
22
22
  const forceStream2String = Boolean(process.env.MODERN_JS_STREAM_TO_STRING);
@@ -36,11 +36,14 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
36
36
  if (extender.modifyRootElement) processedRootElement = extender.modifyRootElement(processedRootElement);
37
37
  });
38
38
  const chunkVec = [];
39
+ let hasStartedPipe = false;
39
40
  return new Promise((resolve)=>{
40
41
  const { pipe: reactStreamingPipe } = renderToPipeableStream(processedRootElement, {
41
42
  nonce: config.nonce,
42
43
  identifierPrefix: SSR_HYDRATION_ID_PREFIX,
43
44
  [onReady] () {
45
+ if (hasStartedPipe) return;
46
+ hasStartedPipe = true;
44
47
  let styledComponentsStyleTags = '';
45
48
  extenders.forEach((extender)=>{
46
49
  if (extender.getStyleTags) styledComponentsStyleTags += extender.getStyleTags();
@@ -53,6 +56,7 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
53
56
  runtimeContext,
54
57
  config,
55
58
  entryName,
59
+ moduleFederationCssAssets,
56
60
  styledComponentsStyleTags
57
61
  }).then(({ shellAfter, shellBefore })=>{
58
62
  const pendingScripts = [];
@@ -110,7 +114,8 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
110
114
  renderLevel,
111
115
  runtimeContext,
112
116
  entryName,
113
- config
117
+ config,
118
+ moduleFederationCssAssets
114
119
  }).then(({ shellAfter, shellBefore })=>{
115
120
  const fallbackHtml = `${shellBefore}${shellAfter}`;
116
121
  const readableStream = getReadableStreamFromString(fallbackHtml);
@@ -9,19 +9,21 @@ import { getTemplates } from "./template.mjs";
9
9
  const createReadableStreamFromElement = async (request, rootElement, options)=>{
10
10
  let shellChunkStatus = ShellChunkStatus.START;
11
11
  const chunkVec = [];
12
- const { htmlTemplate, runtimeContext, config, ssrConfig, entryName, rscRoot } = options;
12
+ const { htmlTemplate, runtimeContext, config, ssrConfig, entryName, moduleFederationCssAssets, rscManifest, rscRoot } = options;
13
13
  const { shellBefore, shellAfter } = await getTemplates(htmlTemplate, {
14
14
  renderLevel: RenderLevel.SERVER_RENDER,
15
15
  runtimeContext,
16
16
  ssrConfig,
17
17
  request,
18
18
  config,
19
- entryName
19
+ entryName,
20
+ moduleFederationCssAssets
20
21
  });
21
22
  try {
22
23
  const readableOriginal = await renderSSRStream(rootElement, {
23
24
  request,
24
25
  nonce: config.nonce,
26
+ rscManifest,
25
27
  rscRoot: rscRoot,
26
28
  routes: runtimeContext.routes,
27
29
  onError (error) {
@@ -64,7 +64,7 @@ function createRenderStreaming(createReadableStreamPromise) {
64
64
  const end = time();
65
65
  const { runtimeContext, config, resource } = options;
66
66
  const { onError, onTiming } = options;
67
- const { htmlTemplate, entryName } = resource;
67
+ const { htmlTemplate, entryName, moduleFederationCssAssets } = resource;
68
68
  const ssrConfig = getSSRConfigByEntry(entryName, config.ssr, config.ssrByEntries);
69
69
  const StreamServerRootWrapper = ({ children })=>/*#__PURE__*/ jsxs(Fragment, {
70
70
  children: [
@@ -84,9 +84,11 @@ function createRenderStreaming(createReadableStreamPromise) {
84
84
  runtimeContext,
85
85
  ssrConfig,
86
86
  entryName,
87
+ moduleFederationCssAssets,
87
88
  rscClientManifest: options.rscClientManifest,
88
89
  rscSSRManifest: options.rscSSRManifest,
89
90
  rscServerManifest: options.rscServerManifest,
91
+ rscManifest: options.rscManifest,
90
92
  rscRoot: options.rscRoot,
91
93
  onShellReady () {
92
94
  const cost = end();
@@ -2,12 +2,12 @@ import "node:module";
2
2
  import { time } from "@modern-js/runtime-utils/time";
3
3
  import { SSR_HYDRATION_ID_PREFIX } from "@modern-js/utils/universal/constants";
4
4
  import server from "react-dom/server";
5
- import react_helmet from "react-helmet";
6
5
  import { RenderLevel } from "../../constants.mjs";
7
6
  import { getGlobalInternalRuntimeContext } from "../../context/index.mjs";
8
7
  import { wrapRuntimeContextProvider } from "../../react/wrapper.mjs";
9
8
  import { CHUNK_CSS_PLACEHOLDER, CHUNK_JS_PLACEHOLDER, HTML_PLACEHOLDER, SSR_DATA_PLACEHOLDER } from "../constants.mjs";
10
- import { createReplaceHelemt } from "../helmet.mjs";
9
+ import { createReplaceHelemt, getHelmetData } from "../helmet.mjs";
10
+ import { injectBeforeHydrationEntryScript } from "../scriptOrder.mjs";
11
11
  import { buildHtml } from "../shared.mjs";
12
12
  import { SSRErrors, SSRTimings } from "../tracer.mjs";
13
13
  import { getSSRConfigByEntry, safeReplace } from "../utils.mjs";
@@ -20,7 +20,7 @@ const renderString = async (request, serverRoot, options)=>{
20
20
  onTiming
21
21
  };
22
22
  const routerContext = runtimeContext.routerContext;
23
- const { htmlTemplate, entryName, loadableStats, routeManifest } = resource;
23
+ const { htmlTemplate, entryName, loadableStats, routeManifest, moduleFederationCssAssets } = resource;
24
24
  const ssrConfig = getSSRConfigByEntry(entryName, config.ssr, config.ssrByEntries);
25
25
  const chunkSet = {
26
26
  renderLevel: RenderLevel.CLIENT_RENDER,
@@ -33,8 +33,10 @@ const renderString = async (request, serverRoot, options)=>{
33
33
  stats: loadableStats,
34
34
  nonce: config.nonce,
35
35
  routeManifest,
36
+ runtimeContext,
36
37
  template: htmlTemplate,
37
38
  entryName,
39
+ moduleFederationCssAssets,
38
40
  chunkSet,
39
41
  config
40
42
  }),
@@ -58,10 +60,10 @@ const renderString = async (request, serverRoot, options)=>{
58
60
  const rootElement = wrapRuntimeContextProvider(serverRoot, Object.assign(runtimeContext, {
59
61
  ssr: true
60
62
  }));
61
- const html = await generateHtml(rootElement, htmlTemplate, chunkSet, collectors, runtimeContext.ssrContext?.htmlModifiers || [], tracer);
63
+ const html = await generateHtml(rootElement, htmlTemplate, chunkSet, collectors, runtimeContext.ssrContext?.htmlModifiers || [], runtimeContext, entryName, tracer);
62
64
  return html;
63
65
  };
64
- async function generateHtml(App, htmlTemplate, chunkSet, collectors, htmlModifiers, { onError, onTiming }) {
66
+ async function generateHtml(App, htmlTemplate, chunkSet, collectors, htmlModifiers, runtimeContext, entryName, { onError, onTiming }) {
65
67
  let html = '';
66
68
  let helmetData;
67
69
  const finalApp = collectors.reduce((pre, creator)=>creator.collect?.(pre) || pre, App);
@@ -71,7 +73,7 @@ async function generateHtml(App, htmlTemplate, chunkSet, collectors, htmlModifie
71
73
  identifierPrefix: SSR_HYDRATION_ID_PREFIX
72
74
  });
73
75
  chunkSet.renderLevel = RenderLevel.SERVER_RENDER;
74
- helmetData = react_helmet.renderStatic();
76
+ helmetData = getHelmetData(runtimeContext);
75
77
  const cost = end();
76
78
  onTiming(SSRTimings.RENDER_HTML, cost);
77
79
  } catch (e) {
@@ -82,7 +84,7 @@ async function generateHtml(App, htmlTemplate, chunkSet, collectors, htmlModifie
82
84
  const { ssrScripts, cssChunk, jsChunk } = chunkSet;
83
85
  const finalHtml = await buildHtml(htmlTemplate, [
84
86
  createReplaceHtml(html),
85
- createReplaceChunkJs(jsChunk),
87
+ createReplaceChunkJs(jsChunk, entryName),
86
88
  createReplaceChunkCss(cssChunk),
87
89
  createReplaceSSRDataScript(ssrScripts),
88
90
  createReplaceHelemt(helmetData),
@@ -96,8 +98,14 @@ function createReplaceHtml(html) {
96
98
  function createReplaceSSRDataScript(data) {
97
99
  return (template)=>safeReplace(template, SSR_DATA_PLACEHOLDER, data);
98
100
  }
99
- function createReplaceChunkJs(js) {
100
- return (template)=>safeReplace(template, CHUNK_JS_PLACEHOLDER, js);
101
+ function createReplaceChunkJs(js, entryName) {
102
+ return (template)=>{
103
+ if (!js) return safeReplace(template, CHUNK_JS_PLACEHOLDER, '');
104
+ const withoutPlaceholder = safeReplace(template, CHUNK_JS_PLACEHOLDER, '');
105
+ const withEarlyScripts = injectBeforeHydrationEntryScript(withoutPlaceholder, js, entryName);
106
+ if (withEarlyScripts !== withoutPlaceholder) return withEarlyScripts;
107
+ return safeReplace(template, CHUNK_JS_PLACEHOLDER, js);
108
+ };
101
109
  }
102
110
  function createReplaceChunkCss(css) {
103
111
  return (template)=>safeReplace(template, CHUNK_CSS_PLACEHOLDER, css);
@@ -1,5 +1,7 @@
1
1
  import "node:module";
2
2
  import { ChunkExtractor } from "@loadable/server";
3
+ import { getRouterMatchedRouteIds } from "../../../router/runtime/lifecycle.mjs";
4
+ import { createFederatedCssLinks } from "../federatedCss.mjs";
3
5
  import { attributesToString, checkIsNode } from "../utils.mjs";
4
6
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
5
7
  import { dirname as __rspack_dirname } from "node:path";
@@ -9,6 +11,33 @@ const extname = (uri)=>{
9
11
  return `.${uri?.split('.').pop()}` || '';
10
12
  };
11
13
  const generateChunks = (chunks, ext)=>chunks.filter((chunk)=>Boolean(chunk.url)).filter((chunk)=>extname(chunk.url).slice(1) === ext);
14
+ const dedupeChunksByUrl = (chunks)=>{
15
+ const seen = new Set();
16
+ return chunks.filter((chunk)=>{
17
+ if (!chunk.url || seen.has(chunk.url)) return false;
18
+ seen.add(chunk.url);
19
+ return true;
20
+ });
21
+ };
22
+ const isAsyncEntryScriptChunk = (chunk, entryName)=>{
23
+ if (!chunk.url?.endsWith('.js')) return false;
24
+ const asyncEntryName = `async-${entryName}`;
25
+ const filename = chunk.filename || chunk.url;
26
+ const basename = filename.split('/').pop() || filename;
27
+ return basename === `${asyncEntryName}.js` || basename.startsWith(`${asyncEntryName}.`) || basename.startsWith(`${asyncEntryName}-`);
28
+ };
29
+ const orderHydrationScriptChunks = ({ asyncEntryChunks, collectedChunks, matchedRouteChunks, entryName })=>{
30
+ const asyncEntryScriptChunks = [];
31
+ const asyncEntryDependencyChunks = [];
32
+ for (const chunk of asyncEntryChunks)if (isAsyncEntryScriptChunk(chunk, entryName)) asyncEntryScriptChunks.push(chunk);
33
+ else asyncEntryDependencyChunks.push(chunk);
34
+ return dedupeChunksByUrl([
35
+ ...asyncEntryDependencyChunks,
36
+ ...collectedChunks,
37
+ ...matchedRouteChunks,
38
+ ...asyncEntryScriptChunks
39
+ ]);
40
+ };
12
41
  const checkIsInline = (chunk, enableInline)=>{
13
42
  if ('production' !== process.env.NODE_ENV) return false;
14
43
  if (enableInline instanceof RegExp) return enableInline.test(chunk.url);
@@ -25,6 +54,20 @@ class LoadableCollector {
25
54
  const { routeManifest, entryName } = this.options;
26
55
  return routeManifest?.routeAssets?.[entryName]?.assets;
27
56
  }
57
+ getMatchedRouteChunks() {
58
+ const { routeManifest, runtimeContext } = this.options;
59
+ const routeAssets = routeManifest?.routeAssets;
60
+ if (!routeAssets) return [];
61
+ const matchedRouteIds = getRouterMatchedRouteIds(runtimeContext) ?? [];
62
+ return matchedRouteIds.flatMap((routeId)=>{
63
+ const routeAsset = routeAssets[routeId];
64
+ return (routeAsset?.assets ?? []).map((asset)=>({
65
+ filename: asset.replace(/^\//, ''),
66
+ path: asset,
67
+ url: asset
68
+ }));
69
+ });
70
+ }
28
71
  collect(comopnent) {
29
72
  const { stats, entryName } = this.options;
30
73
  if (!stats) return comopnent;
@@ -37,20 +80,29 @@ class LoadableCollector {
37
80
  return this.extractor.collectChunks(comopnent);
38
81
  }
39
82
  async effect() {
40
- if (!this.extractor) return;
41
83
  const { extractor, options } = this;
42
84
  const { entryName, config } = options;
43
85
  const asyncChunks = [];
44
- if (config.enableAsyncEntry) try {
86
+ if (extractor && config.enableAsyncEntry) try {
45
87
  asyncChunks.push(...extractor.getChunkAssets([
46
88
  `async-${entryName}`
47
89
  ]));
48
90
  } catch (e) {}
49
- const chunks = [].concat(asyncChunks).concat(extractor.getChunkAssets(extractor.chunks));
50
- const scriptChunks = generateChunks(chunks, 'js');
91
+ const collectedChunks = extractor ? extractor.getChunkAssets(extractor.chunks) : [];
92
+ const matchedRouteChunks = this.getMatchedRouteChunks();
93
+ const orderedScriptChunks = orderHydrationScriptChunks({
94
+ asyncEntryChunks: asyncChunks,
95
+ collectedChunks,
96
+ matchedRouteChunks,
97
+ entryName
98
+ });
99
+ const chunks = [].concat(asyncChunks).concat(collectedChunks).concat(matchedRouteChunks);
100
+ const scriptChunks = generateChunks(orderedScriptChunks, 'js');
51
101
  const styleChunks = generateChunks(chunks, 'css');
52
- this.emitLoadableScripts(extractor);
53
- await this.emitScriptAssets(scriptChunks);
102
+ if (extractor) {
103
+ this.emitLoadableScripts(extractor);
104
+ await this.emitScriptAssets(scriptChunks);
105
+ }
54
106
  await this.emitStyleAssets(styleChunks);
55
107
  }
56
108
  emitLoadableScripts(extractor) {
@@ -85,19 +137,28 @@ class LoadableCollector {
85
137
  chunkSet.jsChunk += scripts.filter((script)=>Boolean(script)).join('');
86
138
  }
87
139
  async emitStyleAssets(chunks) {
88
- const { template, chunkSet, config, entryName } = this.options;
140
+ const { template, chunkSet, config, moduleFederationCssAssets } = this.options;
89
141
  const { inlineStyles } = config;
90
142
  const atrributes = attributesToString(this.generateAttributes());
91
143
  const linkRegExp = /<link .*?href="([^"]+)".*?>/g;
92
144
  const matchs = template.matchAll(linkRegExp);
93
145
  const existedLinks = [];
94
146
  for (const match of matchs)existedLinks.push(match[1]);
95
- const css = await Promise.all(chunks.filter((chunk)=>!existedLinks.includes(chunk.url) && !this.existsAssets?.includes(chunk.path)).map(async (chunk)=>{
147
+ const emittedChunks = chunks.filter((chunk)=>!existedLinks.includes(chunk.url) && !this.existsAssets?.includes(chunk.path));
148
+ const css = await Promise.all(emittedChunks.map(async (chunk)=>{
96
149
  const link = `<link${atrributes} href="${chunk.url}" rel="stylesheet" />`;
97
150
  if (checkIsNode() && checkIsInline(chunk, inlineStyles)) return readAsset(chunk).then((content)=>`<style>${content}</style>`).catch((_)=>link);
98
151
  return link;
99
152
  }));
100
153
  chunkSet.cssChunk += css.filter((css)=>Boolean(css)).join('');
154
+ chunkSet.cssChunk += createFederatedCssLinks(moduleFederationCssAssets, {
155
+ template,
156
+ attributes: this.generateAttributes(),
157
+ existingAssets: [
158
+ ...existedLinks,
159
+ ...emittedChunks.map((chunk)=>chunk.url)
160
+ ]
161
+ });
101
162
  }
102
163
  generateAttributes(extraAtr = {}) {
103
164
  const { config } = this.options;
@@ -113,4 +174,4 @@ class LoadableCollector {
113
174
  this.options = options;
114
175
  }
115
176
  }
116
- export { LoadableCollector };
177
+ export { LoadableCollector, orderHydrationScriptChunks };
@@ -301,7 +301,7 @@ const documentPlugin = ()=>({
301
301
  const { entrypoints, internalDirectory, appDirectory } = api.getAppContext();
302
302
  const documentFilePath = getDocumentByEntryName(entrypoints, entryName, appDirectory);
303
303
  if (!documentFilePath) return null;
304
- return async ({ htmlPlugin })=>{
304
+ return async (templateData)=>{
305
305
  const config = api.getNormalizedConfig();
306
306
  const documentParams = getDocParams({
307
307
  config: config,
@@ -320,6 +320,8 @@ const documentPlugin = ()=>({
320
320
  debug("entry %s's document jsx rendered html: %o", entryName, html);
321
321
  const { partialsByEntrypoint } = api.getAppContext();
322
322
  html = processPartials(html, entryName, partialsByEntrypoint || {});
323
+ const htmlPlugin = templateData.htmlPlugin || templateData.htmlWebpackPlugin || templateData.htmlRspackPlugin;
324
+ if (!htmlPlugin) throw new Error('Failed to get HTML plugin tags from template parameters.');
323
325
  const { scripts, links, metas, titles } = extractHtmlTags(htmlPlugin, templateParameters);
324
326
  return processPlaceholders(html, config, scripts, links, metas, titles);
325
327
  };