@bleedingdev/modern-js-app-tools 3.5.0-ultramodern.99 → 3.8.1-ultramodern.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 (411) hide show
  1. package/bin/modern-bundle-docs.js +7 -0
  2. package/dist/cjs/builder/generator/getBuilderEnvironments.js +73 -11
  3. package/dist/cjs/bundleDocs.js +114 -0
  4. package/dist/cjs/plugins/deploy/platforms/cloudflare-output-verifier/index.js +1 -1
  5. package/dist/cjs/plugins/deploy/platforms/cloudflare-output-verifier/worker-bundles.js +94 -18
  6. package/dist/cjs/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.mjs +1 -0
  7. package/dist/cjs/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +14 -0
  8. package/dist/cjs/ultramodern-release-envelope/framework-output.js +109 -57
  9. package/dist/esm/builder/generator/getBuilderEnvironments.mjs +63 -10
  10. package/dist/esm/bundleDocs.mjs +62 -0
  11. package/dist/esm/plugins/deploy/platforms/cloudflare-output-verifier/index.mjs +1 -1
  12. package/dist/esm/plugins/deploy/platforms/cloudflare-output-verifier/worker-bundles.mjs +93 -18
  13. package/dist/esm/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.mjs +1 -0
  14. package/dist/esm/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +14 -0
  15. package/dist/esm/ultramodern-release-envelope/framework-output.mjs +107 -58
  16. package/dist/esm-node/builder/generator/getBuilderEnvironments.mjs +63 -10
  17. package/dist/esm-node/bundleDocs.mjs +63 -0
  18. package/dist/esm-node/plugins/deploy/platforms/cloudflare-output-verifier/index.mjs +1 -1
  19. package/dist/esm-node/plugins/deploy/platforms/cloudflare-output-verifier/worker-bundles.mjs +93 -18
  20. package/dist/esm-node/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.mjs +1 -0
  21. package/dist/esm-node/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +14 -0
  22. package/dist/esm-node/ultramodern-release-envelope/framework-output.mjs +107 -58
  23. package/dist/types/builder/generator/getBuilderEnvironments.d.ts +29 -0
  24. package/dist/types/bundleDocs.d.ts +20 -0
  25. package/dist/types/plugins/deploy/platforms/cloudflare-output-verifier/worker-bundles.d.ts +1 -1
  26. package/dist/types/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.d.mts +1 -1
  27. package/dist/types/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.d.mts +13 -0
  28. package/dist/types/ultramodern-release-envelope/framework-output.d.ts +1 -0
  29. package/docs/apis/app/{commands.mdx → commands.md} +35 -9
  30. package/docs/apis/app/hooks/api/{lambda.mdx → lambda.md} +2 -6
  31. package/docs/apis/app/hooks/config/{favicon.mdx → favicon.md} +1 -6
  32. package/docs/apis/app/hooks/config/{html.mdx → html.md} +1 -5
  33. package/docs/apis/app/hooks/config/{icon.mdx → icon.md} +1 -6
  34. package/docs/apis/app/hooks/config/{mock.mdx → mock.md} +1 -5
  35. package/docs/apis/app/hooks/config/{public.mdx → public.md} +0 -4
  36. package/docs/apis/app/hooks/config/{upload.mdx → upload.md} +3 -7
  37. package/docs/apis/app/hooks/{modern-config.mdx → modern-config.md} +1 -5
  38. package/docs/apis/app/hooks/server/{server.mdx → server.md} +1 -6
  39. package/docs/apis/app/hooks/{shared.mdx → shared.md} +0 -4
  40. package/docs/apis/app/hooks/src/{app.mdx → app.md} +2 -2
  41. package/docs/apis/app/hooks/src/{entry.mdx → entry.md} +1 -6
  42. package/docs/apis/app/hooks/src/{entry.server.mdx → entry.server.md} +0 -5
  43. package/docs/apis/app/hooks/src/{modern.runtime.mdx → modern.runtime.md} +1 -5
  44. package/docs/apis/app/hooks/src/{routes.mdx → routes.md} +3 -7
  45. package/docs/apis/app/hooks/src/{server.mdx → server.md} +1 -5
  46. package/docs/apis/app/runtime/bff/{use-backend-context.mdx → use-backend-context.md} +0 -3
  47. package/docs/apis/app/runtime/core/{create-root.mdx → create-root.md} +0 -3
  48. package/docs/apis/app/runtime/core/{render.mdx → render.md} +1 -4
  49. package/docs/apis/app/runtime/core/{runtime-context.mdx → runtime-context.md} +0 -4
  50. package/docs/apis/app/runtime/router/{router.mdx → router.md} +1 -6
  51. package/docs/apis/app/runtime/ssr/{no-ssr.mdx → no-ssr.md} +0 -3
  52. package/docs/apis/app/runtime/ssr/{renderStreaming.mdx → renderStreaming.md} +0 -4
  53. package/docs/apis/app/runtime/ssr/{renderString.mdx → renderString.md} +0 -4
  54. package/docs/apis/app/runtime/ssr/{requestHandler.mdx → requestHandler.md} +0 -4
  55. package/docs/apis/app/runtime/utility/{css-in-js.mdx → css-in-js.md} +0 -4
  56. package/docs/apis/app/runtime/utility/{head.mdx → head.md} +0 -3
  57. package/docs/apis/app/runtime/utility/{loadable.mdx → loadable.md} +0 -3
  58. package/docs/community/blog/2022-0708-updates.md +91 -0
  59. package/docs/community/blog/2022-0910-updates.md +76 -0
  60. package/docs/community/blog/overview.md +63 -0
  61. package/docs/community/blog/v2-release-note.md +238 -0
  62. package/docs/community/blog/v3-release-note.md +622 -0
  63. package/docs/community/contributing-guide.md +252 -0
  64. package/docs/community/releases.md +23 -0
  65. package/docs/community/showcase.md +24 -0
  66. package/docs/community/team.md +14 -0
  67. package/docs/configure/app/bff/{cross-project.mdx → cross-project.md} +4 -8
  68. package/docs/configure/app/bff/{effect.mdx → effect.md} +16 -22
  69. package/docs/configure/app/bff/{prefix.mdx → prefix.md} +3 -7
  70. package/docs/configure/app/bff/{runtime-framework.mdx → runtime-framework.md} +3 -7
  71. package/docs/configure/app/{builder-plugins.mdx → builder-plugins.md} +4 -8
  72. package/docs/configure/app/dev/{asset-prefix.mdx → asset-prefix.md} +4 -9
  73. package/docs/configure/app/dev/{before-start-url.mdx → before-start-url.md} +0 -4
  74. package/docs/configure/app/dev/{client.mdx → client.md} +3 -7
  75. package/docs/configure/app/dev/hmr.md +10 -0
  76. package/docs/configure/app/dev/{host.mdx → host.md} +0 -4
  77. package/docs/configure/app/dev/{https.mdx → https.md} +0 -4
  78. package/docs/configure/app/dev/{lazy-compilation.mdx → lazy-compilation.md} +2 -8
  79. package/docs/configure/app/dev/live-reload.md +10 -0
  80. package/docs/configure/app/dev/{mock-dir.mdx → mock-dir.md} +0 -4
  81. package/docs/configure/app/dev/progress-bar.md +19 -0
  82. package/docs/configure/app/dev/{server.mdx → server.md} +0 -4
  83. package/docs/configure/app/dev/{setup-middlewares.mdx → setup-middlewares.md} +3 -7
  84. package/docs/configure/app/dev/{start-url.mdx → start-url.md} +0 -5
  85. package/docs/configure/app/dev/{watch-files.mdx → watch-files.md} +3 -7
  86. package/docs/configure/app/dev/{write-to-disk.mdx → write-to-disk.md} +3 -7
  87. package/docs/configure/app/experiments/{source-build.mdx → source-build.md} +1 -3
  88. package/docs/configure/app/html/{app-icon.mdx → app-icon.md} +3 -7
  89. package/docs/configure/app/html/{crossorigin.mdx → crossorigin.md} +3 -7
  90. package/docs/configure/app/html/{favicon.mdx → favicon.md} +3 -7
  91. package/docs/configure/app/html/inject.md +10 -0
  92. package/docs/configure/app/html/{meta.mdx → meta.md} +3 -7
  93. package/docs/configure/app/html/{mount-id.mdx → mount-id.md} +3 -7
  94. package/docs/configure/app/html/output-structure.md +10 -0
  95. package/docs/configure/app/html/script-loading.md +10 -0
  96. package/docs/configure/app/html/{tags.mdx → tags.md} +3 -7
  97. package/docs/configure/app/html/{template-parameters.mdx → template-parameters.md} +3 -7
  98. package/docs/configure/app/html/template.md +10 -0
  99. package/docs/configure/app/html/title.md +18 -0
  100. package/docs/configure/app/output/asset-prefix.md +11 -0
  101. package/docs/configure/app/output/{assets-retry.mdx → assets-retry.md} +1 -5
  102. package/docs/configure/app/output/{charset.mdx → charset.md} +3 -7
  103. package/docs/configure/app/output/{clean-dist-path.mdx → clean-dist-path.md} +0 -4
  104. package/docs/configure/app/output/{convert-to-rem.mdx → convert-to-rem.md} +12 -16
  105. package/docs/configure/app/output/{copy.mdx → copy.md} +3 -7
  106. package/docs/configure/app/output/{css-modules.mdx → css-modules.md} +3 -7
  107. package/docs/configure/app/output/{data-uri-limit.mdx → data-uri-limit.md} +3 -7
  108. package/docs/configure/app/output/{disable-css-module-extension.mdx → disable-css-module-extension.md} +3 -7
  109. package/docs/configure/app/output/{disable-inline-runtime-chunk.mdx → disable-inline-runtime-chunk.md} +0 -4
  110. package/docs/configure/app/output/{disable-svgr.mdx → disable-svgr.md} +0 -4
  111. package/docs/configure/app/output/{disable-ts-checker.mdx → disable-ts-checker.md} +0 -4
  112. package/docs/configure/app/output/{dist-path.mdx → dist-path.md} +3 -11
  113. package/docs/configure/app/output/{enable-asset-manifest.mdx → enable-asset-manifest.md} +0 -4
  114. package/docs/configure/app/output/{enable-css-module-tsdeclaration.mdx → enable-css-module-tsdeclaration.md} +0 -4
  115. package/docs/configure/app/output/{enable-inline-route-manifests.mdx → enable-inline-route-manifests.md} +0 -4
  116. package/docs/configure/app/output/{externals.mdx → externals.md} +3 -7
  117. package/docs/configure/app/output/filename-hash.md +10 -0
  118. package/docs/configure/app/output/{filename.mdx → filename.md} +3 -7
  119. package/docs/configure/app/output/inject-styles.md +10 -0
  120. package/docs/configure/app/output/{inline-scripts.mdx → inline-scripts.md} +4 -8
  121. package/docs/configure/app/output/{inline-styles.mdx → inline-styles.md} +4 -8
  122. package/docs/configure/app/output/{legal-comments.mdx → legal-comments.md} +3 -7
  123. package/docs/configure/app/output/{minify.mdx → minify.md} +3 -7
  124. package/docs/configure/app/output/{override-browserslist.mdx → override-browserslist.md} +4 -8
  125. package/docs/configure/app/output/polyfill.md +12 -0
  126. package/docs/configure/app/output/{source-map.mdx → source-map.md} +3 -7
  127. package/docs/configure/app/output/{split-route-chunks.mdx → split-route-chunks.md} +0 -4
  128. package/docs/configure/app/output/{ssg.mdx → ssg.md} +3 -7
  129. package/docs/configure/app/output/{ssgByEntries.mdx → ssgByEntries.md} +1 -4
  130. package/docs/configure/app/output/{svg-default-export.mdx → svg-default-export.md} +0 -4
  131. package/docs/configure/app/output/{temp-dir.mdx → temp-dir.md} +0 -4
  132. package/docs/configure/app/performance/{build-cache.mdx → build-cache.md} +3 -7
  133. package/docs/configure/app/performance/{chunk-split.mdx → chunk-split.md} +3 -7
  134. package/docs/configure/app/performance/{dns-prefetch.mdx → dns-prefetch.md} +3 -7
  135. package/docs/configure/app/performance/preconnect.md +16 -0
  136. package/docs/configure/app/performance/{prefetch.mdx → prefetch.md} +3 -7
  137. package/docs/configure/app/performance/{preload.mdx → preload.md} +3 -7
  138. package/docs/configure/app/performance/{print-file-size.mdx → print-file-size.md} +3 -7
  139. package/docs/configure/app/performance/profile.md +10 -0
  140. package/docs/configure/app/performance/remove-console.md +10 -0
  141. package/docs/configure/app/performance/remove-moment-locale.md +10 -0
  142. package/docs/configure/app/performance/{rsdoctor.mdx → rsdoctor.md} +0 -4
  143. package/docs/configure/app/{plugins.mdx → plugins.md} +4 -4
  144. package/docs/configure/app/resolve/{alias-strategy.mdx → alias-strategy.md} +3 -7
  145. package/docs/configure/app/resolve/alias.md +9 -0
  146. package/docs/configure/app/resolve/{condition-names.mdx → condition-names.md} +3 -8
  147. package/docs/configure/app/resolve/{dedupe.mdx → dedupe.md} +3 -7
  148. package/docs/configure/app/resolve/{extensions.mdx → extensions.md} +3 -8
  149. package/docs/configure/app/runtime/{0-intro.mdx → 0-intro.md} +1 -4
  150. package/docs/configure/app/runtime/{plugins.mdx → plugins.md} +1 -1
  151. package/docs/configure/app/runtime/{router.mdx → router.md} +3 -7
  152. package/docs/configure/app/security/{check-syntax.mdx → check-syntax.md} +0 -4
  153. package/docs/configure/app/security/{nonce.mdx → nonce.md} +3 -7
  154. package/docs/configure/app/security/{sri.mdx → sri.md} +0 -4
  155. package/docs/configure/app/server/{base-url.mdx → base-url.md} +0 -4
  156. package/docs/configure/app/server/{port.mdx → port.md} +3 -7
  157. package/docs/configure/app/server/{public-routes.mdx → public-routes.md} +0 -4
  158. package/docs/configure/app/server/{routes.mdx → routes.md} +1 -5
  159. package/docs/configure/app/server/rsc.md +22 -0
  160. package/docs/configure/app/server/{ssr-by-entries.mdx → ssr-by-entries.md} +1 -5
  161. package/docs/configure/app/server/ssr.md +80 -0
  162. package/docs/configure/app/server/{tsconfig-path.mdx → tsconfig-path.md} +0 -4
  163. package/docs/configure/app/source/{alias-strategy.mdx → alias-strategy.md} +4 -8
  164. package/docs/configure/app/source/{alias.mdx → alias.md} +4 -8
  165. package/docs/configure/app/source/{config-dir.mdx → config-dir.md} +1 -5
  166. package/docs/configure/app/source/{decorators.mdx → decorators.md} +0 -4
  167. package/docs/configure/app/source/{define.mdx → define.md} +3 -7
  168. package/docs/configure/app/source/{disable-default-entries.mdx → disable-default-entries.md} +2 -6
  169. package/docs/{components/module-federation.mdx → configure/app/source/enable-async-entry.md} +47 -0
  170. package/docs/configure/app/source/{enable-async-pre-entry.mdx → enable-async-pre-entry.md} +0 -4
  171. package/docs/configure/app/source/{entries-dir.mdx → entries-dir.md} +0 -4
  172. package/docs/configure/app/source/{entries.mdx → entries.md} +1 -5
  173. package/docs/configure/app/source/{exclude.mdx → exclude.md} +4 -8
  174. package/docs/configure/app/source/{global-vars.mdx → global-vars.md} +0 -4
  175. package/docs/configure/app/source/{include.mdx → include.md} +4 -8
  176. package/docs/configure/app/source/{main-entry-name.mdx → main-entry-name.md} +0 -4
  177. package/docs/configure/app/source/{pre-entry.mdx → pre-entry.md} +3 -7
  178. package/docs/configure/app/source/{react-compiler.mdx → react-compiler.md} +0 -4
  179. package/docs/configure/app/source/{transform-import.mdx → transform-import.md} +3 -7
  180. package/docs/configure/app/{split-chunks.mdx → split-chunks.md} +3 -3
  181. package/docs/configure/app/tools/{autoprefixer.mdx → autoprefixer.md} +0 -4
  182. package/docs/configure/app/tools/{bundler-chain.mdx → bundler-chain.md} +0 -4
  183. package/docs/configure/app/tools/{css-extract.mdx → css-extract.md} +3 -7
  184. package/docs/configure/app/tools/{css-loader.mdx → css-loader.md} +3 -7
  185. package/docs/configure/app/tools/{dev-server.mdx → dev-server.md} +0 -4
  186. package/docs/configure/app/tools/{html-plugin.mdx → html-plugin.md} +3 -7
  187. package/docs/configure/app/tools/{less.mdx → less.md} +0 -4
  188. package/docs/configure/app/tools/{lightningcss-loader.mdx → lightningcss-loader.md} +3 -7
  189. package/docs/configure/app/tools/{minify-css.mdx → minify-css.md} +0 -4
  190. package/docs/configure/app/tools/{postcss.mdx → postcss.md} +3 -7
  191. package/docs/configure/app/tools/rspack.md +10 -0
  192. package/docs/configure/app/tools/{sass.mdx → sass.md} +0 -4
  193. package/docs/configure/app/tools/style-loader.md +10 -0
  194. package/docs/configure/app/tools/{swc.mdx → swc.md} +4 -8
  195. package/docs/configure/app/tools/{ts-checker.mdx → ts-checker.md} +20 -7
  196. package/docs/configure/app/{usage.mdx → usage.md} +1 -1
  197. package/docs/guides/advanced-features/bff/{cross-project.mdx → cross-project.md} +1 -2
  198. package/docs/guides/advanced-features/bff/{data-platform.mdx → data-platform.md} +0 -4
  199. package/docs/guides/advanced-features/bff/{extend-server.mdx → extend-server.md} +1 -1
  200. package/docs/guides/advanced-features/bff/frameworks.md +243 -0
  201. package/docs/guides/advanced-features/bff/{function.mdx → function.md} +60 -7
  202. package/docs/guides/advanced-features/bff/{operators.mdx → operators.md} +2 -77
  203. package/docs/{components/bff-upload.mdx → guides/advanced-features/bff/upload.md} +4 -0
  204. package/docs/guides/advanced-features/{bff.mdx → bff.md} +0 -4
  205. package/docs/guides/advanced-features/{build-performance.mdx → build-performance.md} +3 -7
  206. package/docs/guides/advanced-features/{compatibility.mdx → compatibility.md} +54 -15
  207. package/docs/guides/advanced-features/international/{advanced.mdx → advanced.md} +0 -4
  208. package/docs/guides/advanced-features/international/{api.mdx → api.md} +16 -20
  209. package/docs/guides/advanced-features/international/{best-practices.mdx → best-practices.md} +0 -4
  210. package/docs/guides/advanced-features/international/configuration.md +228 -0
  211. package/docs/guides/advanced-features/international/{locale-detection.mdx → locale-detection.md} +25 -29
  212. package/docs/guides/advanced-features/international/{quick-start.mdx → quick-start.md} +29 -13
  213. package/docs/guides/advanced-features/international/{resource-loading.mdx → resource-loading.md} +11 -15
  214. package/docs/guides/advanced-features/international/{routing.mdx → routing.md} +12 -16
  215. package/docs/guides/advanced-features/international.md +27 -0
  216. package/docs/guides/advanced-features/{low-level.mdx → low-level.md} +17 -21
  217. package/docs/guides/advanced-features/page-performance/{code-split.mdx → code-split.md} +2 -6
  218. package/docs/guides/advanced-features/page-performance/{inline-assets.mdx → inline-assets.md} +3 -7
  219. package/docs/guides/advanced-features/page-performance/{optimize-bundle.mdx → optimize-bundle.md} +4 -8
  220. package/docs/{components/internal-logger.mdx → guides/advanced-features/server-monitor/logger.md} +16 -0
  221. package/docs/guides/advanced-features/server-monitor/metrics.md +58 -0
  222. package/docs/guides/advanced-features/server-monitor/{monitors.mdx → monitors.md} +3 -3
  223. package/docs/guides/advanced-features/{source-build.mdx → source-build.md} +1 -5
  224. package/docs/guides/advanced-features/{web-server.mdx → web-server.md} +1 -9
  225. package/docs/guides/basic-features/{alias.mdx → alias.md} +3 -7
  226. package/docs/guides/basic-features/css/{css-in-js.mdx → css-in-js.md} +12 -9
  227. package/docs/guides/basic-features/css/{css-modules.mdx → css-modules.md} +3 -3
  228. package/docs/guides/basic-features/css/{css.mdx → css.md} +2 -6
  229. package/docs/guides/basic-features/data/{data-cache.mdx → data-cache.md} +1 -6
  230. package/docs/guides/basic-features/data/{data-fetch.mdx → data-fetch.md} +4 -8
  231. package/docs/guides/basic-features/data/{data-write.mdx → data-write.md} +6 -9
  232. package/docs/guides/basic-features/debug/{mock.mdx → mock.md} +1 -5
  233. package/docs/guides/basic-features/debug/{proxy.mdx → proxy.md} +1 -5
  234. package/docs/guides/basic-features/debug/{using-storybook.mdx → using-storybook.md} +20 -8
  235. package/docs/guides/basic-features/{deploy.mdx → deploy.md} +23 -13
  236. package/docs/guides/basic-features/{env-vars.mdx → env-vars.md} +8 -12
  237. package/docs/guides/basic-features/{html.mdx → html.md} +3 -7
  238. package/docs/guides/basic-features/{output-files.mdx → output-files.md} +6 -10
  239. package/docs/guides/basic-features/render/{before-render.mdx → before-render.md} +1 -1
  240. package/docs/guides/basic-features/render/overview.md +47 -0
  241. package/docs/guides/basic-features/render/{rsc.mdx → rsc.md} +16 -33
  242. package/docs/guides/basic-features/render/{ssg.mdx → ssg.md} +71 -10
  243. package/docs/guides/basic-features/render/{ssr-cache.mdx → ssr-cache.md} +5 -5
  244. package/docs/guides/basic-features/render/{ssr.mdx → ssr.md} +10 -12
  245. package/docs/guides/basic-features/render/{streaming-ssr.mdx → streaming-ssr.md} +5 -8
  246. package/docs/guides/basic-features/routes/{config-routes.mdx → config-routes.md} +10 -11
  247. package/docs/guides/basic-features/routes/{routes.mdx → routes.md} +8 -16
  248. package/docs/guides/basic-features/static-assets/{json-files.mdx → json-files.md} +0 -4
  249. package/docs/guides/basic-features/static-assets/{svg-assets.mdx → svg-assets.md} +3 -7
  250. package/docs/guides/basic-features/static-assets/{wasm-assets.mdx → wasm-assets.md} +1 -5
  251. package/docs/guides/basic-features/{static-assets.mdx → static-assets.md} +10 -14
  252. package/docs/guides/basic-features/testing/{playwright.mdx → playwright.md} +12 -3
  253. package/docs/guides/basic-features/testing/{rstest.mdx → rstest.md} +70 -11
  254. package/docs/guides/concept/{builder.mdx → builder.md} +3 -26
  255. package/docs/guides/concept/{entries.mdx → entries.md} +11 -17
  256. package/docs/guides/concept/{server.mdx → server.md} +3 -3
  257. package/docs/guides/get-started/{ai-coding-agents.mdx → ai-coding-agents.md} +4 -9
  258. package/docs/guides/get-started/glossary.md +63 -0
  259. package/docs/guides/get-started/{introduction.mdx → introduction.md} +1 -6
  260. package/docs/guides/get-started/quick-start.md +269 -0
  261. package/docs/guides/get-started/{tech-stack.mdx → tech-stack.md} +9 -15
  262. package/docs/guides/get-started/{ultramodern.mdx → ultramodern.md} +38 -31
  263. package/docs/guides/get-started/{upgrade.mdx → upgrade.md} +26 -22
  264. package/docs/guides/topic-detail/module-federation/{application.mdx → application.md} +3 -3
  265. package/docs/guides/topic-detail/module-federation/{deploy.mdx → deploy.md} +2 -2
  266. package/docs/guides/topic-detail/module-federation/{i18n.mdx → i18n.md} +14 -14
  267. package/docs/guides/topic-detail/module-federation/{introduce.mdx → introduce.md} +2 -3
  268. package/docs/guides/topic-detail/module-federation/{ssr.mdx → ssr.md} +12 -7
  269. package/docs/guides/topic-detail/module-federation/{usage.mdx → usage.md} +20 -3
  270. package/docs/guides/troubleshooting/{builder.mdx → builder.md} +10 -14
  271. package/docs/guides/troubleshooting/{cli.mdx → cli.md} +0 -4
  272. package/docs/guides/troubleshooting/{dependencies.mdx → dependencies.md} +7 -11
  273. package/docs/guides/troubleshooting/{hmr.mdx → hmr.md} +5 -9
  274. package/docs/guides/upgrade/{config.mdx → config.md} +8 -5
  275. package/docs/guides/upgrade/{entry.mdx → entry.md} +6 -6
  276. package/docs/guides/upgrade/{other.mdx → other.md} +8 -8
  277. package/docs/guides/upgrade/{overview.mdx → overview.md} +4 -4
  278. package/docs/guides/upgrade/{tailwindcss.mdx → tailwindcss.md} +0 -1
  279. package/docs/guides/upgrade/web-server.md +11 -11
  280. package/docs/index.md +33 -4
  281. package/docs/llms.txt +290 -0
  282. package/docs/plugin/cli-plugins/api.md +573 -0
  283. package/docs/plugin/cli-plugins/life-cycle.md +2 -0
  284. package/docs/plugin/introduction.md +152 -0
  285. package/docs/plugin/official/cli-plugins/plugin-bff.md +5 -0
  286. package/docs/plugin/official/cli-plugins/plugin-ssg.md +5 -0
  287. package/docs/plugin/official/cli-plugins/plugin-styled-components.md +5 -0
  288. package/docs/plugin/official/cli-plugins.md +4 -0
  289. package/docs/plugin/plugin-system.md +238 -0
  290. package/docs/plugin/runtime-plugins/api.md +194 -0
  291. package/docs/plugin/runtime-plugins/life-cycle.md +2 -0
  292. package/docs/plugin/server-plugins/api.md +209 -0
  293. package/docs/plugin/server-plugins/life-cycle.md +13 -0
  294. package/docs/tutorials/examples/csr-auth.md +9 -0
  295. package/docs/tutorials/foundations/introduction.md +16 -0
  296. package/package.json +33 -15
  297. package/docs/_nav.json +0 -36
  298. package/docs/apis/_meta.json +0 -13
  299. package/docs/apis/app/hooks/_meta.json +0 -28
  300. package/docs/apis/app/hooks/config/_meta.json +0 -1
  301. package/docs/apis/app/runtime/_meta.json +0 -32
  302. package/docs/components/auto-upgrade.mdx +0 -0
  303. package/docs/components/build-output.mdx +0 -45
  304. package/docs/components/bundler.mdx +0 -3
  305. package/docs/components/convention-routing-motivation.mdx +0 -0
  306. package/docs/components/debug-app.mdx +0 -15
  307. package/docs/components/default-browserslist.mdx +0 -7
  308. package/docs/components/deploy-command.mdx +0 -14
  309. package/docs/components/deploy.mdx +0 -1
  310. package/docs/components/enable-bff-caution.mdx +0 -3
  311. package/docs/components/enable-bff.mdx +0 -56
  312. package/docs/components/enable-ssg.mdx +0 -49
  313. package/docs/components/entry-mode.mdx +0 -0
  314. package/docs/components/entry-scan-logic.mdx +0 -7
  315. package/docs/components/extend-bff-function.mdx +0 -3
  316. package/docs/components/hono.mdx +0 -120
  317. package/docs/components/init-app.mdx +0 -93
  318. package/docs/components/init-rspack-app.mdx +0 -5
  319. package/docs/components/internal-metrics.mdx +0 -20
  320. package/docs/components/international/custom-instance-code.mdx +0 -16
  321. package/docs/components/international/init-options-desc.mdx +0 -1
  322. package/docs/components/international/install-command.mdx +0 -10
  323. package/docs/components/international/instance-code.mdx +0 -16
  324. package/docs/components/international/introduce.mdx +0 -5
  325. package/docs/components/international/platform-support.mdx +0 -0
  326. package/docs/components/language-config.mdx +0 -9
  327. package/docs/components/micro-frontend.mdx +0 -6
  328. package/docs/components/micro-master-manifest-config.mdx +0 -15
  329. package/docs/components/micro-runtime-config.mdx +0 -17
  330. package/docs/components/new-entry-tooltip.mdx +0 -0
  331. package/docs/components/nodeVersion.mdx +0 -28
  332. package/docs/components/other-plugins.mdx +0 -0
  333. package/docs/components/output-asset-prefix-extend.mdx +0 -0
  334. package/docs/components/output-distpath-warning.mdx +0 -0
  335. package/docs/components/output-polyfill-extend.mdx +0 -1
  336. package/docs/components/prerequisites.mdx +0 -18
  337. package/docs/components/release-note.mdx +0 -1
  338. package/docs/components/routes-practice.mdx +0 -0
  339. package/docs/components/rsbuild-config-tooltip.mdx +0 -5
  340. package/docs/components/rsbuild.mdx +0 -3
  341. package/docs/components/rsc-deploy-tip.mdx +0 -1
  342. package/docs/components/rspack.mdx +0 -3
  343. package/docs/components/rspackTip.mdx +0 -7
  344. package/docs/components/runtime-cli-config.mdx +0 -0
  345. package/docs/components/serve-command.mdx +0 -22
  346. package/docs/components/ssr-monitor.mdx +0 -3
  347. package/docs/components/stream-ssr-performance.mdx +0 -0
  348. package/docs/components/swc.mdx +0 -3
  349. package/docs/components/tech-stack-node-framework.mdx +0 -1
  350. package/docs/components/turtorials-example-list.mdx +0 -2
  351. package/docs/components/ua-polyfill.mdx +0 -44
  352. package/docs/components/upgrade-browserslist.mdx +0 -0
  353. package/docs/components/upgrade-config-deploy.mdx +0 -0
  354. package/docs/components/upgrade-faq.mdx +0 -0
  355. package/docs/configure/_meta.json +0 -78
  356. package/docs/configure/app/dev/hmr.mdx +0 -14
  357. package/docs/configure/app/dev/live-reload.mdx +0 -14
  358. package/docs/configure/app/dev/progress-bar.mdx +0 -23
  359. package/docs/configure/app/html/inject.mdx +0 -14
  360. package/docs/configure/app/html/output-structure.mdx +0 -14
  361. package/docs/configure/app/html/script-loading.mdx +0 -14
  362. package/docs/configure/app/html/template.mdx +0 -14
  363. package/docs/configure/app/html/title.mdx +0 -22
  364. package/docs/configure/app/output/asset-prefix.mdx +0 -18
  365. package/docs/configure/app/output/filename-hash.mdx +0 -14
  366. package/docs/configure/app/output/inject-styles.mdx +0 -14
  367. package/docs/configure/app/output/polyfill.mdx +0 -18
  368. package/docs/configure/app/performance/preconnect.mdx +0 -20
  369. package/docs/configure/app/performance/profile.mdx +0 -14
  370. package/docs/configure/app/performance/remove-console.mdx +0 -14
  371. package/docs/configure/app/performance/remove-moment-locale.mdx +0 -14
  372. package/docs/configure/app/resolve/alias.mdx +0 -13
  373. package/docs/configure/app/server/rsc.mdx +0 -30
  374. package/docs/configure/app/server/ssr.mdx +0 -85
  375. package/docs/configure/app/source/enable-async-entry.mdx +0 -54
  376. package/docs/configure/app/tools/rspack.mdx +0 -14
  377. package/docs/configure/app/tools/style-loader.mdx +0 -14
  378. package/docs/guides/_meta.json +0 -37
  379. package/docs/guides/advanced-features/_meta.json +0 -32
  380. package/docs/guides/advanced-features/bff/_meta.json +0 -10
  381. package/docs/guides/advanced-features/bff/frameworks.mdx +0 -131
  382. package/docs/guides/advanced-features/bff/upload.mdx +0 -7
  383. package/docs/guides/advanced-features/international/_meta.json +0 -10
  384. package/docs/guides/advanced-features/international/configuration.mdx +0 -222
  385. package/docs/guides/advanced-features/international.mdx +0 -29
  386. package/docs/guides/advanced-features/page-performance/_meta.json +0 -1
  387. package/docs/guides/advanced-features/server-monitor/_meta.json +0 -1
  388. package/docs/guides/advanced-features/server-monitor/logger.mdx +0 -19
  389. package/docs/guides/advanced-features/server-monitor/metrics.mdx +0 -41
  390. package/docs/guides/basic-features/_meta.json +0 -49
  391. package/docs/guides/basic-features/css/_meta.json +0 -1
  392. package/docs/guides/basic-features/data/_meta.json +0 -1
  393. package/docs/guides/basic-features/debug/_meta.json +0 -1
  394. package/docs/guides/basic-features/render/_meta.json +0 -1
  395. package/docs/guides/basic-features/render/overview.mdx +0 -51
  396. package/docs/guides/basic-features/routes/_meta.json +0 -1
  397. package/docs/guides/basic-features/static-assets/_meta.json +0 -1
  398. package/docs/guides/basic-features/testing/_meta.json +0 -1
  399. package/docs/guides/concept/_meta.json +0 -1
  400. package/docs/guides/get-started/_meta.json +0 -9
  401. package/docs/guides/get-started/glossary.mdx +0 -63
  402. package/docs/guides/get-started/quick-start.mdx +0 -92
  403. package/docs/guides/topic-detail/_meta.json +0 -8
  404. package/docs/guides/topic-detail/module-federation/_meta.json +0 -1
  405. package/docs/guides/troubleshooting/_meta.json +0 -1
  406. package/docs/guides/upgrade/_meta.json +0 -1
  407. package/scripts/copy-main-doc.mjs +0 -50
  408. /package/docs/guides/advanced-features/bff/{sdk.mdx → sdk.md} +0 -0
  409. /package/docs/guides/advanced-features/page-performance/{react-compiler.mdx → react-compiler.md} +0 -0
  410. /package/docs/guides/basic-features/css/{tailwindcss.mdx → tailwindcss.md} +0 -0
  411. /package/docs/guides/basic-features/debug/{rsdoctor.mdx → rsdoctor.md} +0 -0
@@ -1,42 +1,15 @@
1
+ import { createHash } from "node:crypto";
1
2
  import promises from "node:fs/promises";
2
3
  import node_path from "node:path";
3
- import { parse } from "@babel/parser";
4
4
  import { BACKEND_FEDERATION_MANIFEST_FILE, BACKEND_FEDERATION_REMOTE_ENTRY_FILE, ULTRAMODERN_BUILD_ARTIFACT_FILE, isUltramodernBuildArtifact } from "@modern-js/utils/universal";
5
5
  import { canonicalSerializeMicroVerticalReleaseEnvelope, createMicroVerticalReleaseEnvelope, verifyMicroVerticalReleaseEnvelope } from "./index.mjs";
6
6
  const MICROVERTICAL_RELEASE_ENVELOPE_PATH = 'release/microvertical-release-envelope.json';
7
+ const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH = 'release/microvertical-release-identity-carriers.json';
8
+ const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_KIND = 'ultramodern-release-identity-carriers';
9
+ const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_SCHEMA_VERSION = 1;
7
10
  const COMPILED_MODULE_PATTERN = /\.(?:c|m)?js$/u;
8
11
  const EFFECT_BFF_WORKER_PATTERN = /^worker\/__modern_bff_effect\.(?:c|m)?js$/u;
9
12
  const isRecord = (value)=>'object' == typeof value && null !== value && !Array.isArray(value);
10
- const isAstNode = (value)=>isRecord(value) && 'string' == typeof value.type;
11
- const visitAst = (node, visitor)=>{
12
- visitor(node);
13
- for (const value of Object.values(node))if (isAstNode(value)) visitAst(value, visitor);
14
- else if (Array.isArray(value)) {
15
- for (const item of value)if (isAstNode(item)) visitAst(item, visitor);
16
- }
17
- };
18
- const compiledModuleIdentityValues = (source)=>{
19
- const values = new Set();
20
- const ast = parse(source, {
21
- sourceType: 'unambiguous'
22
- });
23
- visitAst(ast.program, (node)=>{
24
- if ('StringLiteral' === node.type && 'string' == typeof node.value) values.add(node.value);
25
- else if ('TemplateElement' === node.type && isRecord(node.value) && 'string' == typeof node.value.cooked) values.add(node.value.cooked);
26
- });
27
- return values;
28
- };
29
- const assertEveryCompiledIdentityCarrier = async (distDirectory, logicalPaths, identity, surface)=>{
30
- const compiledLogicalPaths = logicalPaths.filter((pathname)=>COMPILED_MODULE_PATTERN.test(pathname));
31
- if (0 === compiledLogicalPaths.length) throw new Error(`[ultramodern-release-envelope] ${surface} has no compiled execution module carrying release identity.`);
32
- for (const logicalPath of compiledLogicalPaths){
33
- const source = await promises.readFile(node_path.join(distDirectory, logicalPath), {
34
- encoding: 'utf8'
35
- });
36
- const values = compiledModuleIdentityValues(source);
37
- if (!values.has(identity.buildMarker) || !values.has(identity.sourceRevision) || !values.has(identity.releaseVersion)) throw new Error(`[ultramodern-release-envelope] ${surface} execution module ${logicalPath} does not carry exact buildMarker ${identity.buildMarker}, sourceRevision ${identity.sourceRevision}, and releaseVersion ${identity.releaseVersion}.`);
38
- }
39
- };
40
13
  const flattenStrings = (value)=>'string' == typeof value ? [
41
14
  value
42
15
  ] : Array.isArray(value) ? value.flatMap(flattenStrings) : [];
@@ -179,6 +152,49 @@ const releaseArtifact = (logicalPath, runtime)=>({
179
152
  logicalPath,
180
153
  runtime
181
154
  });
155
+ const writeReleaseIdentityCarrierMetadata = async (artifactRoot, identity, carrierPaths)=>{
156
+ const surfacesByPath = new Map();
157
+ for (const [surface, logicalPaths] of Object.entries(carrierPaths)){
158
+ if (0 === logicalPaths.length) throw new Error(`[ultramodern-release-envelope] ${surface} has no declared release-identity carrier artifact.`);
159
+ for (const logicalPath of logicalPaths){
160
+ const surfaces = surfacesByPath.get(logicalPath) ?? new Set();
161
+ surfaces.add(surface);
162
+ surfacesByPath.set(logicalPath, surfaces);
163
+ }
164
+ }
165
+ const carriers = await Promise.all([
166
+ ...surfacesByPath
167
+ ].sort(([left], [right])=>left.localeCompare(right)).map(async ([logicalPath, surfaces])=>{
168
+ const bytes = await promises.readFile(node_path.join(artifactRoot, logicalPath));
169
+ return {
170
+ logicalPath,
171
+ byteLength: bytes.byteLength,
172
+ sha256: createHash('sha256').update(bytes).digest('hex'),
173
+ surfaces: [
174
+ ...surfaces
175
+ ].sort((left, right)=>left.localeCompare(right))
176
+ };
177
+ }));
178
+ const releaseEnvelopePath = await resolveSafeReleaseEnvelopePath({
179
+ artifactRoot,
180
+ createDirectory: true
181
+ });
182
+ if (!releaseEnvelopePath) throw new Error('[ultramodern-release-envelope] could not resolve private release metadata directory.');
183
+ const metadataPath = node_path.join(node_path.dirname(releaseEnvelopePath), node_path.basename(MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH));
184
+ try {
185
+ const metadataStat = await promises.lstat(metadataPath);
186
+ if (metadataStat.isSymbolicLink() || !metadataStat.isFile()) throw new Error('[ultramodern-release-envelope] release identity carrier metadata must be a real file inside artifactRoot.');
187
+ } catch (error) {
188
+ if (!isMissingPathError(error)) throw error;
189
+ }
190
+ await promises.writeFile(metadataPath, `${JSON.stringify({
191
+ schemaVersion: MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_SCHEMA_VERSION,
192
+ kind: MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_KIND,
193
+ identity,
194
+ carriers
195
+ }, null, 2)}\n`);
196
+ return releaseArtifact(MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH, 'release-identity-metadata');
197
+ };
182
198
  const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
183
199
  const files = await collectFiles(distDirectory);
184
200
  if ('node' === target && files.some((logicalPath)=>EFFECT_BFF_WORKER_PATTERN.test(logicalPath))) throw new Error('[ultramodern-release-envelope] Node target conflicts with a Cloudflare Effect API/BFF worker artifact; resolve the canonical deploy target instead of emitting a Node envelope for Cloudflare output.');
@@ -202,13 +218,7 @@ const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
202
218
  const clientExecutionPaths = await manifestReferencedClientModules(distDirectory, files);
203
219
  if (0 === clientExecutionPaths.length) throw new Error('[ultramodern-release-envelope] UI/client manifest references no compiled execution module.');
204
220
  const ssrExecutionPaths = await routeReferencedSsrModules(distDirectory, files, target);
205
- await assertEveryCompiledIdentityCarrier(distDirectory, clientExecutionPaths, identity, 'manifest-referenced UI/client');
206
- await assertEveryCompiledIdentityCarrier(distDirectory, ssrExecutionPaths, identity, 'node' === target ? 'route-referenced Node SSR' : 'route-referenced Cloudflare SSR');
207
- await assertEveryCompiledIdentityCarrier(distDirectory, ssrPaths, identity, 'node' === target ? 'compiled Node SSR closure' : 'compiled Cloudflare SSR/workerd closure');
208
- await assertEveryCompiledIdentityCarrier(distDirectory, 'node' === target ? nodeApiEntryPaths : apiBackendPaths, identity, 'node' === target ? 'Node API/backend' : 'Cloudflare API/backend');
209
- await assertEveryCompiledIdentityCarrier(distDirectory, [
210
- BACKEND_FEDERATION_REMOTE_ENTRY_FILE
211
- ], identity, 'backend Module Federation container');
221
+ if (0 === ssrExecutionPaths.length) throw new Error(`[ultramodern-release-envelope] route manifest references no emitted ${'node' === target ? 'Node' : 'Cloudflare'} SSR execution module.`);
212
222
  const runtimeByPath = new Map();
213
223
  const add = (paths, runtime)=>{
214
224
  for (const logicalPath of paths){
@@ -244,8 +254,25 @@ const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
244
254
  const artifacts = [
245
255
  ...runtimeByPath
246
256
  ].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)).sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath));
257
+ const identityCarrierMetadata = await writeReleaseIdentityCarrierMetadata(distDirectory, identity, {
258
+ apiBackend: apiBackendPaths,
259
+ backendFederation: [
260
+ BACKEND_FEDERATION_MANIFEST_FILE,
261
+ BACKEND_FEDERATION_REMOTE_ENTRY_FILE
262
+ ],
263
+ ssr: [
264
+ ...new Set([
265
+ ...ssrExecutionPaths,
266
+ ...ssrPaths
267
+ ])
268
+ ],
269
+ uiClient: uiClientPaths.filter((logicalPath)=>COMPILED_MODULE_PATTERN.test(logicalPath))
270
+ });
247
271
  return {
248
- artifacts,
272
+ artifacts: [
273
+ ...artifacts,
274
+ identityCarrierMetadata
275
+ ].sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath)),
249
276
  surfaces
250
277
  };
251
278
  };
@@ -367,13 +394,7 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
367
394
  ])if (0 === paths.length) throw new Error(`[ultramodern-release-envelope] final Node staging has no ${surface} artifacts.`);
368
395
  const clientExecutionPaths = await manifestReferencedClientModules(outputDirectory, files);
369
396
  const ssrExecutionPaths = await routeReferencedSsrModules(outputDirectory, files, 'node');
370
- await assertEveryCompiledIdentityCarrier(outputDirectory, clientExecutionPaths, identity, 'final manifest-referenced Node UI/client');
371
- await assertEveryCompiledIdentityCarrier(outputDirectory, ssrExecutionPaths, identity, 'final route-referenced Node SSR');
372
- await assertEveryCompiledIdentityCarrier(outputDirectory, ssrPaths.filter((logicalPath)=>'index.js' !== logicalPath), identity, 'final compiled Node SSR closure');
373
- await assertEveryCompiledIdentityCarrier(outputDirectory, apiBackendPaths.filter((logicalPath)=>logicalPath.startsWith('api/')), identity, 'final Node API/backend');
374
- await assertEveryCompiledIdentityCarrier(outputDirectory, [
375
- BACKEND_FEDERATION_REMOTE_ENTRY_FILE
376
- ], identity, 'final Node backend Module Federation container');
397
+ if (0 === clientExecutionPaths.length || 0 === ssrExecutionPaths.length) throw new Error('[ultramodern-release-envelope] final Node manifests must reference emitted UI/client and SSR execution modules.');
377
398
  const runtimeByPath = new Map(files.filter((logicalPath)=>!backendFederationPaths.has(logicalPath)).map((logicalPath)=>[
378
399
  logicalPath,
379
400
  'nodejs-deployment'
@@ -383,10 +404,27 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
383
404
  for (const logicalPath of apiBackendPaths)runtimeByPath.set(logicalPath, 'nodejs');
384
405
  runtimeByPath.set(BACKEND_FEDERATION_MANIFEST_FILE, 'module-federation-manifest');
385
406
  runtimeByPath.set(BACKEND_FEDERATION_REMOTE_ENTRY_FILE, 'nodejs');
407
+ const identityCarrierMetadata = await writeReleaseIdentityCarrierMetadata(outputDirectory, identity, {
408
+ apiBackend: apiBackendPaths,
409
+ backendFederation: [
410
+ BACKEND_FEDERATION_MANIFEST_FILE,
411
+ BACKEND_FEDERATION_REMOTE_ENTRY_FILE
412
+ ],
413
+ ssr: [
414
+ ...new Set([
415
+ ...ssrExecutionPaths,
416
+ ...ssrPaths.filter((logicalPath)=>'index.js' !== logicalPath)
417
+ ])
418
+ ],
419
+ uiClient: uiClientPaths.filter((logicalPath)=>COMPILED_MODULE_PATTERN.test(logicalPath))
420
+ });
386
421
  return {
387
422
  artifacts: [
388
- ...runtimeByPath
389
- ].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)).sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath)),
423
+ ...[
424
+ ...runtimeByPath
425
+ ].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)),
426
+ identityCarrierMetadata
427
+ ].sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath)),
390
428
  surfaces: {
391
429
  uiClient: [
392
430
  ...uiClientPaths
@@ -460,13 +498,7 @@ const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, iden
460
498
  ])if (!files.includes(logicalPath)) throw new Error(`[ultramodern-release-envelope] final Cloudflare staging is missing ${logicalPath}.`);
461
499
  const clientExecutionPaths = await manifestReferencedClientModules(outputDirectory, files, 'public/mf-manifest.json');
462
500
  const ssrExecutionPaths = await routeReferencedSsrModules(outputDirectory, files, 'cloudflare', 'server/route.json');
463
- await assertEveryCompiledIdentityCarrier(outputDirectory, clientExecutionPaths, identity, 'final manifest-referenced Cloudflare UI/client');
464
- await assertEveryCompiledIdentityCarrier(outputDirectory, ssrExecutionPaths, identity, 'final route-referenced Cloudflare SSR');
465
- await assertEveryCompiledIdentityCarrier(outputDirectory, ssrPaths.filter((logicalPath)=>logicalPath.startsWith('worker/')), identity, 'final compiled Cloudflare SSR/workerd closure');
466
- await assertEveryCompiledIdentityCarrier(outputDirectory, apiBackendPaths, identity, 'final Cloudflare API/backend');
467
- await assertEveryCompiledIdentityCarrier(outputDirectory, [
468
- backendContainerPath
469
- ], identity, 'final Cloudflare backend Module Federation container');
501
+ if (0 === clientExecutionPaths.length || 0 === ssrExecutionPaths.length) throw new Error('[ultramodern-release-envelope] final Cloudflare manifests must reference emitted UI/client and SSR execution modules.');
470
502
  const runtimeByPath = new Map();
471
503
  for (const logicalPath of files)runtimeByPath.set(logicalPath, 'cloudflare-deployment');
472
504
  const add = (paths, runtime)=>{
@@ -481,10 +513,27 @@ const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, iden
481
513
  add([
482
514
  backendContainerPath
483
515
  ], 'commonjs-module');
516
+ const identityCarrierMetadata = await writeReleaseIdentityCarrierMetadata(outputDirectory, identity, {
517
+ apiBackend: apiBackendPaths,
518
+ backendFederation: [
519
+ backendManifestPath,
520
+ backendContainerPath
521
+ ],
522
+ ssr: [
523
+ ...new Set([
524
+ ...ssrExecutionPaths,
525
+ ...ssrPaths.filter((logicalPath)=>logicalPath.startsWith('worker/'))
526
+ ])
527
+ ],
528
+ uiClient: uiClientPaths.filter((logicalPath)=>COMPILED_MODULE_PATTERN.test(logicalPath))
529
+ });
484
530
  return {
485
531
  artifacts: [
486
- ...runtimeByPath
487
- ].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)).sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath)),
532
+ ...[
533
+ ...runtimeByPath
534
+ ].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)),
535
+ identityCarrierMetadata
536
+ ].sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath)),
488
537
  surfaces: {
489
538
  uiClient: [
490
539
  ...uiClientPaths
@@ -521,4 +570,4 @@ const verifyCloudflareReleaseEnvelopeStaging = async (outputDirectory)=>readFram
521
570
  expectedTarget: 'cloudflare',
522
571
  required: true
523
572
  });
524
- export { MICROVERTICAL_RELEASE_ENVELOPE_PATH, emitCloudflareStagedReleaseEnvelope, emitFrameworkMicroVerticalReleaseEnvelope, emitNodeStagedReleaseEnvelope, readFrameworkMicroVerticalReleaseEnvelope, stageCloudflareReleaseEnvelope, verifyBuildOutputReleaseEnvelope, verifyCloudflareReleaseEnvelopeStaging, verifyNodeReleaseEnvelopeStaging };
573
+ export { MICROVERTICAL_RELEASE_ENVELOPE_PATH, MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH, emitCloudflareStagedReleaseEnvelope, emitFrameworkMicroVerticalReleaseEnvelope, emitNodeStagedReleaseEnvelope, readFrameworkMicroVerticalReleaseEnvelope, stageCloudflareReleaseEnvelope, verifyBuildOutputReleaseEnvelope, verifyCloudflareReleaseEnvelopeStaging, verifyNodeReleaseEnvelopeStaging };
@@ -10,6 +10,8 @@ import { dirname as __rspack_dirname } from "node:path";
10
10
  var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
11
11
  const BFF_EFFECT_WORKER_ENTRY_NAME = '__modern_bff_effect';
12
12
  const BFF_EFFECT_WORKER_RUNTIME_QUERY = 'modern-bff-runtime';
13
+ const MF_SSR_DATA_FETCH_RUNTIME_PLUGIN = '@module-federation/modern-js-v3/ssr-inject-data-fetch-function-plugin';
14
+ const MF_SSR_DEV_RUNTIME_PLUGIN = '@module-federation/modern-js-v3/ssr-dev-plugin';
13
15
  const JS_OR_TS_EXTS = [
14
16
  '.js',
15
17
  '.jsx',
@@ -90,6 +92,64 @@ function getCloudflareWorkerNodeExternals() {
90
92
  ];
91
93
  }));
92
94
  }
95
+ const reserveWorkerChunkName = (baseName, reservedOutputNames)=>{
96
+ let name = baseName;
97
+ while(reservedOutputNames.has(normalizeWorkerOutputName(name)))name = `${name}_`;
98
+ return name;
99
+ };
100
+ const normalizeWorkerOutputName = (name)=>node_path.posix.normalize(name.replace(/\\/gu, '/')).toLowerCase();
101
+ function getCloudflareWorkerRspackConfig(workerEntryNames) {
102
+ const entryNames = [
103
+ ...workerEntryNames
104
+ ];
105
+ for (const entryName of entryNames){
106
+ const slashName = entryName.replace(/\\/gu, '/');
107
+ const normalizedName = node_path.posix.normalize(slashName);
108
+ if (entryName !== slashName || normalizedName !== slashName || '.' === normalizedName || normalizedName.startsWith('../') || node_path.posix.isAbsolute(normalizedName) || node_path.win32.isAbsolute(slashName) || /^[A-Za-z]:/u.test(slashName)) throw new Error(`Cloudflare worker entry name "${entryName}" must be a canonical relative output path without dot segments or backslashes.`);
109
+ }
110
+ const reservedNames = new Set(entryNames.map(normalizeWorkerOutputName));
111
+ const runtimeName = reserveWorkerChunkName('__modern_worker_runtime', reservedNames);
112
+ reservedNames.add(normalizeWorkerOutputName(runtimeName));
113
+ const sharedName = reserveWorkerChunkName('__modern_worker_shared', reservedNames);
114
+ return {
115
+ experiments: {
116
+ outputModule: true
117
+ },
118
+ externals: getCloudflareWorkerNodeExternals(),
119
+ externalsType: 'module-import',
120
+ module: {
121
+ parser: {
122
+ javascript: {
123
+ dynamicImportMode: 'eager'
124
+ }
125
+ }
126
+ },
127
+ optimization: {
128
+ runtimeChunk: {
129
+ name: runtimeName
130
+ },
131
+ splitChunks: {
132
+ chunks: 'all',
133
+ minSize: 0,
134
+ name: sharedName
135
+ }
136
+ }
137
+ };
138
+ }
139
+ function applyCloudflareWorkerRspackConfig(chain, workerEntryNames) {
140
+ const config = getCloudflareWorkerRspackConfig(workerEntryNames);
141
+ chain.experiments(config.experiments);
142
+ chain.externals(config.externals);
143
+ chain.externalsType(config.externalsType);
144
+ chain.module.parser.merge(config.module.parser);
145
+ chain.optimization.runtimeChunk(config.optimization.runtimeChunk);
146
+ chain.optimization.splitChunks(config.optimization.splitChunks);
147
+ }
148
+ function applyCloudflareWorkerMfRuntimeBoundary(chain) {
149
+ chain.plugins.delete('plugin-module-federation');
150
+ chain.resolve.alias.set(`${MF_SSR_DATA_FETCH_RUNTIME_PLUGIN}$`, getCloudflareWorkerCompatFile('cloudflare-worker-mf-ssr-runtime-plugin.mjs'));
151
+ chain.resolve.alias.set(`${MF_SSR_DEV_RUNTIME_PLUGIN}$`, getCloudflareWorkerCompatFile('cloudflare-worker-mf-ssr-runtime-plugin.mjs'));
152
+ }
93
153
  function getEffectBffEntry(normalizedConfig, appContext) {
94
154
  if (!normalizedConfig.bff || 'hono' === normalizedConfig.bff.runtimeFramework) return;
95
155
  const configuredEntry = normalizedConfig.bff.effect?.entry;
@@ -248,17 +308,10 @@ function getBuilderEnvironments(normalizedConfig, appContext, tempBuilderConfig)
248
308
  htmlPlugin: false,
249
309
  ...useCloudflareModuleWorker ? {
250
310
  bundlerChain: (chain)=>{
251
- chain.merge({
252
- experiments: {
253
- outputModule: true
254
- },
255
- externals: getCloudflareWorkerNodeExternals(),
256
- externalsType: 'module-import'
257
- });
311
+ applyCloudflareWorkerRspackConfig(chain, Object.keys(workerEntries));
258
312
  chain.output.module(true).library({
259
313
  type: 'module'
260
314
  }).publicPath('/').chunkFormat('module').chunkLoading('import').workerChunkLoading('import');
261
- chain.optimization.usedExports(false).providedExports(true).innerGraph(false).sideEffects(false);
262
315
  for (const condition of [
263
316
  'workerd',
264
317
  'worker',
@@ -268,7 +321,7 @@ function getBuilderEnvironments(normalizedConfig, appContext, tempBuilderConfig)
268
321
  'require',
269
322
  'module'
270
323
  ])chain.resolve.conditionNames.add(condition);
271
- chain.plugins.delete('plugin-module-federation');
324
+ applyCloudflareWorkerMfRuntimeBoundary(chain);
272
325
  if (tanstackRouterSsrServerFile) {
273
326
  chain.resolve.alias.set('@tanstack/router-core/ssr/server$', tanstackRouterSsrServerFile);
274
327
  chain.resolve.alias.set('@tanstack/router-core/ssr/server', tanstackRouterSsrServerFile);
@@ -309,4 +362,4 @@ function getBuilderEnvironments(normalizedConfig, appContext, tempBuilderConfig)
309
362
  builderConfig: tempBuilderConfig
310
363
  };
311
364
  }
312
- export { getBuilderEnvironments };
365
+ export { applyCloudflareWorkerMfRuntimeBoundary, applyCloudflareWorkerRspackConfig, getBuilderEnvironments, getCloudflareWorkerRspackConfig };
@@ -0,0 +1,63 @@
1
+ import "node:module";
2
+ import node_fs from "node:fs";
3
+ import node_path from "node:path";
4
+ const DEFAULT_INDEX_FILE = 'llms.txt';
5
+ const DEFAULT_EXCLUDED_DIRS = [
6
+ 'zh'
7
+ ];
8
+ function bundleDocs({ source, target, indexFile = DEFAULT_INDEX_FILE, excludedDirs = DEFAULT_EXCLUDED_DIRS }) {
9
+ if (!node_fs.existsSync(source)) {
10
+ console.warn(`[bundle-docs] docs build output not found: ${source}`);
11
+ console.warn('[bundle-docs] skipping the bundled docs — build the docs site first if you need them');
12
+ return 0;
13
+ }
14
+ node_fs.rmSync(target, {
15
+ recursive: true,
16
+ force: true
17
+ });
18
+ const isBundled = (rel)=>rel === indexFile || rel.endsWith('.md') && !excludedDirs.some((dir)=>rel.startsWith(`${dir}${node_path.sep}`));
19
+ let count = 0;
20
+ for (const entry of node_fs.readdirSync(source, {
21
+ recursive: true,
22
+ withFileTypes: true
23
+ })){
24
+ if (!entry.isFile()) continue;
25
+ const from = node_path.join(entry.parentPath ?? entry.path, entry.name);
26
+ const rel = node_path.relative(source, from);
27
+ if (!isBundled(rel)) continue;
28
+ const to = node_path.join(target, rel);
29
+ node_fs.mkdirSync(node_path.dirname(to), {
30
+ recursive: true
31
+ });
32
+ node_fs.copyFileSync(from, to);
33
+ count++;
34
+ }
35
+ if (0 === count) throw new Error(`[bundle-docs] no files copied from ${source}`);
36
+ return count;
37
+ }
38
+ function parseArgs(argv) {
39
+ const options = {};
40
+ for(let i = 0; i < argv.length; i += 2){
41
+ const key = argv[i]?.replace(/^--/, '');
42
+ const value = argv[i + 1];
43
+ if (key && value) options[key] = value;
44
+ }
45
+ return options;
46
+ }
47
+ function runBundleDocsCli(pkgRoot) {
48
+ const args = parseArgs(process.argv.slice(2));
49
+ const source = args.source ? node_path.resolve(process.cwd(), args.source) : node_path.resolve(pkgRoot, '../../document/doc_build');
50
+ const target = args.target ? node_path.resolve(process.cwd(), args.target) : node_path.resolve(pkgRoot, 'docs');
51
+ try {
52
+ const count = bundleDocs({
53
+ source,
54
+ target,
55
+ indexFile: args.index
56
+ });
57
+ if (count > 0) console.log(`[bundle-docs] bundled ${count} doc files into docs`);
58
+ } catch (error) {
59
+ console.error(error.message);
60
+ process.exit(1);
61
+ }
62
+ }
63
+ export { bundleDocs, runBundleDocsCli };
@@ -117,7 +117,7 @@ const verifyCloudflareOutput = async (options)=>{
117
117
  path: publicPath
118
118
  });
119
119
  }
120
- if (false !== options.importWorker && await pathExists(outputPlan.paths.workerEntry)) await verifyWorkerImport(issues, outputPlan.paths.workerEntry);
120
+ if (false !== options.importWorker && await pathExists(outputPlan.paths.workerEntry)) await verifyWorkerImport(issues, outputPlan.paths.workerEntry, manifest);
121
121
  return {
122
122
  ok: 0 === issues.length,
123
123
  issues
@@ -2,7 +2,9 @@ import "node:module";
2
2
  import promises from "node:fs/promises";
3
3
  import node_path from "node:path";
4
4
  import { pathToFileURL } from "node:url";
5
+ import { isDeepStrictEqual } from "node:util";
5
6
  import { parse } from "@babel/parser";
7
+ import traverse from "@babel/traverse";
6
8
  import { CLOUDFLARE_WORKER_BUNDLE_DIRECTORY, CLOUDFLARE_WORKER_NODE_BUILTINS } from "../cloudflare-output-contract.mjs";
7
9
  import { addIssue } from "./issues.mjs";
8
10
  const getReferencedRouteWorkers = (manifest)=>Array.isArray(manifest?.routeSpec?.routes) ? manifest.routeSpec.routes.map((route)=>'string' == typeof route?.worker && route.worker.length > 0 ? route.worker : void 0).filter((worker)=>'string' == typeof worker) : [];
@@ -46,6 +48,7 @@ const getNodeName = (node)=>{
46
48
  if (!isAstNode(node)) return;
47
49
  return 'Identifier' === node.type && 'string' == typeof node.name ? node.name : 'StringLiteral' === node.type && 'string' == typeof node.value ? node.value : void 0;
48
50
  };
51
+ const getStringLiteralValue = (node)=>isAstNode(node) && 'StringLiteral' === node.type && 'string' == typeof node.value ? node.value : void 0;
49
52
  const collectBindingNames = (node, names)=>{
50
53
  if (!isAstNode(node)) return;
51
54
  const name = getNodeName(node);
@@ -55,7 +58,11 @@ const collectBindingNames = (node, names)=>{
55
58
  } else if ('ArrayPattern' === node.type && Array.isArray(node.elements)) for (const element of node.elements)collectBindingNames(element, names);
56
59
  else if ('AssignmentPattern' === node.type || 'RestElement' === node.type) collectBindingNames('AssignmentPattern' === node.type ? node.left : node.argument, names);
57
60
  };
58
- const getMemberPropertyName = (node)=>'MemberExpression' === node.type ? getNodeName(node.property) : void 0;
61
+ const getMemberPropertyName = (node)=>{
62
+ if ('MemberExpression' !== node.type) return;
63
+ return true === node.computed ? getStringLiteralValue(node.property) : getNodeName(node.property);
64
+ };
65
+ const isAmbientModuleRequire = (node, modulePath)=>isAstNode(node) && 'MemberExpression' === node.type && isAstNode(node.object) && 'Identifier' === node.object.type && 'module' === node.object.name && void 0 === modulePath.scope.getBinding('module') && 'require' === getMemberPropertyName(node);
59
66
  const isModuleExports = (node)=>isAstNode(node) && 'MemberExpression' === node.type && isAstNode(node.object) && 'Identifier' === node.object.type && 'module' === node.object.name && 'exports' === getMemberPropertyName(node);
60
67
  const collectCommonJsExports = (statement, exports)=>{
61
68
  if ('ExpressionStatement' !== statement.type || !isAstNode(statement.expression) || 'AssignmentExpression' !== statement.expression.type) return;
@@ -90,19 +97,31 @@ const collectEsmExports = (statement, exports)=>{
90
97
  }
91
98
  }
92
99
  };
93
- const visitAst = (node, visitor)=>{
94
- visitor(node);
95
- for (const [key, value] of Object.entries(node))if ('loc' !== key && 'start' !== key && 'end' !== key && 'leadingComments' !== key && 'trailingComments' !== key && 'innerComments' !== key) {
96
- if (isAstNode(value)) visitAst(value, visitor);
97
- else if (Array.isArray(value)) {
98
- for (const item of value)if (isAstNode(item)) visitAst(item, visitor);
100
+ const getStaticImport = (modulePath)=>{
101
+ const node = modulePath.node;
102
+ if (('ImportDeclaration' === node.type || 'ExportNamedDeclaration' === node.type || 'ExportAllDeclaration' === node.type) && isAstNode(node.source)) return getStringLiteralValue(node.source);
103
+ if ('ImportExpression' === node.type && isAstNode(node.source)) return getStringLiteralValue(node.source);
104
+ if ('CallExpression' === node.type && Array.isArray(node.arguments) && 1 === node.arguments.length && isAstNode(node.callee) && ('Identifier' === node.callee.type && 'require' === node.callee.name && void 0 === modulePath.scope.getBinding('require') || isAmbientModuleRequire(node.callee, modulePath) || 'Import' === node.callee.type)) return getStringLiteralValue(node.arguments[0]);
105
+ };
106
+ const isAmbientLoaderWrite = (modulePath)=>{
107
+ let targetPath = modulePath;
108
+ while(targetPath.parentPath){
109
+ const parentPath = targetPath.parentPath;
110
+ if (parentPath.isAssignmentExpression()) return 'left' === targetPath.key;
111
+ if (parentPath.isUpdateExpression()) return 'argument' === targetPath.key;
112
+ if (parentPath.isForInStatement() || parentPath.isForOfStatement()) return 'left' === targetPath.key;
113
+ if (parentPath.isObjectProperty()) {
114
+ if ('value' !== targetPath.key) return false;
115
+ targetPath = parentPath;
116
+ continue;
117
+ }
118
+ if (parentPath.isObjectPattern() || parentPath.isArrayPattern() || parentPath.isRestElement() || parentPath.isAssignmentPattern()) {
119
+ targetPath = parentPath;
120
+ continue;
99
121
  }
122
+ break;
100
123
  }
101
- };
102
- const getStaticImport = (node)=>{
103
- if (('ImportDeclaration' === node.type || 'ExportNamedDeclaration' === node.type || 'ExportAllDeclaration' === node.type) && isAstNode(node.source)) return getNodeName(node.source);
104
- if ('ImportExpression' === node.type && isAstNode(node.source)) return getNodeName(node.source);
105
- if ('CallExpression' === node.type && Array.isArray(node.arguments) && 1 === node.arguments.length && isAstNode(node.callee) && ('Identifier' === node.callee.type && 'require' === node.callee.name || 'Import' === node.callee.type)) return getNodeName(node.arguments[0]);
124
+ return false;
106
125
  };
107
126
  const analyzeWorkerModule = (source)=>{
108
127
  const ast = parse(source, {
@@ -110,17 +129,49 @@ const analyzeWorkerModule = (source)=>{
110
129
  });
111
130
  const exports = new Set();
112
131
  const imports = new Set();
132
+ let unsafeCommonJsLoaderUsage = false;
133
+ let unsafeDynamicImport = false;
113
134
  for (const statement of ast.program.body){
114
135
  collectEsmExports(statement, exports);
115
136
  collectCommonJsExports(statement, exports);
116
137
  }
117
- visitAst(ast.program, (node)=>{
118
- const specifier = getStaticImport(node);
119
- if (specifier) imports.add(specifier);
138
+ traverse(ast, {
139
+ enter (modulePath) {
140
+ const node = modulePath.node;
141
+ if (('ImportExpression' === node.type || 'CallExpression' === node.type && isAstNode(node.callee) && 'Import' === node.callee.type) && void 0 === getStaticImport(modulePath)) unsafeDynamicImport = true;
142
+ if (modulePath.isReferencedIdentifier({
143
+ name: 'require'
144
+ }) && void 0 === modulePath.scope.getBinding('require')) {
145
+ const parentPath = modulePath.parentPath;
146
+ const isStaticRequireCall = parentPath?.isCallExpression() && 'callee' === modulePath.key && void 0 !== getStaticImport(parentPath);
147
+ const isAvailabilityCheck = parentPath?.isUnaryExpression({
148
+ operator: 'typeof'
149
+ });
150
+ if (!isStaticRequireCall && !isAvailabilityCheck) unsafeCommonJsLoaderUsage = true;
151
+ }
152
+ if ('Identifier' === node.type && isAmbientLoaderWrite(modulePath) && ('require' === node.name || 'module' === node.name) && void 0 === modulePath.scope.getBinding(node.name)) unsafeCommonJsLoaderUsage = true;
153
+ if (modulePath.isReferencedIdentifier({
154
+ name: 'module'
155
+ }) && void 0 === modulePath.scope.getBinding('module')) {
156
+ const parentPath = modulePath.parentPath;
157
+ const isExportsAccess = null !== parentPath && isModuleExports(parentPath.node);
158
+ const isStaticModuleRequireCall = null !== parentPath && isAmbientModuleRequire(parentPath.node, parentPath) && parentPath.parentPath?.isCallExpression() === true && 'callee' === parentPath.key && void 0 !== getStaticImport(parentPath.parentPath);
159
+ if (!isExportsAccess && !isStaticModuleRequireCall) unsafeCommonJsLoaderUsage = true;
160
+ }
161
+ if (isAmbientModuleRequire(node, modulePath)) {
162
+ const parentPath = modulePath.parentPath;
163
+ const isStaticRequireCall = parentPath?.isCallExpression() && 'callee' === modulePath.key && void 0 !== getStaticImport(parentPath);
164
+ if (!isStaticRequireCall) unsafeCommonJsLoaderUsage = true;
165
+ }
166
+ const specifier = getStaticImport(modulePath);
167
+ if (void 0 !== specifier) imports.add(specifier);
168
+ }
120
169
  });
121
170
  return {
122
171
  exports,
123
- imports
172
+ imports,
173
+ unsafeCommonJsLoaderUsage,
174
+ unsafeDynamicImport
124
175
  };
125
176
  };
126
177
  const getPackageName = (specifier)=>specifier.startsWith('@') ? specifier.split('/').slice(0, 2).join('/') : specifier.split('/')[0];
@@ -171,7 +222,25 @@ const verifyWorkerModuleClosure = async (issues, entryPath, entrySource, contrac
171
222
  return;
172
223
  }
173
224
  if (isEntry) entryAnalysis = analysis;
225
+ if (analysis.unsafeCommonJsLoaderUsage) addIssue(issues, {
226
+ code: 'invalid-worker-bundle',
227
+ message: 'Cloudflare worker bundles must use exactly one string-literal specifier in ambient CommonJS loader calls and must not pass or alias the loader.',
228
+ path: modulePath
229
+ });
230
+ if (analysis.unsafeDynamicImport) addIssue(issues, {
231
+ code: 'invalid-worker-bundle',
232
+ message: 'Cloudflare worker bundles must not contain non-static dynamic module imports.',
233
+ path: modulePath
234
+ });
174
235
  for (const specifier of analysis.imports){
236
+ if (0 === specifier.length) {
237
+ addIssue(issues, {
238
+ code: 'invalid-worker-bundle',
239
+ message: 'Cloudflare worker bundle module specifiers must not be empty.',
240
+ path: modulePath
241
+ });
242
+ continue;
243
+ }
175
244
  if (!specifier.startsWith('.') && !node_path.isAbsolute(specifier)) {
176
245
  if (CLOUDFLARE_WORKER_NODE_BUILTIN_SPECIFIERS.has(specifier)) continue;
177
246
  if (specifier.startsWith('node:')) {
@@ -220,14 +289,20 @@ const verifyWorkerBundleReferences = async (issues, worker, source, contract)=>{
220
289
  path: worker.path
221
290
  });
222
291
  };
223
- const verifyWorkerImport = async (issues, entryPath)=>{
292
+ const verifyWorkerImport = async (issues, entryPath, expectedManifest)=>{
224
293
  try {
225
- const worker = (await import(`${pathToFileURL(entryPath).href}?t=${Date.now()}`)).default;
294
+ const workerModule = await import(`${pathToFileURL(entryPath).href}?t=${Date.now()}`);
295
+ const worker = workerModule.default;
226
296
  if (!worker || 'function' != typeof worker.fetch) addIssue(issues, {
227
297
  code: 'worker-import-failed',
228
298
  message: 'Cloudflare server entry must default-export a Worker with fetch.',
229
299
  path: entryPath
230
300
  });
301
+ if (void 0 !== expectedManifest && !isDeepStrictEqual(workerModule.modernWorkerManifest, expectedManifest)) addIssue(issues, {
302
+ code: 'worker-import-failed',
303
+ message: 'Cloudflare server entry runtime manifest must exactly match modern-worker-manifest.json.',
304
+ path: entryPath
305
+ });
231
306
  } catch (error) {
232
307
  addIssue(issues, {
233
308
  code: 'worker-import-failed',
@@ -1,5 +1,6 @@
1
1
  const ASSETS_BINDING = 'ASSETS';
2
2
  const MODERN_WORKER_MANIFEST = p_workerManifest;
3
+ export const modernWorkerManifest = MODERN_WORKER_MANIFEST;
3
4
  const WORKER_MODULE_LOADERS = p_workerModuleLoaders;
4
5
  const workerModulePromises = new Map();
5
6
  const effectBffDispatcherPromises = new Map();
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Workerd cannot initialize Module Federation's Node-oriented SSR data-fetch
3
+ * runtime. Cloudflare workers do not load native MF remotes, so retain the
4
+ * runtime-plugin contract without installing its server data-fetch hooks.
5
+ */
6
+ export const injectDataFetchFunctionPlugin = () => ({
7
+ name: '@module-federation/inject-data-fetch-function-plugin',
8
+ setup() {},
9
+ });
10
+
11
+ export const mfSSRDevPlugin = () => ({
12
+ name: '@module-federation/modern-js-v3',
13
+ setup() {},
14
+ });