@bleedingdev/modern-js-app-tools 3.5.0-ultramodern.98 → 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 (334) hide show
  1. package/bin/modern-bundle-docs.js +7 -0
  2. package/dist/cjs/builder/generator/createBuilderProviderConfig.js +5 -1
  3. package/dist/cjs/builder/generator/getBuilderEnvironments.js +80 -11
  4. package/dist/cjs/bundleDocs.js +114 -0
  5. package/dist/cjs/commands/build.js +2 -1
  6. package/dist/cjs/commands/deploy.js +4 -2
  7. package/dist/cjs/commands/index.js +0 -4
  8. package/dist/cjs/config/default.js +2 -0
  9. package/dist/cjs/index.js +56 -15
  10. package/dist/cjs/plugins/analyze/index.js +2 -2
  11. package/dist/cjs/plugins/analyze/utils.js +3 -2
  12. package/dist/cjs/plugins/deploy/platforms/cloudflare-output-verifier/index.js +1 -1
  13. package/dist/cjs/plugins/deploy/platforms/cloudflare-output-verifier/worker-bundles.js +94 -18
  14. package/dist/cjs/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.mjs +1 -0
  15. package/dist/cjs/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +14 -0
  16. package/dist/cjs/plugins/initialize/index.js +4 -3
  17. package/dist/cjs/plugins/serverBuild.js +3 -2
  18. package/dist/cjs/ultramodern-release-envelope/framework-output.js +109 -57
  19. package/dist/esm/builder/generator/createBuilderProviderConfig.mjs +5 -1
  20. package/dist/esm/builder/generator/getBuilderEnvironments.mjs +70 -10
  21. package/dist/esm/bundleDocs.mjs +62 -0
  22. package/dist/esm/commands/build.mjs +2 -1
  23. package/dist/esm/commands/deploy.mjs +4 -2
  24. package/dist/esm/commands/index.mjs +0 -4
  25. package/dist/esm/config/default.mjs +2 -0
  26. package/dist/esm/index.mjs +15 -1
  27. package/dist/esm/plugins/analyze/index.mjs +2 -2
  28. package/dist/esm/plugins/analyze/utils.mjs +3 -2
  29. package/dist/esm/plugins/deploy/platforms/cloudflare-output-verifier/index.mjs +1 -1
  30. package/dist/esm/plugins/deploy/platforms/cloudflare-output-verifier/worker-bundles.mjs +93 -18
  31. package/dist/esm/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.mjs +1 -0
  32. package/dist/esm/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +14 -0
  33. package/dist/esm/plugins/initialize/index.mjs +4 -3
  34. package/dist/esm/plugins/serverBuild.mjs +3 -2
  35. package/dist/esm/ultramodern-release-envelope/framework-output.mjs +107 -58
  36. package/dist/esm-node/builder/generator/createBuilderProviderConfig.mjs +5 -1
  37. package/dist/esm-node/builder/generator/getBuilderEnvironments.mjs +70 -10
  38. package/dist/esm-node/bundleDocs.mjs +63 -0
  39. package/dist/esm-node/commands/build.mjs +2 -1
  40. package/dist/esm-node/commands/deploy.mjs +4 -2
  41. package/dist/esm-node/commands/index.mjs +0 -4
  42. package/dist/esm-node/config/default.mjs +2 -0
  43. package/dist/esm-node/index.mjs +15 -1
  44. package/dist/esm-node/plugins/analyze/index.mjs +2 -2
  45. package/dist/esm-node/plugins/analyze/utils.mjs +3 -2
  46. package/dist/esm-node/plugins/deploy/platforms/cloudflare-output-verifier/index.mjs +1 -1
  47. package/dist/esm-node/plugins/deploy/platforms/cloudflare-output-verifier/worker-bundles.mjs +93 -18
  48. package/dist/esm-node/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.mjs +1 -0
  49. package/dist/esm-node/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.mjs +14 -0
  50. package/dist/esm-node/plugins/initialize/index.mjs +4 -3
  51. package/dist/esm-node/plugins/serverBuild.mjs +3 -2
  52. package/dist/esm-node/ultramodern-release-envelope/framework-output.mjs +107 -58
  53. package/dist/types/builder/generator/getBuilderEnvironments.d.ts +29 -0
  54. package/dist/types/bundleDocs.d.ts +20 -0
  55. package/dist/types/commands/deploy.d.ts +2 -1
  56. package/dist/types/index.d.ts +4 -1
  57. package/dist/types/plugins/analyze/utils.d.ts +1 -1
  58. package/dist/types/plugins/deploy/platforms/cloudflare-output-verifier/worker-bundles.d.ts +1 -1
  59. package/dist/types/plugins/deploy/platforms/templates/cloudflare-entry.001-bootstrap-security.d.mts +1 -1
  60. package/dist/types/plugins/deploy/platforms/templates/cloudflare-worker-mf-ssr-runtime-plugin.d.mts +13 -0
  61. package/dist/types/types/config/dev.d.ts +6 -0
  62. package/dist/types/ultramodern-release-envelope/framework-output.d.ts +1 -0
  63. package/docs/apis/app/commands.md +231 -0
  64. package/docs/apis/app/hooks/api/lambda.md +9 -0
  65. package/docs/apis/app/hooks/config/favicon.md +24 -0
  66. package/docs/apis/app/hooks/config/html.md +5 -0
  67. package/docs/apis/app/hooks/config/icon.md +24 -0
  68. package/docs/apis/app/hooks/config/mock.md +6 -0
  69. package/docs/apis/app/hooks/config/public.md +26 -0
  70. package/docs/apis/app/hooks/config/upload.md +50 -0
  71. package/docs/apis/app/hooks/modern-config.md +5 -0
  72. package/docs/apis/app/hooks/server/server.md +5 -0
  73. package/docs/apis/app/hooks/shared.md +3 -0
  74. package/docs/apis/app/hooks/src/app.md +30 -0
  75. package/docs/apis/app/hooks/src/entry.md +34 -0
  76. package/docs/apis/app/hooks/src/entry.server.md +51 -0
  77. package/docs/apis/app/hooks/src/modern.runtime.md +5 -0
  78. package/docs/apis/app/hooks/src/routes.md +86 -0
  79. package/docs/apis/app/hooks/src/server.md +3 -0
  80. package/docs/apis/app/runtime/bff/use-backend-context.md +27 -0
  81. package/docs/apis/app/runtime/core/create-root.md +19 -0
  82. package/docs/apis/app/runtime/core/render.md +39 -0
  83. package/docs/apis/app/runtime/core/runtime-context.md +156 -0
  84. package/docs/apis/app/runtime/router/router.md +283 -0
  85. package/docs/apis/app/runtime/ssr/no-ssr.md +35 -0
  86. package/docs/apis/app/runtime/ssr/renderStreaming.md +67 -0
  87. package/docs/apis/app/runtime/ssr/renderString.md +60 -0
  88. package/docs/apis/app/runtime/ssr/requestHandler.md +44 -0
  89. package/docs/apis/app/runtime/utility/css-in-js.md +40 -0
  90. package/docs/apis/app/runtime/utility/head.md +35 -0
  91. package/docs/apis/app/runtime/utility/loadable.md +82 -0
  92. package/docs/community/blog/2022-0708-updates.md +91 -0
  93. package/docs/community/blog/2022-0910-updates.md +76 -0
  94. package/docs/community/blog/overview.md +63 -0
  95. package/docs/community/blog/v2-release-note.md +238 -0
  96. package/docs/community/blog/v3-release-note.md +622 -0
  97. package/docs/community/contributing-guide.md +252 -0
  98. package/docs/community/releases.md +23 -0
  99. package/docs/community/showcase.md +24 -0
  100. package/docs/community/team.md +14 -0
  101. package/docs/configure/app/bff/cross-project.md +20 -0
  102. package/docs/configure/app/bff/effect.md +313 -0
  103. package/docs/configure/app/bff/prefix.md +29 -0
  104. package/docs/configure/app/bff/runtime-framework.md +26 -0
  105. package/docs/configure/app/builder-plugins.md +66 -0
  106. package/docs/configure/app/dev/asset-prefix.md +13 -0
  107. package/docs/configure/app/dev/before-start-url.md +17 -0
  108. package/docs/configure/app/dev/client.md +41 -0
  109. package/docs/configure/app/dev/hmr.md +10 -0
  110. package/docs/configure/app/dev/host.md +18 -0
  111. package/docs/configure/app/dev/https.md +77 -0
  112. package/docs/configure/app/dev/lazy-compilation.md +39 -0
  113. package/docs/configure/app/dev/live-reload.md +10 -0
  114. package/docs/configure/app/dev/mock-dir.md +31 -0
  115. package/docs/configure/app/dev/progress-bar.md +19 -0
  116. package/docs/configure/app/dev/server.md +124 -0
  117. package/docs/configure/app/dev/setup-middlewares.md +32 -0
  118. package/docs/configure/app/dev/start-url.md +48 -0
  119. package/docs/configure/app/dev/watch-files.md +27 -0
  120. package/docs/configure/app/dev/write-to-disk.md +10 -0
  121. package/docs/configure/app/experiments/source-build.md +31 -0
  122. package/docs/configure/app/html/app-icon.md +28 -0
  123. package/docs/configure/app/html/crossorigin.md +10 -0
  124. package/docs/configure/app/html/favicon.md +16 -0
  125. package/docs/configure/app/html/inject.md +10 -0
  126. package/docs/configure/app/html/meta.md +24 -0
  127. package/docs/configure/app/html/mount-id.md +10 -0
  128. package/docs/configure/app/html/output-structure.md +10 -0
  129. package/docs/configure/app/html/script-loading.md +10 -0
  130. package/docs/configure/app/html/tags.md +15 -0
  131. package/docs/configure/app/html/template-parameters.md +33 -0
  132. package/docs/configure/app/html/template.md +10 -0
  133. package/docs/configure/app/html/title.md +18 -0
  134. package/docs/configure/app/output/asset-prefix.md +11 -0
  135. package/docs/configure/app/output/assets-retry.md +77 -0
  136. package/docs/configure/app/output/charset.md +10 -0
  137. package/docs/configure/app/output/clean-dist-path.md +16 -0
  138. package/docs/configure/app/output/convert-to-rem.md +79 -0
  139. package/docs/configure/app/output/copy.md +10 -0
  140. package/docs/configure/app/output/css-modules.md +48 -0
  141. package/docs/configure/app/output/data-uri-limit.md +26 -0
  142. package/docs/configure/app/output/disable-css-module-extension.md +55 -0
  143. package/docs/configure/app/output/disable-inline-runtime-chunk.md +41 -0
  144. package/docs/configure/app/output/disable-svgr.md +18 -0
  145. package/docs/configure/app/output/disable-ts-checker.md +49 -0
  146. package/docs/configure/app/output/dist-path.md +43 -0
  147. package/docs/configure/app/output/enable-asset-manifest.md +36 -0
  148. package/docs/configure/app/output/enable-css-module-tsdeclaration.md +28 -0
  149. package/docs/configure/app/output/enable-inline-route-manifests.md +16 -0
  150. package/docs/configure/app/output/externals.md +20 -0
  151. package/docs/configure/app/output/filename-hash.md +10 -0
  152. package/docs/configure/app/output/filename.md +55 -0
  153. package/docs/configure/app/output/inject-styles.md +10 -0
  154. package/docs/configure/app/output/inline-scripts.md +29 -0
  155. package/docs/configure/app/output/inline-styles.md +29 -0
  156. package/docs/configure/app/output/legal-comments.md +18 -0
  157. package/docs/configure/app/output/minify.md +22 -0
  158. package/docs/configure/app/output/override-browserslist.md +22 -0
  159. package/docs/configure/app/output/polyfill.md +12 -0
  160. package/docs/configure/app/output/source-map.md +30 -0
  161. package/docs/configure/app/output/split-route-chunks.md +16 -0
  162. package/docs/configure/app/output/ssg.md +81 -0
  163. package/docs/configure/app/output/ssgByEntries.md +90 -0
  164. package/docs/configure/app/output/svg-default-export.md +30 -0
  165. package/docs/configure/app/output/temp-dir.md +20 -0
  166. package/docs/configure/app/performance/build-cache.md +44 -0
  167. package/docs/configure/app/performance/chunk-split.md +40 -0
  168. package/docs/configure/app/performance/dns-prefetch.md +15 -0
  169. package/docs/configure/app/performance/preconnect.md +16 -0
  170. package/docs/configure/app/performance/prefetch.md +21 -0
  171. package/docs/configure/app/performance/preload.md +23 -0
  172. package/docs/configure/app/performance/print-file-size.md +40 -0
  173. package/docs/configure/app/performance/profile.md +10 -0
  174. package/docs/configure/app/performance/remove-console.md +10 -0
  175. package/docs/configure/app/performance/remove-moment-locale.md +10 -0
  176. package/docs/configure/app/performance/rsdoctor.md +38 -0
  177. package/docs/configure/app/plugins.md +59 -0
  178. package/docs/configure/app/resolve/alias-strategy.md +10 -0
  179. package/docs/configure/app/resolve/alias.md +9 -0
  180. package/docs/configure/app/resolve/condition-names.md +13 -0
  181. package/docs/configure/app/resolve/dedupe.md +9 -0
  182. package/docs/configure/app/resolve/extensions.md +13 -0
  183. package/docs/configure/app/runtime/0-intro.md +58 -0
  184. package/docs/configure/app/runtime/plugins.md +58 -0
  185. package/docs/configure/app/runtime/router.md +35 -0
  186. package/docs/configure/app/security/check-syntax.md +69 -0
  187. package/docs/configure/app/security/nonce.md +15 -0
  188. package/docs/configure/app/security/sri.md +20 -0
  189. package/docs/configure/app/server/base-url.md +26 -0
  190. package/docs/configure/app/server/port.md +18 -0
  191. package/docs/configure/app/server/public-routes.md +22 -0
  192. package/docs/configure/app/server/routes.md +86 -0
  193. package/docs/configure/app/server/rsc.md +22 -0
  194. package/docs/configure/app/server/ssr-by-entries.md +25 -0
  195. package/docs/configure/app/server/ssr.md +80 -0
  196. package/docs/configure/app/server/tsconfig-path.md +59 -0
  197. package/docs/configure/app/source/alias-strategy.md +14 -0
  198. package/docs/configure/app/source/alias.md +23 -0
  199. package/docs/configure/app/source/config-dir.md +20 -0
  200. package/docs/configure/app/source/decorators.md +25 -0
  201. package/docs/configure/app/source/define.md +16 -0
  202. package/docs/configure/app/source/disable-default-entries.md +28 -0
  203. package/docs/configure/app/source/enable-async-entry.md +54 -0
  204. package/docs/configure/app/source/enable-async-pre-entry.md +26 -0
  205. package/docs/configure/app/source/entries-dir.md +35 -0
  206. package/docs/configure/app/source/entries.md +179 -0
  207. package/docs/configure/app/source/exclude.md +10 -0
  208. package/docs/configure/app/source/global-vars.md +106 -0
  209. package/docs/configure/app/source/include.md +36 -0
  210. package/docs/configure/app/source/main-entry-name.md +24 -0
  211. package/docs/configure/app/source/pre-entry.md +10 -0
  212. package/docs/configure/app/source/react-compiler.md +68 -0
  213. package/docs/configure/app/source/transform-import.md +27 -0
  214. package/docs/configure/app/split-chunks.md +17 -0
  215. package/docs/configure/app/tools/autoprefixer.md +44 -0
  216. package/docs/configure/app/tools/bundler-chain.md +26 -0
  217. package/docs/configure/app/tools/css-extract.md +33 -0
  218. package/docs/configure/app/tools/css-loader.md +17 -0
  219. package/docs/configure/app/tools/dev-server.md +113 -0
  220. package/docs/configure/app/tools/html-plugin.md +41 -0
  221. package/docs/configure/app/tools/less.md +81 -0
  222. package/docs/configure/app/tools/lightningcss-loader.md +35 -0
  223. package/docs/configure/app/tools/minify-css.md +53 -0
  224. package/docs/configure/app/tools/postcss.md +34 -0
  225. package/docs/configure/app/tools/rspack.md +10 -0
  226. package/docs/configure/app/tools/sass.md +78 -0
  227. package/docs/configure/app/tools/style-loader.md +10 -0
  228. package/docs/configure/app/tools/swc.md +65 -0
  229. package/docs/configure/app/tools/ts-checker.md +116 -0
  230. package/docs/configure/app/usage.md +276 -0
  231. package/docs/guides/advanced-features/bff/cross-project.md +109 -0
  232. package/docs/guides/advanced-features/bff/data-platform.md +116 -0
  233. package/docs/guides/advanced-features/bff/extend-server.md +120 -0
  234. package/docs/guides/advanced-features/bff/frameworks.md +243 -0
  235. package/docs/guides/advanced-features/bff/function.md +318 -0
  236. package/docs/guides/advanced-features/bff/operators.md +554 -0
  237. package/docs/guides/advanced-features/bff/sdk.md +116 -0
  238. package/docs/guides/advanced-features/bff/upload.md +101 -0
  239. package/docs/guides/advanced-features/bff.md +18 -0
  240. package/docs/guides/advanced-features/build-performance.md +130 -0
  241. package/docs/guides/advanced-features/compatibility.md +120 -0
  242. package/docs/guides/advanced-features/international/advanced.md +128 -0
  243. package/docs/guides/advanced-features/international/api.md +267 -0
  244. package/docs/guides/advanced-features/international/best-practices.md +286 -0
  245. package/docs/guides/advanced-features/international/configuration.md +228 -0
  246. package/docs/guides/advanced-features/international/locale-detection.md +126 -0
  247. package/docs/guides/advanced-features/international/quick-start.md +128 -0
  248. package/docs/guides/advanced-features/international/resource-loading.md +154 -0
  249. package/docs/guides/advanced-features/international/routing.md +173 -0
  250. package/docs/guides/advanced-features/international.md +27 -0
  251. package/docs/guides/advanced-features/low-level.md +46 -0
  252. package/docs/guides/advanced-features/page-performance/code-split.md +77 -0
  253. package/docs/guides/advanced-features/page-performance/inline-assets.md +159 -0
  254. package/docs/guides/advanced-features/page-performance/optimize-bundle.md +97 -0
  255. package/docs/guides/advanced-features/page-performance/react-compiler.md +51 -0
  256. package/docs/guides/advanced-features/server-monitor/logger.md +41 -0
  257. package/docs/guides/advanced-features/server-monitor/metrics.md +58 -0
  258. package/docs/guides/advanced-features/server-monitor/monitors.md +242 -0
  259. package/docs/guides/advanced-features/source-build.md +164 -0
  260. package/docs/guides/advanced-features/web-server.md +288 -0
  261. package/docs/guides/basic-features/alias.md +102 -0
  262. package/docs/guides/basic-features/css/css-in-js.md +72 -0
  263. package/docs/guides/basic-features/css/css-modules.md +212 -0
  264. package/docs/guides/basic-features/css/css.md +27 -0
  265. package/docs/guides/basic-features/css/tailwindcss.md +27 -0
  266. package/docs/guides/basic-features/data/data-cache.md +510 -0
  267. package/docs/guides/basic-features/data/data-fetch.md +415 -0
  268. package/docs/guides/basic-features/data/data-write.md +227 -0
  269. package/docs/guides/basic-features/debug/mock.md +109 -0
  270. package/docs/guides/basic-features/debug/proxy.md +21 -0
  271. package/docs/guides/basic-features/debug/rsdoctor.md +47 -0
  272. package/docs/guides/basic-features/debug/using-storybook.md +112 -0
  273. package/docs/guides/basic-features/deploy.md +458 -0
  274. package/docs/guides/basic-features/env-vars.md +177 -0
  275. package/docs/guides/basic-features/html.md +255 -0
  276. package/docs/guides/basic-features/output-files.md +141 -0
  277. package/docs/guides/basic-features/render/before-render.md +108 -0
  278. package/docs/guides/basic-features/render/overview.md +47 -0
  279. package/docs/guides/basic-features/render/rsc.md +516 -0
  280. package/docs/guides/basic-features/render/ssg.md +228 -0
  281. package/docs/guides/basic-features/render/ssr-cache.md +201 -0
  282. package/docs/guides/basic-features/render/ssr.md +321 -0
  283. package/docs/guides/basic-features/render/streaming-ssr.md +264 -0
  284. package/docs/guides/basic-features/routes/config-routes.md +426 -0
  285. package/docs/guides/basic-features/routes/routes.md +524 -0
  286. package/docs/guides/basic-features/static-assets/json-files.md +120 -0
  287. package/docs/guides/basic-features/static-assets/svg-assets.md +168 -0
  288. package/docs/guides/basic-features/static-assets/wasm-assets.md +62 -0
  289. package/docs/guides/basic-features/static-assets.md +160 -0
  290. package/docs/guides/basic-features/testing/playwright.md +120 -0
  291. package/docs/guides/basic-features/testing/rstest.md +251 -0
  292. package/docs/guides/concept/builder.md +37 -0
  293. package/docs/guides/concept/entries.md +319 -0
  294. package/docs/guides/concept/server.md +35 -0
  295. package/docs/guides/get-started/ai-coding-agents.md +58 -0
  296. package/docs/guides/get-started/glossary.md +63 -0
  297. package/docs/guides/get-started/introduction.md +40 -0
  298. package/docs/guides/get-started/quick-start.md +269 -0
  299. package/docs/guides/get-started/tech-stack.md +91 -0
  300. package/docs/guides/get-started/ultramodern.md +440 -0
  301. package/docs/guides/get-started/upgrade.md +118 -0
  302. package/docs/guides/topic-detail/module-federation/application.md +116 -0
  303. package/docs/guides/topic-detail/module-federation/deploy.md +104 -0
  304. package/docs/guides/topic-detail/module-federation/i18n.md +670 -0
  305. package/docs/guides/topic-detail/module-federation/introduce.md +35 -0
  306. package/docs/guides/topic-detail/module-federation/ssr.md +182 -0
  307. package/docs/guides/topic-detail/module-federation/usage.md +219 -0
  308. package/docs/guides/troubleshooting/builder.md +110 -0
  309. package/docs/guides/troubleshooting/cli.md +35 -0
  310. package/docs/guides/troubleshooting/dependencies.md +119 -0
  311. package/docs/guides/troubleshooting/hmr.md +144 -0
  312. package/docs/guides/upgrade/config.md +954 -0
  313. package/docs/guides/upgrade/entry.md +463 -0
  314. package/docs/guides/upgrade/other.md +183 -0
  315. package/docs/guides/upgrade/overview.md +33 -0
  316. package/docs/guides/upgrade/tailwindcss.md +91 -0
  317. package/docs/guides/upgrade/web-server.md +109 -0
  318. package/docs/index.md +33 -0
  319. package/docs/llms.txt +290 -0
  320. package/docs/plugin/cli-plugins/api.md +573 -0
  321. package/docs/plugin/cli-plugins/life-cycle.md +2 -0
  322. package/docs/plugin/introduction.md +152 -0
  323. package/docs/plugin/official/cli-plugins/plugin-bff.md +5 -0
  324. package/docs/plugin/official/cli-plugins/plugin-ssg.md +5 -0
  325. package/docs/plugin/official/cli-plugins/plugin-styled-components.md +5 -0
  326. package/docs/plugin/official/cli-plugins.md +4 -0
  327. package/docs/plugin/plugin-system.md +238 -0
  328. package/docs/plugin/runtime-plugins/api.md +194 -0
  329. package/docs/plugin/runtime-plugins/life-cycle.md +2 -0
  330. package/docs/plugin/server-plugins/api.md +209 -0
  331. package/docs/plugin/server-plugins/life-cycle.md +13 -0
  332. package/docs/tutorials/examples/csr-auth.md +9 -0
  333. package/docs/tutorials/foundations/introduction.md +16 -0
  334. package/package.json +63 -22
@@ -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
+ });
@@ -26,7 +26,7 @@ const initialize = ()=>({
26
26
  api.modifyResolvedConfig(async (resolved)=>{
27
27
  let appContext = api.getAppContext();
28
28
  const userConfig = api.getConfig();
29
- const port = await getServerPort(resolved);
29
+ const port = await getServerPort(resolved, appContext.command);
30
30
  appContext = {
31
31
  ...appContext,
32
32
  port,
@@ -61,9 +61,10 @@ function stabilizeConfig(resolve, config, keys) {
61
61
  resolve[key] = config[key] || {};
62
62
  });
63
63
  }
64
- async function getServerPort(config) {
64
+ async function getServerPort(config, contextCommand) {
65
65
  const prodPort = Number(process.env.PORT) || config.server.port || 8080;
66
- if (isDev() && isDevCommand()) return getPort(Number(process.env.PORT) || prodPort);
66
+ const isProgrammaticDev = 'dev' === contextCommand || 'start' === contextCommand;
67
+ if (isDev() && (isDevCommand() || isProgrammaticDev)) return getPort(Number(process.env.PORT) || prodPort);
67
68
  return prodPort;
68
69
  }
69
70
  export default initialize;
@@ -18,7 +18,7 @@ const serverBuild = ()=>({
18
18
  name: '@modern-js/server-build',
19
19
  setup (api) {
20
20
  api.onAfterBuild(async ()=>{
21
- const { appDirectory, distDirectory, metaName } = api.getAppContext();
21
+ const { appDirectory, distDirectory, metaName, moduleType } = api.getAppContext();
22
22
  if (!checkHasCache(appDirectory) && !checkHasConfig(appDirectory, metaName)) return;
23
23
  const modernConfig = api.getNormalizedConfig();
24
24
  const distDir = path.resolve(distDirectory);
@@ -38,7 +38,8 @@ const serverBuild = ()=>({
38
38
  }, {
39
39
  sourceDirs,
40
40
  distDir,
41
- tsconfigPath
41
+ tsconfigPath,
42
+ moduleType
42
43
  });
43
44
  });
44
45
  }
@@ -1,43 +1,16 @@
1
1
  import "node:module";
2
+ import { createHash } from "node:crypto";
2
3
  import promises from "node:fs/promises";
3
4
  import node_path from "node:path";
4
- import { parse } from "@babel/parser";
5
5
  import { BACKEND_FEDERATION_MANIFEST_FILE, BACKEND_FEDERATION_REMOTE_ENTRY_FILE, ULTRAMODERN_BUILD_ARTIFACT_FILE, isUltramodernBuildArtifact } from "@modern-js/utils/universal";
6
6
  import { canonicalSerializeMicroVerticalReleaseEnvelope, createMicroVerticalReleaseEnvelope, verifyMicroVerticalReleaseEnvelope } from "./index.mjs";
7
7
  const MICROVERTICAL_RELEASE_ENVELOPE_PATH = 'release/microvertical-release-envelope.json';
8
+ const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH = 'release/microvertical-release-identity-carriers.json';
9
+ const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_KIND = 'ultramodern-release-identity-carriers';
10
+ const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_SCHEMA_VERSION = 1;
8
11
  const COMPILED_MODULE_PATTERN = /\.(?:c|m)?js$/u;
9
12
  const EFFECT_BFF_WORKER_PATTERN = /^worker\/__modern_bff_effect\.(?:c|m)?js$/u;
10
13
  const isRecord = (value)=>'object' == typeof value && null !== value && !Array.isArray(value);
11
- const isAstNode = (value)=>isRecord(value) && 'string' == typeof value.type;
12
- const visitAst = (node, visitor)=>{
13
- visitor(node);
14
- for (const value of Object.values(node))if (isAstNode(value)) visitAst(value, visitor);
15
- else if (Array.isArray(value)) {
16
- for (const item of value)if (isAstNode(item)) visitAst(item, visitor);
17
- }
18
- };
19
- const compiledModuleIdentityValues = (source)=>{
20
- const values = new Set();
21
- const ast = parse(source, {
22
- sourceType: 'unambiguous'
23
- });
24
- visitAst(ast.program, (node)=>{
25
- if ('StringLiteral' === node.type && 'string' == typeof node.value) values.add(node.value);
26
- else if ('TemplateElement' === node.type && isRecord(node.value) && 'string' == typeof node.value.cooked) values.add(node.value.cooked);
27
- });
28
- return values;
29
- };
30
- const assertEveryCompiledIdentityCarrier = async (distDirectory, logicalPaths, identity, surface)=>{
31
- const compiledLogicalPaths = logicalPaths.filter((pathname)=>COMPILED_MODULE_PATTERN.test(pathname));
32
- if (0 === compiledLogicalPaths.length) throw new Error(`[ultramodern-release-envelope] ${surface} has no compiled execution module carrying release identity.`);
33
- for (const logicalPath of compiledLogicalPaths){
34
- const source = await promises.readFile(node_path.join(distDirectory, logicalPath), {
35
- encoding: 'utf8'
36
- });
37
- const values = compiledModuleIdentityValues(source);
38
- 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}.`);
39
- }
40
- };
41
14
  const flattenStrings = (value)=>'string' == typeof value ? [
42
15
  value
43
16
  ] : Array.isArray(value) ? value.flatMap(flattenStrings) : [];
@@ -180,6 +153,49 @@ const releaseArtifact = (logicalPath, runtime)=>({
180
153
  logicalPath,
181
154
  runtime
182
155
  });
156
+ const writeReleaseIdentityCarrierMetadata = async (artifactRoot, identity, carrierPaths)=>{
157
+ const surfacesByPath = new Map();
158
+ for (const [surface, logicalPaths] of Object.entries(carrierPaths)){
159
+ if (0 === logicalPaths.length) throw new Error(`[ultramodern-release-envelope] ${surface} has no declared release-identity carrier artifact.`);
160
+ for (const logicalPath of logicalPaths){
161
+ const surfaces = surfacesByPath.get(logicalPath) ?? new Set();
162
+ surfaces.add(surface);
163
+ surfacesByPath.set(logicalPath, surfaces);
164
+ }
165
+ }
166
+ const carriers = await Promise.all([
167
+ ...surfacesByPath
168
+ ].sort(([left], [right])=>left.localeCompare(right)).map(async ([logicalPath, surfaces])=>{
169
+ const bytes = await promises.readFile(node_path.join(artifactRoot, logicalPath));
170
+ return {
171
+ logicalPath,
172
+ byteLength: bytes.byteLength,
173
+ sha256: createHash('sha256').update(bytes).digest('hex'),
174
+ surfaces: [
175
+ ...surfaces
176
+ ].sort((left, right)=>left.localeCompare(right))
177
+ };
178
+ }));
179
+ const releaseEnvelopePath = await resolveSafeReleaseEnvelopePath({
180
+ artifactRoot,
181
+ createDirectory: true
182
+ });
183
+ if (!releaseEnvelopePath) throw new Error('[ultramodern-release-envelope] could not resolve private release metadata directory.');
184
+ const metadataPath = node_path.join(node_path.dirname(releaseEnvelopePath), node_path.basename(MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH));
185
+ try {
186
+ const metadataStat = await promises.lstat(metadataPath);
187
+ if (metadataStat.isSymbolicLink() || !metadataStat.isFile()) throw new Error('[ultramodern-release-envelope] release identity carrier metadata must be a real file inside artifactRoot.');
188
+ } catch (error) {
189
+ if (!isMissingPathError(error)) throw error;
190
+ }
191
+ await promises.writeFile(metadataPath, `${JSON.stringify({
192
+ schemaVersion: MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_SCHEMA_VERSION,
193
+ kind: MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_KIND,
194
+ identity,
195
+ carriers
196
+ }, null, 2)}\n`);
197
+ return releaseArtifact(MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH, 'release-identity-metadata');
198
+ };
183
199
  const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
184
200
  const files = await collectFiles(distDirectory);
185
201
  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.');
@@ -203,13 +219,7 @@ const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
203
219
  const clientExecutionPaths = await manifestReferencedClientModules(distDirectory, files);
204
220
  if (0 === clientExecutionPaths.length) throw new Error('[ultramodern-release-envelope] UI/client manifest references no compiled execution module.');
205
221
  const ssrExecutionPaths = await routeReferencedSsrModules(distDirectory, files, target);
206
- await assertEveryCompiledIdentityCarrier(distDirectory, clientExecutionPaths, identity, 'manifest-referenced UI/client');
207
- await assertEveryCompiledIdentityCarrier(distDirectory, ssrExecutionPaths, identity, 'node' === target ? 'route-referenced Node SSR' : 'route-referenced Cloudflare SSR');
208
- await assertEveryCompiledIdentityCarrier(distDirectory, ssrPaths, identity, 'node' === target ? 'compiled Node SSR closure' : 'compiled Cloudflare SSR/workerd closure');
209
- await assertEveryCompiledIdentityCarrier(distDirectory, 'node' === target ? nodeApiEntryPaths : apiBackendPaths, identity, 'node' === target ? 'Node API/backend' : 'Cloudflare API/backend');
210
- await assertEveryCompiledIdentityCarrier(distDirectory, [
211
- BACKEND_FEDERATION_REMOTE_ENTRY_FILE
212
- ], identity, 'backend Module Federation container');
222
+ if (0 === ssrExecutionPaths.length) throw new Error(`[ultramodern-release-envelope] route manifest references no emitted ${'node' === target ? 'Node' : 'Cloudflare'} SSR execution module.`);
213
223
  const runtimeByPath = new Map();
214
224
  const add = (paths, runtime)=>{
215
225
  for (const logicalPath of paths){
@@ -245,8 +255,25 @@ const createReleaseArtifactInputs = async (distDirectory, identity, target)=>{
245
255
  const artifacts = [
246
256
  ...runtimeByPath
247
257
  ].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)).sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath));
258
+ const identityCarrierMetadata = await writeReleaseIdentityCarrierMetadata(distDirectory, identity, {
259
+ apiBackend: apiBackendPaths,
260
+ backendFederation: [
261
+ BACKEND_FEDERATION_MANIFEST_FILE,
262
+ BACKEND_FEDERATION_REMOTE_ENTRY_FILE
263
+ ],
264
+ ssr: [
265
+ ...new Set([
266
+ ...ssrExecutionPaths,
267
+ ...ssrPaths
268
+ ])
269
+ ],
270
+ uiClient: uiClientPaths.filter((logicalPath)=>COMPILED_MODULE_PATTERN.test(logicalPath))
271
+ });
248
272
  return {
249
- artifacts,
273
+ artifacts: [
274
+ ...artifacts,
275
+ identityCarrierMetadata
276
+ ].sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath)),
250
277
  surfaces
251
278
  };
252
279
  };
@@ -368,13 +395,7 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
368
395
  ])if (0 === paths.length) throw new Error(`[ultramodern-release-envelope] final Node staging has no ${surface} artifacts.`);
369
396
  const clientExecutionPaths = await manifestReferencedClientModules(outputDirectory, files);
370
397
  const ssrExecutionPaths = await routeReferencedSsrModules(outputDirectory, files, 'node');
371
- await assertEveryCompiledIdentityCarrier(outputDirectory, clientExecutionPaths, identity, 'final manifest-referenced Node UI/client');
372
- await assertEveryCompiledIdentityCarrier(outputDirectory, ssrExecutionPaths, identity, 'final route-referenced Node SSR');
373
- await assertEveryCompiledIdentityCarrier(outputDirectory, ssrPaths.filter((logicalPath)=>'index.js' !== logicalPath), identity, 'final compiled Node SSR closure');
374
- await assertEveryCompiledIdentityCarrier(outputDirectory, apiBackendPaths.filter((logicalPath)=>logicalPath.startsWith('api/')), identity, 'final Node API/backend');
375
- await assertEveryCompiledIdentityCarrier(outputDirectory, [
376
- BACKEND_FEDERATION_REMOTE_ENTRY_FILE
377
- ], identity, 'final Node backend Module Federation container');
398
+ 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.');
378
399
  const runtimeByPath = new Map(files.filter((logicalPath)=>!backendFederationPaths.has(logicalPath)).map((logicalPath)=>[
379
400
  logicalPath,
380
401
  'nodejs-deployment'
@@ -384,10 +405,27 @@ const createNodeStagedReleaseArtifactInputs = async (outputDirectory, identity)=
384
405
  for (const logicalPath of apiBackendPaths)runtimeByPath.set(logicalPath, 'nodejs');
385
406
  runtimeByPath.set(BACKEND_FEDERATION_MANIFEST_FILE, 'module-federation-manifest');
386
407
  runtimeByPath.set(BACKEND_FEDERATION_REMOTE_ENTRY_FILE, 'nodejs');
408
+ const identityCarrierMetadata = await writeReleaseIdentityCarrierMetadata(outputDirectory, identity, {
409
+ apiBackend: apiBackendPaths,
410
+ backendFederation: [
411
+ BACKEND_FEDERATION_MANIFEST_FILE,
412
+ BACKEND_FEDERATION_REMOTE_ENTRY_FILE
413
+ ],
414
+ ssr: [
415
+ ...new Set([
416
+ ...ssrExecutionPaths,
417
+ ...ssrPaths.filter((logicalPath)=>'index.js' !== logicalPath)
418
+ ])
419
+ ],
420
+ uiClient: uiClientPaths.filter((logicalPath)=>COMPILED_MODULE_PATTERN.test(logicalPath))
421
+ });
387
422
  return {
388
423
  artifacts: [
389
- ...runtimeByPath
390
- ].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)).sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath)),
424
+ ...[
425
+ ...runtimeByPath
426
+ ].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)),
427
+ identityCarrierMetadata
428
+ ].sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath)),
391
429
  surfaces: {
392
430
  uiClient: [
393
431
  ...uiClientPaths
@@ -461,13 +499,7 @@ const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, iden
461
499
  ])if (!files.includes(logicalPath)) throw new Error(`[ultramodern-release-envelope] final Cloudflare staging is missing ${logicalPath}.`);
462
500
  const clientExecutionPaths = await manifestReferencedClientModules(outputDirectory, files, 'public/mf-manifest.json');
463
501
  const ssrExecutionPaths = await routeReferencedSsrModules(outputDirectory, files, 'cloudflare', 'server/route.json');
464
- await assertEveryCompiledIdentityCarrier(outputDirectory, clientExecutionPaths, identity, 'final manifest-referenced Cloudflare UI/client');
465
- await assertEveryCompiledIdentityCarrier(outputDirectory, ssrExecutionPaths, identity, 'final route-referenced Cloudflare SSR');
466
- await assertEveryCompiledIdentityCarrier(outputDirectory, ssrPaths.filter((logicalPath)=>logicalPath.startsWith('worker/')), identity, 'final compiled Cloudflare SSR/workerd closure');
467
- await assertEveryCompiledIdentityCarrier(outputDirectory, apiBackendPaths, identity, 'final Cloudflare API/backend');
468
- await assertEveryCompiledIdentityCarrier(outputDirectory, [
469
- backendContainerPath
470
- ], identity, 'final Cloudflare backend Module Federation container');
502
+ 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.');
471
503
  const runtimeByPath = new Map();
472
504
  for (const logicalPath of files)runtimeByPath.set(logicalPath, 'cloudflare-deployment');
473
505
  const add = (paths, runtime)=>{
@@ -482,10 +514,27 @@ const createCloudflareStagedReleaseArtifactInputs = async (outputDirectory, iden
482
514
  add([
483
515
  backendContainerPath
484
516
  ], 'commonjs-module');
517
+ const identityCarrierMetadata = await writeReleaseIdentityCarrierMetadata(outputDirectory, identity, {
518
+ apiBackend: apiBackendPaths,
519
+ backendFederation: [
520
+ backendManifestPath,
521
+ backendContainerPath
522
+ ],
523
+ ssr: [
524
+ ...new Set([
525
+ ...ssrExecutionPaths,
526
+ ...ssrPaths.filter((logicalPath)=>logicalPath.startsWith('worker/'))
527
+ ])
528
+ ],
529
+ uiClient: uiClientPaths.filter((logicalPath)=>COMPILED_MODULE_PATTERN.test(logicalPath))
530
+ });
485
531
  return {
486
532
  artifacts: [
487
- ...runtimeByPath
488
- ].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)).sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath)),
533
+ ...[
534
+ ...runtimeByPath
535
+ ].map(([logicalPath, runtime])=>releaseArtifact(logicalPath, runtime)),
536
+ identityCarrierMetadata
537
+ ].sort((left, right)=>left.logicalPath.localeCompare(right.logicalPath)),
489
538
  surfaces: {
490
539
  uiClient: [
491
540
  ...uiClientPaths
@@ -522,4 +571,4 @@ const verifyCloudflareReleaseEnvelopeStaging = async (outputDirectory)=>readFram
522
571
  expectedTarget: 'cloudflare',
523
572
  required: true
524
573
  });
525
- export { MICROVERTICAL_RELEASE_ENVELOPE_PATH, emitCloudflareStagedReleaseEnvelope, emitFrameworkMicroVerticalReleaseEnvelope, emitNodeStagedReleaseEnvelope, readFrameworkMicroVerticalReleaseEnvelope, stageCloudflareReleaseEnvelope, verifyBuildOutputReleaseEnvelope, verifyCloudflareReleaseEnvelopeStaging, verifyNodeReleaseEnvelopeStaging };
574
+ export { MICROVERTICAL_RELEASE_ENVELOPE_PATH, MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH, emitCloudflareStagedReleaseEnvelope, emitFrameworkMicroVerticalReleaseEnvelope, emitNodeStagedReleaseEnvelope, readFrameworkMicroVerticalReleaseEnvelope, stageCloudflareReleaseEnvelope, verifyBuildOutputReleaseEnvelope, verifyCloudflareReleaseEnvelopeStaging, verifyNodeReleaseEnvelopeStaging };
@@ -1,5 +1,34 @@
1
+ import type { ModifyBundlerChainFn } from '@rsbuild/core';
1
2
  import type { AppNormalizedConfig } from '../../types';
2
3
  import type { AppToolsContext } from '../../types/plugin';
4
+ export declare function getCloudflareWorkerRspackConfig(workerEntryNames: Iterable<string>): {
5
+ readonly experiments: {
6
+ readonly outputModule: true;
7
+ };
8
+ readonly externals: {
9
+ [k: string]: string;
10
+ };
11
+ readonly externalsType: 'module-import';
12
+ readonly module: {
13
+ readonly parser: {
14
+ readonly javascript: {
15
+ readonly dynamicImportMode: 'eager';
16
+ };
17
+ };
18
+ };
19
+ readonly optimization: {
20
+ readonly runtimeChunk: {
21
+ readonly name: string;
22
+ };
23
+ readonly splitChunks: {
24
+ readonly chunks: 'all';
25
+ readonly minSize: 0;
26
+ readonly name: string;
27
+ };
28
+ };
29
+ };
30
+ export declare function applyCloudflareWorkerRspackConfig(chain: Parameters<ModifyBundlerChainFn>[0], workerEntryNames: Iterable<string>): void;
31
+ export declare function applyCloudflareWorkerMfRuntimeBoundary(chain: Parameters<ModifyBundlerChainFn>[0]): void;
3
32
  export declare function getBuilderEnvironments(normalizedConfig: AppNormalizedConfig, appContext: AppToolsContext, tempBuilderConfig: Omit<AppNormalizedConfig, 'plugins'>): {
4
33
  environments: Record<string, import("@rsbuild/core").EnvironmentConfig>;
5
34
  builderConfig: Omit<AppNormalizedConfig, "plugins">;
@@ -0,0 +1,20 @@
1
+ export interface BundleDocsOptions {
2
+ /** Docs site build output (e.g. `doc_build`). */
3
+ source: string;
4
+ /** Directory to write the bundle to. */
5
+ target: string;
6
+ /** Index file to ship alongside the pages. */
7
+ indexFile?: string;
8
+ /** Top-level directories to skip. */
9
+ excludedDirs?: string[];
10
+ }
11
+ /** @returns files copied, or 0 when the source is absent */
12
+ export declare function bundleDocs({ source, target, indexFile, excludedDirs, }: BundleDocsOptions): number;
13
+ /**
14
+ * `modern-bundle-docs --source <doc_build> --target <pkg>/docs`; both default
15
+ * to this repo's layout.
16
+ *
17
+ * @param pkgRoot supplied by the bin shim — the compiled module cannot know
18
+ * its own package root portably across output formats.
19
+ */
20
+ export declare function runBundleDocsCli(pkgRoot: string): void;
@@ -1,3 +1,4 @@
1
1
  import type { CLIPluginAPI } from '@modern-js/plugin';
2
2
  import type { AppTools } from '../types';
3
- export declare const deploy: (api: CLIPluginAPI<AppTools>, options: any) => Promise<void>;
3
+ import type { DeployOptions } from '../utils/types';
4
+ export declare const deploy: (api: CLIPluginAPI<AppTools>, options?: DeployOptions) => Promise<void>;
@@ -3,13 +3,16 @@ import { initAppContext } from './utils/initAppContext';
3
3
  export * from './defineConfig';
4
4
  export * from './presetUltramodern';
5
5
  export declare const appTools: () => CliPlugin<AppTools>;
6
+ export { build } from './commands/build';
7
+ export { deploy } from './commands/deploy';
6
8
  export { dev } from './commands/dev';
7
9
  export { serve } from './commands/serve';
8
10
  export { defineConfig } from './defineConfig';
9
11
  export { type ResolveModernRsbuildConfigOptions, resolveModernRsbuildConfig, } from './rsbuild';
10
12
  export * from './types';
13
+ export { closeServer } from './utils/createServer';
11
14
  export { generateWatchFiles } from './utils/generateWatchFiles';
12
- export type { DevOptions } from './utils/types';
15
+ export type { BuildOptions, DeployOptions, DevOptions } from './utils/types';
13
16
  export { initAppContext };
14
17
  export default appTools;
15
18
  export { mergeConfig } from '@modern-js/plugin/cli';
@@ -5,6 +5,6 @@ export declare const parseModule: ({ source, filename, }: {
5
5
  filename: string;
6
6
  }) => Promise<readonly [imports: readonly import("es-module-lexer").ImportSpecifier[], exports: readonly import("es-module-lexer").ExportSpecifier[], facade: boolean, hasModuleSyntax: boolean]>;
7
7
  export declare const getServerCombinedModuleFile: (internalDirectory: string, entryName: string) => string;
8
- export declare const checkIsBuildCommands: () => boolean;
8
+ export declare const checkIsBuildCommands: (contextCommand?: string) => boolean;
9
9
  export declare const checkIsServeCommand: () => boolean;
10
10
  export declare const isSubDirOrEqual: (parent: string, child: string) => boolean;
@@ -16,5 +16,5 @@ interface WorkerBundleVerificationContract {
16
16
  workerRoot: string;
17
17
  }
18
18
  export declare const verifyWorkerBundleReferences: (issues: CloudflareOutputVerifierIssue[], worker: ResolvedWorkerBundleReference, source: string, contract: WorkerBundleVerificationContract) => Promise<void>;
19
- export declare const verifyWorkerImport: (issues: CloudflareOutputVerifierIssue[], entryPath: string) => Promise<void>;
19
+ export declare const verifyWorkerImport: (issues: CloudflareOutputVerifierIssue[], entryPath: string, expectedManifest?: JsonObject) => Promise<void>;
20
20
  export {};
@@ -1 +1 @@
1
- export {};
1
+ export declare const modernWorkerManifest: any;
@@ -0,0 +1,13 @@
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 declare const injectDataFetchFunctionPlugin: () => {
7
+ name: string;
8
+ setup(): void;
9
+ };
10
+ export declare const mfSSRDevPlugin: () => {
11
+ name: string;
12
+ setup(): void;
13
+ };
@@ -46,6 +46,12 @@ export interface DevServerUserConfig {
46
46
  * Although its name is the same as in Rsbuild, it is consumed by Modern.js.
47
47
  */
48
48
  export type DevUserConfig = Omit<BuilderDevConfig, 'setupMiddlewares'> & {
49
+ /**
50
+ * Customize the directory containing the Mock API entry file.
51
+ * Relative paths are resolved from the application directory.
52
+ * @default './config/mock'
53
+ */
54
+ mockDir?: string;
49
55
  setupMiddlewares?: SetupMiddlewares;
50
56
  /**
51
57
  * Dev server specific options.
@@ -1,5 +1,6 @@
1
1
  import type { MicroVerticalReleaseArtifact, MicroVerticalReleaseEnvelope, MicroVerticalReleaseTarget } from './types';
2
2
  export declare const MICROVERTICAL_RELEASE_ENVELOPE_PATH = "release/microvertical-release-envelope.json";
3
+ export declare const MICROVERTICAL_RELEASE_IDENTITY_CARRIERS_PATH = "release/microvertical-release-identity-carriers.json";
3
4
  export declare const emitFrameworkMicroVerticalReleaseEnvelope: ({ apiOnly, distDirectory, target, }: {
4
5
  apiOnly: boolean;
5
6
  distDirectory: string;