@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
@@ -0,0 +1,243 @@
1
+ # Runtime Framework
2
+
3
+ Modern.js supports two BFF runtime frameworks:
4
+
5
+ - `effect` (default): use [Effect HttpApi](https://effect.website/) runtime from `api/index`.
6
+ - `hono`: use file-convention BFF handlers from `api/lambda/**`.
7
+
8
+ `effect` and `hono` are strict runtime modes. There is no automatic fallback between them.
9
+
10
+ ::::info
11
+ This page documents generic Modern.js runtime support. Generated UltraModern
12
+ workspaces always use the `effect` runtime with
13
+ `bff.effect.strictEffectApproach: true`. Add or change generated UltraModern
14
+ HTTP API work through `shared/api.ts` and `api/index.ts`; do not add
15
+ Hono/file-convention handlers, raw request parsing, or manual `Response`
16
+ construction inside those workspaces.
17
+ ::::
18
+
19
+ ## Switch to Effect runtime
20
+
21
+ ```ts title="modern.config.ts"
22
+ import { bffPlugin } from '@modern-js/plugin-bff';
23
+ import { defineConfig } from '@modern-js/app-tools';
24
+
25
+ export default defineConfig({
26
+ plugins: [bffPlugin()],
27
+ bff: {
28
+ runtimeFramework: 'effect',
29
+ effect: {
30
+ entry: './api/index',
31
+ strictEffectApproach: true,
32
+ openapi: {
33
+ path: '/openapi.json',
34
+ },
35
+ },
36
+ },
37
+ });
38
+ ```
39
+
40
+ Define a shared Effect HttpApi contract (for type-safe client + server):
41
+
42
+ ```ts title="shared/api.ts"
43
+ import {
44
+ HttpApi,
45
+ HttpApiEndpoint,
46
+ HttpApiGroup,
47
+ Schema,
48
+ } from '@modern-js/plugin-bff/effect-client';
49
+
50
+ export const bffApi = HttpApi.make('MyApi').add(
51
+ HttpApiGroup.make('hello').add(
52
+ HttpApiEndpoint.get('ping', '/ping', {
53
+ success: Schema.String,
54
+ }),
55
+ ),
56
+ );
57
+ ```
58
+
59
+ Implement your Effect API entry at `api/index.ts`:
60
+
61
+ ```ts title="api/index.ts"
62
+ import {
63
+ Schema,
64
+ Effect,
65
+ HttpApiBuilder,
66
+ defineEffectBff,
67
+ Layer,
68
+ ServiceMap,
69
+ } from '@modern-js/plugin-bff/effect-server';
70
+ import { bffApi } from '../shared/api';
71
+
72
+ class GreetingUnavailableError extends Schema.TaggedError<GreetingUnavailableError>()(
73
+ 'GreetingUnavailableError',
74
+ {
75
+ message: Schema.String,
76
+ },
77
+ ) {}
78
+
79
+ class GreetingService extends ServiceMap.Service<GreetingService>()('GreetingService', {
80
+ make: Effect.succeed({
81
+ hello: Effect.fn('GreetingService.hello')(function* () {
82
+ if (Date.now() < 0) {
83
+ return yield* Effect.fail(
84
+ new GreetingUnavailableError({
85
+ message: 'Greeting service is unavailable',
86
+ }),
87
+ );
88
+ }
89
+ return yield* Effect.succeed('pong');
90
+ }),
91
+ }),
92
+ }) {
93
+ static readonly layer = Layer.effect(this, this.make);
94
+ }
95
+
96
+ const group = HttpApiBuilder.group(bffApi, 'hello', handlers =>
97
+ handlers.handle('ping', () =>
98
+ GreetingService.use(service => service.hello()).pipe(
99
+ Effect.catchTag('GreetingUnavailableError', error =>
100
+ Effect.succeed(error.message),
101
+ ),
102
+ ),
103
+ ),
104
+ );
105
+
106
+ const layer = HttpApiBuilder.layer(bffApi).pipe(
107
+ Layer.provide(group),
108
+ Layer.provide(GreetingService.layer),
109
+ );
110
+
111
+ export default defineEffectBff({ api: bffApi, layer });
112
+ ```
113
+
114
+ Call Effect endpoints from browser code via `@api/index`:
115
+
116
+ ```ts title="src/routes/page.tsx"
117
+ import api from '@api/index';
118
+
119
+ const response = await api.client.hello.ping({});
120
+ ```
121
+
122
+ The `api.client.*` surface is materialized by the BFF loader for `@api/index` imports. Do not import `api/index` directly and expect `client` to run in server code, scripts, or tests; direct entry imports expose the server runtime definition, and `client` is only a typed placeholder there.
123
+
124
+ ### Getting Request Context
125
+
126
+ Sometimes in BFF functions, it's necessary to obtain the request context to handle more logic. In such cases, you can use `useHonoContext` to get it:
127
+
128
+ ```ts title="api/lambda/hello.ts"
129
+ import { useHonoContext } from '@modern-js/server-runtime';
130
+
131
+ export const get = async () => {
132
+ const c = useHonoContext();
133
+ console.info(`access url: ${c.req.url}`);
134
+ return 'Hello Modern.js';
135
+ };
136
+ ```
137
+
138
+ :::info
139
+ For more details, refer to [useHonoContext](/apis/app/runtime/bff/use-backend-context.md).
140
+ :::
141
+
142
+ ### Getting Cookies
143
+
144
+ When getting cookies in BFF functions, you need to get the request context through `useHonoContext`, then use `c.req.header('cookie')` to get the Cookie string and parse it manually:
145
+
146
+ ```ts title="api/lambda/cookies.ts"
147
+ import { Api, Get } from '@modern-js/plugin-bff/hono-server';
148
+ import { useHonoContext } from '@modern-js/server-runtime';
149
+
150
+ // Helper function to parse Cookie string
151
+ function parseCookies(
152
+ cookieHeader: string | undefined,
153
+ ): Record<string, string> {
154
+ const cookies: Record<string, string> = {};
155
+ if (!cookieHeader) return cookies;
156
+
157
+ cookieHeader.split(';').forEach(cookie => {
158
+ const [name, ...rest] = cookie.trim().split('=');
159
+ if (name) {
160
+ cookies[name] = rest.join('=');
161
+ }
162
+ });
163
+
164
+ return cookies;
165
+ }
166
+
167
+ export const getCookies = Api(Get('/cookies'), async () => {
168
+ const c = useHonoContext();
169
+ const cookieHeader = c.req.header('cookie');
170
+ const cookies = parseCookies(cookieHeader);
171
+ const token = cookies.token;
172
+ const sessionId = cookies.sessionId;
173
+ return {
174
+ hasToken: !!token,
175
+ token: token || null,
176
+ sessionId: sessionId || null,
177
+ };
178
+ });
179
+ ```
180
+
181
+ :::caution Note
182
+ The `c.req.cookie()` method does not exist in the current version. You need to use `c.req.header('cookie')` to get the Cookie string and parse it manually.
183
+ :::
184
+
185
+ ### Defining BFF Functions
186
+
187
+ When using Hono as the runtime framework, you can define interfaces through [Api functions](/guides/advanced-features/bff/operators.md):
188
+
189
+ ```ts title="api/lambda/user.ts"
190
+ import { Api, Get, Query } from '@modern-js/plugin-bff/hono-server';
191
+ import { z } from 'zod';
192
+
193
+ const QuerySchema = z.object({
194
+ id: z.string(),
195
+ });
196
+
197
+ export const getUser = Api(
198
+ Get('/user'),
199
+ Query(QuerySchema),
200
+ async ({ query }) => {
201
+ return {
202
+ id: query.id,
203
+ name: 'Modern.js',
204
+ email: 'modernjs@bytedance.com',
205
+ };
206
+ },
207
+ );
208
+ ```
209
+
210
+ :::info
211
+ For more details about Api functions and operators, refer to [Creating Extensible BFF Functions](/guides/advanced-features/bff/operators.md).
212
+ :::
213
+
214
+ ### Using Middleware
215
+
216
+ Hono supports a rich middleware ecosystem, and you can use middleware in BFF functions:
217
+
218
+ ```ts title="api/lambda/user.ts"
219
+ import { Api, Get, Middleware } from '@modern-js/plugin-bff/hono-server';
220
+
221
+ export const getUser = Api(
222
+ Get('/user'),
223
+ Middleware(async (c, next) => {
224
+ // You can access Hono's Context in middleware
225
+ c.res.headers.set('X-Powered-By', 'Modern.js');
226
+ await next();
227
+ }),
228
+ async () => {
229
+ return {
230
+ name: 'Modern.js',
231
+ email: 'modernjs@bytedance.com',
232
+ };
233
+ },
234
+ );
235
+ ```
236
+
237
+ :::info
238
+ For more details about middleware, refer to [Creating Extensible BFF Functions](/guides/advanced-features/bff/operators.md#middleware).
239
+ :::
240
+
241
+ ### More Hono Documentation
242
+
243
+ For more detailed information about Hono, please refer to the [Hono official documentation](https://hono.dev/).
@@ -0,0 +1,318 @@
1
+ # Basic Usage
2
+
3
+ In a Modern.js application, developers can define API files under the `api/lambda` directory and export API functions from these files. In the frontend code, these API functions can be directly invoked by importing the file, which initiates the API requests.
4
+
5
+ :::warning
6
+ `api/lambda/**` is the Hono/file-function compatibility runtime. New UltraModern generated API work should use the strict Effect runtime with `api/index.ts`, `shared/api.ts`, `defineEffectBff(...)`, and Effect `HttpApi` schemas instead.
7
+ :::
8
+
9
+ This invocation method is called **unified invocation**, where developers do not need to write glue code for the frontend and backend separately, thereby ensuring type safety across both.
10
+
11
+ ## Enable BFF
12
+
13
+ To enable BFF functionality in a Modern.js project, follow these steps to modify the code:
14
+
15
+ 1. Install BFF plugin dependencies
16
+
17
+ If the BFF plugin is not yet installed in your project, install it first:
18
+
19
+ ```bash
20
+ pnpm add @modern-js/plugin-bff
21
+ ```
22
+
23
+ :::tip Version Consistency
24
+ Make sure the version of `@modern-js/plugin-bff` matches the version of `@modern-js/app-tools` in your project. All Modern.js official packages are released with a uniform version number, and version mismatches may cause compatibility issues.
25
+
26
+ Check the version of `@modern-js/app-tools` first, then install the same version of `@modern-js/plugin-bff`:
27
+
28
+ ```bash
29
+ # Check the current version of @modern-js/app-tools
30
+ pnpm list @modern-js/app-tools
31
+
32
+ # Install the same version of @modern-js/plugin-bff
33
+ pnpm add @modern-js/plugin-bff@<version>
34
+ ```
35
+
36
+ :::
37
+
38
+ 2. Configure `modern.config.ts`
39
+
40
+ Import and add the BFF plugin in the `modern.config.ts` file:
41
+
42
+ ```ts title="modern.config.ts"
43
+ import { defineConfig, appTools } from '@modern-js/app-tools';
44
+ import { bffPlugin } from '@modern-js/plugin-bff';
45
+
46
+ export default defineConfig({
47
+ plugins: [appTools(), bffPlugin()],
48
+ });
49
+ ```
50
+
51
+ 3. Configure TypeScript alias
52
+
53
+ To correctly recognize the `@api` alias in TypeScript, it is recommended to add path mapping in `tsconfig.json`:
54
+
55
+ ```json title="tsconfig.json"
56
+ {
57
+ "compilerOptions": {
58
+ "paths": {
59
+ ..., // other paths,
60
+ "@api/*": ["./api/lambda/*"]
61
+ }
62
+ },
63
+ "include": [
64
+ ..., // other include directories
65
+ "api" // Add api directory
66
+ ]
67
+ }
68
+ ```
69
+
70
+ ## BFF Functions
71
+
72
+ Functions that allow unified invocation are called **BFF Functions**. Here is an example of the simplest BFF function. First, create the `api/lambda/hello.ts` file:
73
+
74
+ ```ts title="api/lambda/hello.ts"
75
+ export const get = async () => 'Hello Modern.js';
76
+ ```
77
+
78
+ Then, import and invoke the function directly in `src/routes/page.tsx`:
79
+
80
+ ```tsx title="src/routes/page.tsx"
81
+ import { useState, useEffect } from 'react';
82
+ import { get as hello } from '@api/hello';
83
+
84
+ export default () => {
85
+ const [text, setText] = useState('');
86
+
87
+ useEffect(() => {
88
+ hello().then(setText);
89
+ }, []);
90
+ return <div>{text}</div>;
91
+ };
92
+ ```
93
+
94
+ The function imported in `src/routes/page.tsx` will be automatically converted into an API call, eliminating the need to use an SDK or Web Fetch to call the API.
95
+
96
+ After running `pnpm run dev`, open `http://localhost:8080/` and you can see that the page displays the content returned by the BFF function. In the Network tab, you can see a request was made to `http://localhost:8080/api/hello`.
97
+
98
+ ![Network](https://p6-piu.byteimg.com/tos-cn-i-8jisjyls3a/fd41750f8d414179a9b4ecb519919b36~tplv-8jisjyls3a-3:0:0:q75.png)
99
+
100
+ ## Function Routes
101
+
102
+ In Modern.js, the routing system for BFF functions is implemented based on the file system, which is another form of **conventional routing**. Each BFF function in the `api/lambda` directory is mapped to an API route. Here are some routing conventions.
103
+
104
+ :::info
105
+ All routes generated by BFF functions have a common prefix, which defaults to `/api`. This can be configured using [bff.prefix](/configure/app/bff/prefix.md).
106
+ :::
107
+
108
+ ### Default Routes
109
+
110
+ Files named `index.ts` will be mapped to the parent directory.
111
+
112
+ - `api/lambda/index.ts` -> `{prefix}/`
113
+ - `api/lambda/user/index.ts` -> `{prefix}/user`
114
+
115
+ ### Nested Routes
116
+
117
+ Nested directories are supported, and files will be automatically parsed into routes in the same way.
118
+
119
+ - `api/lambda/hello.ts` -> `{prefix}/hello`
120
+ - `api/lambda/user/list.ts` -> `{prefix}/user/list`
121
+
122
+ ### Dynamic Routes
123
+
124
+ Similarly, creating a directory or file with `[xxx]` in the name supports dynamic route parameters. The rules for dynamic route function parameters can be found in [dynamic-path](/guides/advanced-features/bff/function.md#dynamic-path).
125
+
126
+ - `api/lambda/user/[username]/info.ts` -> `{prefix}/user/:username/info`
127
+ - `api/lambda/user/username/[action].ts` -> `{prefix}/user/username/:action`
128
+
129
+ ### Whitelist
130
+
131
+ By default, all files under the `api/lambda/` directory are parsed as BFF function files, but the following files are ignored:
132
+
133
+ - Files starting with an underscore `_`. For example: `_utils.ts`.
134
+ - Files under directories starting with an underscore `_`. For example: `_utils/index.ts`, `_utils/cp.ts`.
135
+ - Test files. For example: `foo.test.ts`.
136
+ - TypeScript type files. For example: `hello.d.ts`.
137
+ - Files under `node_modules`.
138
+
139
+ ## RESTful API
140
+
141
+ Modern.js BFF functions need to follow RESTful API standards for definition. Developers must define BFF functions according to a set of rules.
142
+
143
+ :::tip Design Principles
144
+ BFF functions should not only be invoked within the project but also be accessible to other projects via an SDK or Web fetch. Therefore, Modern.js does not define a **private protocol** for unified invocation but uses standard HTTP methods along with common HTTP request parameters like `params`, `query`, and `body` to define functions.
145
+ :::
146
+
147
+ ### Function Export Rules
148
+
149
+ #### HTTP Method Named Functions
150
+
151
+ Modern.js BFF functions' export names determine the HTTP method for the corresponding API, such as `get`, `post`, etc. For example, to export a GET API:
152
+
153
+ ```ts
154
+ export const get = async () => {
155
+ return {
156
+ name: 'Modern.js',
157
+ desc: 'A modern web engineering solution',
158
+ };
159
+ };
160
+ ```
161
+
162
+ The following example exports a `POST` API:
163
+
164
+ ```ts
165
+ export const post = async () => {
166
+ return {
167
+ name: 'Modern.js',
168
+ desc: 'A modern web engineering solution',
169
+ };
170
+ };
171
+ ```
172
+
173
+ - Modern.js supports 9 HTTP methods: `GET`, `POST`, `PUT`, `DELETE`, `CONNECT`, `TRACE`, `PATCH`, `OPTIONS`, and `HEAD`, which can be used as function export names.
174
+
175
+ - Names are case-insensitive. If the method is `GET`, it can be written as `get`, `Get`, `GEt`, or `GET`, and the default export, i.e., `export default xxx`, will be mapped to `Get`.
176
+
177
+ #### Using Async Functions
178
+
179
+ Modern.js recommends defining BFF functions as async functions, even if there is no asynchronous process in the function, for example:
180
+
181
+ ```ts
182
+ export const get = async () => {
183
+ return {
184
+ name: 'Modern.js',
185
+ desc: 'A modern web engineering solution',
186
+ };
187
+ };
188
+ ```
189
+
190
+ This is because, during frontend invocation, the BFF function will be automatically converted into an HTTP API call, and HTTP API calls are asynchronous. On the frontend, it is typically used like this:
191
+
192
+ ```tsx title="src/routes/page.tsx"
193
+ import { useState, useEffect } from 'react';
194
+ import { get as hello } from '@api/hello';
195
+
196
+ export default () => {
197
+ const [text, setText] = useState('');
198
+
199
+ useEffect(() => {
200
+ hello().then(setText);
201
+ }, []);
202
+ return <div>{text}</div>;
203
+ };
204
+ ```
205
+
206
+ Therefore, to keep the type definitions consistent with the actual invocation experience, we recommend defining BFF functions as async functions.
207
+
208
+ ### Function Parameter Rules
209
+
210
+ Function parameter rules are divided into two parts: dynamic routes in the request path (`Dynamic Path`) and request options (`RequestOption`).
211
+
212
+ #### Dynamic Path
213
+
214
+ Dynamic routes will be the first part of the BFF function parameters, with each parameter corresponding to a segment of the dynamic route. For example, the `level` and `id` parameters will be passed to the function in the following example:
215
+
216
+ ```ts title="api/lambda/[level]/[id].ts"
217
+ export default async (level: number, id: number) => {
218
+ const userData = await queryUser(level, uid);
219
+ return userData;
220
+ };
221
+ ```
222
+
223
+ Invoke the function by directly passing in the dynamic parameters:
224
+
225
+ ```tsx title="src/routes/page.tsx"
226
+ import { useState, useEffect } from 'react';
227
+ import { get as getUser } from '@api/[level]/[id]';
228
+
229
+ export default () => {
230
+ const [name, setName] = useState('');
231
+
232
+ useEffect(() => {
233
+ getUser(6, 001).then(userData => setName(userData.name));
234
+ }, []);
235
+
236
+ return <div>{name}</div>;
237
+ };
238
+ ```
239
+
240
+ #### RequestOption
241
+
242
+ Parameters following the dynamic path are an object called `RequestOption`, which includes the query string and request body. This field is used to define the types for `data` and `query`.
243
+
244
+ In a standard function without dynamic routes, `RequestOption` can be obtained from the first parameter, for example:
245
+
246
+ ```ts title="api/lambda/hello.ts"
247
+ import type { RequestOption } from '@modern-js/plugin-bff/hono-server';
248
+
249
+ export async function post({
250
+ query,
251
+ data,
252
+ }: RequestOption<Record<string, string>, Record<string, string>>) {
253
+ // do something
254
+ }
255
+ ```
256
+
257
+ Custom types can also be used here:
258
+
259
+ ```ts title="api/lambda/hello.ts"
260
+ import type { RequestOption } from '@modern-js/plugin-bff/hono-server';
261
+
262
+ type IQuery = {
263
+ // some types
264
+ };
265
+ type IData = {
266
+ // some types
267
+ };
268
+
269
+ export async function post({ query, data }: { query: IQuery; data: IData }) {
270
+ // do something
271
+ }
272
+ ```
273
+
274
+ When the function file uses dynamic routing, dynamic routes will precede the `RequestOption` object parameter.
275
+
276
+ ```ts title="api/lambda/[sku]/[id]/item.ts"
277
+ export async function post(
278
+ sku: string,
279
+ id: string,
280
+ {
281
+ data,
282
+ query,
283
+ }: RequestOption<Record<string, string>, Record<string, string>>,
284
+ ) {
285
+ // do somethings
286
+ }
287
+ ```
288
+
289
+ Pass the corresponding parameters when invoking the function according to its definition:
290
+
291
+ ```ts title="src/routes/page.tsx"
292
+ import { post } from '@api/[sku]/[id]/item';
293
+
294
+ export default () => {
295
+ const addSku = () => {
296
+ post('0001' /* sku */, '1234' /* id */, {
297
+ query: {
298
+ /* ... */
299
+ },
300
+ data: {
301
+ /* ... */
302
+ },
303
+ });
304
+ };
305
+
306
+ return <div onClick={addSku}>Add SKU</div>;
307
+ };
308
+ ```
309
+
310
+ ## Extend BFF Function
311
+
312
+ The standard BFF function writing method may not always meet your needs. For example, complex TS type requirements in business scenarios. Modern.js provides a more powerful BFF function writing method.
313
+
314
+ For more details, please refer to - [Creating Extensible BFF Functions](/guides/advanced-features/bff/operators.md).
315
+
316
+ ## Code Sharing
317
+
318
+ Besides the BFF functions in the `api/` directory, which can be referenced in the `src/` directory through an integrated calling method, the `src/` and `api/` directories cannot directly reference each other's code by default. To achieve code sharing, a [`shared`](/apis/app/hooks/shared.md) directory can be created at the root of the project for both `src/` and `api/` to use commonly.