@modern-js/main-doc 3.9.2 → 3.10.0

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 (203) hide show
  1. package/docs/en/apis/app/hooks/api/lambda.mdx +2 -1
  2. package/docs/en/apis/app/hooks/config/html.mdx +1 -0
  3. package/docs/en/apis/app/hooks/config/mock.mdx +1 -0
  4. package/docs/en/apis/app/hooks/config/public.mdx +1 -0
  5. package/docs/en/apis/app/hooks/config/upload.mdx +2 -3
  6. package/docs/en/apis/app/hooks/modern-config.mdx +1 -0
  7. package/docs/en/apis/app/hooks/shared.mdx +1 -0
  8. package/docs/en/apis/app/hooks/src/modern.runtime.mdx +1 -0
  9. package/docs/en/apis/app/hooks/src/routes.mdx +1 -0
  10. package/docs/en/apis/app/hooks/src/server.mdx +2 -1
  11. package/docs/en/apis/app/runtime/bff/use-hono-context.mdx +1 -0
  12. package/docs/en/apis/app/runtime/core/create-root.mdx +4 -1
  13. package/docs/en/apis/app/runtime/core/render.mdx +6 -2
  14. package/docs/en/apis/app/runtime/core/runtime-context.mdx +17 -17
  15. package/docs/en/apis/app/runtime/router/router.mdx +9 -6
  16. package/docs/en/apis/app/runtime/ssr/no-ssr.mdx +1 -0
  17. package/docs/en/apis/app/runtime/utility/head.mdx +1 -0
  18. package/docs/en/apis/app/runtime/utility/loadable.mdx +1 -0
  19. package/docs/en/community/blog/v3-release-note.mdx +36 -27
  20. package/docs/en/community/contributing-guide.mdx +15 -33
  21. package/docs/en/components/default-browserslist.mdx +0 -1
  22. package/docs/en/components/deploy-command.mdx +1 -1
  23. package/docs/en/components/deploy.mdx +1 -1
  24. package/docs/en/components/entry-scan-logic.mdx +1 -1
  25. package/docs/en/components/init-app.mdx +9 -3
  26. package/docs/en/components/international/custom-instance-code.mdx +0 -1
  27. package/docs/en/components/micro-runtime-config.mdx +12 -9
  28. package/docs/en/components/nodeVersion.mdx +2 -2
  29. package/docs/en/components/rsc-deploy-tip.mdx +0 -1
  30. package/docs/en/components/ssr-monitor.mdx +1 -1
  31. package/docs/en/configure/app/bff/cross-project.mdx +2 -2
  32. package/docs/en/configure/app/bff/prefix.mdx +1 -1
  33. package/docs/en/configure/app/dev/lazy-compilation.mdx +17 -1
  34. package/docs/en/configure/app/dev/start-url.mdx +0 -1
  35. package/docs/en/configure/app/output/css-modules.mdx +1 -5
  36. package/docs/en/configure/app/output/disable-svgr.mdx +4 -0
  37. package/docs/en/configure/app/output/dist-path.mdx +0 -1
  38. package/docs/en/configure/app/output/inline-scripts.mdx +1 -2
  39. package/docs/en/configure/app/output/inline-styles.mdx +1 -2
  40. package/docs/en/configure/app/output/split-route-chunks.mdx +1 -1
  41. package/docs/en/configure/app/output/ssg.mdx +1 -1
  42. package/docs/en/configure/app/output/ssgByEntries.mdx +1 -0
  43. package/docs/en/configure/app/output/svg-default-export.mdx +4 -0
  44. package/docs/en/configure/app/performance/chunk-split.mdx +1 -4
  45. package/docs/en/configure/app/runtime/plugins.mdx +6 -4
  46. package/docs/en/configure/app/server/rsc.mdx +1 -1
  47. package/docs/en/configure/app/server/ssr.mdx +7 -8
  48. package/docs/en/configure/app/server/tsconfig-path.mdx +2 -2
  49. package/docs/en/configure/app/tools/less.mdx +94 -19
  50. package/docs/en/configure/app/tools/sass.mdx +87 -18
  51. package/docs/en/configure/app/tools/svgr.mdx +93 -0
  52. package/docs/en/configure/app/usage.mdx +1 -5
  53. package/docs/en/guides/advanced-features/bff/cross-project.mdx +5 -4
  54. package/docs/en/guides/advanced-features/compatibility.mdx +0 -1
  55. package/docs/en/guides/advanced-features/international/advanced.mdx +1 -1
  56. package/docs/en/guides/advanced-features/international/api.mdx +34 -28
  57. package/docs/en/guides/advanced-features/international/best-practices.mdx +15 -15
  58. package/docs/en/guides/advanced-features/international/configuration.mdx +37 -37
  59. package/docs/en/guides/advanced-features/international/locale-detection.mdx +37 -28
  60. package/docs/en/guides/advanced-features/international/resource-loading.mdx +19 -17
  61. package/docs/en/guides/advanced-features/international/routing.mdx +8 -6
  62. package/docs/en/guides/advanced-features/international.mdx +8 -8
  63. package/docs/en/guides/advanced-features/server-monitor/logger.mdx +5 -5
  64. package/docs/en/guides/advanced-features/server-monitor/metrics.mdx +8 -8
  65. package/docs/en/guides/advanced-features/server-monitor/monitors.mdx +1 -3
  66. package/docs/en/guides/advanced-features/source-build.mdx +1 -1
  67. package/docs/en/guides/advanced-features/web-server.mdx +3 -3
  68. package/docs/en/guides/basic-features/data/data-fetch.mdx +1 -3
  69. package/docs/en/guides/basic-features/data/data-write.mdx +24 -28
  70. package/docs/en/guides/basic-features/debug/mock.mdx +2 -2
  71. package/docs/en/guides/basic-features/debug/using-storybook.mdx +5 -6
  72. package/docs/en/guides/basic-features/html.mdx +2 -3
  73. package/docs/en/guides/basic-features/output-files.mdx +1 -1
  74. package/docs/en/guides/basic-features/render/overview.mdx +12 -12
  75. package/docs/en/guides/basic-features/render/rsc.mdx +16 -9
  76. package/docs/en/guides/basic-features/render/ssr-cache.mdx +5 -5
  77. package/docs/en/guides/basic-features/render/ssr.mdx +8 -12
  78. package/docs/en/guides/basic-features/render/streaming-ssr.mdx +2 -1
  79. package/docs/en/guides/basic-features/routes/config-routes.mdx +60 -59
  80. package/docs/en/guides/basic-features/static-assets/svg-assets.mdx +29 -17
  81. package/docs/en/guides/basic-features/testing/playwright.mdx +14 -8
  82. package/docs/en/guides/basic-features/testing/rstest.mdx +6 -4
  83. package/docs/en/guides/get-started/ai-coding-agents.mdx +6 -6
  84. package/docs/en/guides/get-started/introduction.mdx +0 -1
  85. package/docs/en/guides/topic-detail/module-federation/deploy.mdx +2 -2
  86. package/docs/en/guides/topic-detail/module-federation/introduce.mdx +0 -1
  87. package/docs/en/guides/upgrade/config.mdx +12 -0
  88. package/docs/en/guides/upgrade/other.mdx +4 -4
  89. package/docs/en/guides/upgrade/tailwindcss.mdx +0 -1
  90. package/docs/en/guides/upgrade/web-server.md +34 -17
  91. package/docs/en/index.md +1 -0
  92. package/docs/en/plugin/cli-plugins/api.mdx +23 -23
  93. package/docs/en/plugin/cli-plugins/life-cycle.mdx +2 -0
  94. package/docs/en/plugin/introduction.mdx +6 -6
  95. package/docs/en/plugin/official/cli-plugins/plugin-bff.mdx +1 -1
  96. package/docs/en/plugin/official/cli-plugins/plugin-ssg.mdx +1 -1
  97. package/docs/en/plugin/plugin-system.mdx +19 -26
  98. package/docs/en/plugin/runtime-plugins/life-cycle.mdx +2 -0
  99. package/docs/en/plugin/server-plugins/api.mdx +11 -14
  100. package/docs/en/plugin/server-plugins/life-cycle.mdx +2 -0
  101. package/docs/zh/apis/app/hooks/api/lambda.mdx +1 -1
  102. package/docs/zh/apis/app/hooks/config/html.mdx +1 -0
  103. package/docs/zh/apis/app/hooks/config/mock.mdx +1 -0
  104. package/docs/zh/apis/app/hooks/config/public.mdx +1 -0
  105. package/docs/zh/apis/app/hooks/config/upload.mdx +2 -3
  106. package/docs/zh/apis/app/hooks/modern-config.mdx +1 -0
  107. package/docs/zh/apis/app/hooks/shared.mdx +1 -0
  108. package/docs/zh/apis/app/hooks/src/modern.runtime.mdx +1 -0
  109. package/docs/zh/apis/app/hooks/src/routes.mdx +1 -0
  110. package/docs/zh/apis/app/hooks/src/server.mdx +2 -1
  111. package/docs/zh/apis/app/runtime/bff/use-hono-context.mdx +1 -1
  112. package/docs/zh/apis/app/runtime/core/create-root.mdx +4 -1
  113. package/docs/zh/apis/app/runtime/core/render.mdx +6 -3
  114. package/docs/zh/apis/app/runtime/core/runtime-context.mdx +17 -17
  115. package/docs/zh/apis/app/runtime/router/router.mdx +10 -6
  116. package/docs/zh/apis/app/runtime/ssr/no-ssr.mdx +1 -0
  117. package/docs/zh/apis/app/runtime/utility/head.mdx +1 -0
  118. package/docs/zh/apis/app/runtime/utility/loadable.mdx +1 -0
  119. package/docs/zh/community/blog/v3-release-note.mdx +38 -29
  120. package/docs/zh/community/contributing-guide.mdx +16 -34
  121. package/docs/zh/components/default-browserslist.mdx +0 -1
  122. package/docs/zh/components/deploy-command.mdx +1 -1
  123. package/docs/zh/components/deploy.mdx +1 -1
  124. package/docs/zh/components/entry-scan-logic.mdx +1 -1
  125. package/docs/zh/components/init-app.mdx +9 -3
  126. package/docs/zh/components/international/custom-instance-code.mdx +0 -1
  127. package/docs/zh/components/international/install-command.mdx +0 -1
  128. package/docs/zh/components/micro-runtime-config.mdx +12 -9
  129. package/docs/zh/components/nodeVersion.mdx +2 -2
  130. package/docs/zh/components/rsc-deploy-tip.mdx +0 -1
  131. package/docs/zh/components/ssr-monitor.mdx +1 -1
  132. package/docs/zh/configure/app/bff/cross-project.mdx +2 -2
  133. package/docs/zh/configure/app/bff/prefix.mdx +1 -1
  134. package/docs/zh/configure/app/dev/lazy-compilation.mdx +17 -1
  135. package/docs/zh/configure/app/html/crossorigin.mdx +0 -1
  136. package/docs/zh/configure/app/html/favicon.mdx +0 -1
  137. package/docs/zh/configure/app/output/convert-to-rem.mdx +0 -1
  138. package/docs/zh/configure/app/output/css-modules.mdx +1 -5
  139. package/docs/zh/configure/app/output/disable-svgr.mdx +4 -0
  140. package/docs/zh/configure/app/output/inline-scripts.mdx +1 -2
  141. package/docs/zh/configure/app/output/inline-styles.mdx +1 -2
  142. package/docs/zh/configure/app/output/source-map.mdx +0 -2
  143. package/docs/zh/configure/app/output/split-route-chunks.mdx +1 -1
  144. package/docs/zh/configure/app/output/ssg.mdx +1 -0
  145. package/docs/zh/configure/app/output/ssgByEntries.mdx +1 -1
  146. package/docs/zh/configure/app/output/svg-default-export.mdx +4 -0
  147. package/docs/zh/configure/app/performance/chunk-split.mdx +1 -4
  148. package/docs/zh/configure/app/resolve/dedupe.mdx +0 -1
  149. package/docs/zh/configure/app/runtime/plugins.mdx +6 -4
  150. package/docs/zh/configure/app/server/rsc.mdx +1 -1
  151. package/docs/zh/configure/app/server/ssr.mdx +6 -7
  152. package/docs/zh/configure/app/server/tsconfig-path.mdx +2 -2
  153. package/docs/zh/configure/app/tools/less.mdx +93 -19
  154. package/docs/zh/configure/app/tools/sass.mdx +87 -16
  155. package/docs/zh/configure/app/tools/svgr.mdx +93 -0
  156. package/docs/zh/configure/app/usage.mdx +1 -5
  157. package/docs/zh/guides/advanced-features/bff.mdx +1 -0
  158. package/docs/zh/guides/advanced-features/international/advanced.mdx +1 -1
  159. package/docs/zh/guides/advanced-features/international/api.mdx +28 -27
  160. package/docs/zh/guides/advanced-features/international/best-practices.mdx +15 -15
  161. package/docs/zh/guides/advanced-features/international/configuration.mdx +38 -36
  162. package/docs/zh/guides/advanced-features/international/locale-detection.mdx +37 -28
  163. package/docs/zh/guides/advanced-features/international/resource-loading.mdx +20 -16
  164. package/docs/zh/guides/advanced-features/international/routing.mdx +6 -4
  165. package/docs/zh/guides/advanced-features/international.mdx +9 -9
  166. package/docs/zh/guides/advanced-features/server-monitor/logger.mdx +4 -6
  167. package/docs/zh/guides/advanced-features/server-monitor/metrics.mdx +9 -10
  168. package/docs/zh/guides/advanced-features/source-build.mdx +1 -1
  169. package/docs/zh/guides/advanced-features/web-server.mdx +3 -3
  170. package/docs/zh/guides/basic-features/data/data-fetch.mdx +1 -3
  171. package/docs/zh/guides/basic-features/data/data-write.mdx +25 -31
  172. package/docs/zh/guides/basic-features/debug/mock.mdx +2 -2
  173. package/docs/zh/guides/basic-features/debug/using-storybook.mdx +5 -5
  174. package/docs/zh/guides/basic-features/env-vars.mdx +0 -1
  175. package/docs/zh/guides/basic-features/html.mdx +2 -3
  176. package/docs/zh/guides/basic-features/render/overview.mdx +12 -13
  177. package/docs/zh/guides/basic-features/render/rsc.mdx +16 -9
  178. package/docs/zh/guides/basic-features/render/ssr.mdx +8 -17
  179. package/docs/zh/guides/basic-features/routes/config-routes.mdx +61 -59
  180. package/docs/zh/guides/basic-features/static-assets/svg-assets.mdx +29 -17
  181. package/docs/zh/guides/basic-features/testing/playwright.mdx +15 -10
  182. package/docs/zh/guides/basic-features/testing/rstest.mdx +6 -4
  183. package/docs/zh/guides/get-started/ai-coding-agents.mdx +7 -7
  184. package/docs/zh/guides/topic-detail/module-federation/deploy.mdx +2 -2
  185. package/docs/zh/guides/upgrade/config.mdx +12 -0
  186. package/docs/zh/guides/upgrade/other.md +4 -11
  187. package/docs/zh/guides/upgrade/overview.mdx +1 -4
  188. package/docs/zh/guides/upgrade/tailwindcss.mdx +0 -1
  189. package/docs/zh/guides/upgrade/web-server.md +34 -19
  190. package/docs/zh/index.md +1 -0
  191. package/docs/zh/plugin/cli-plugins/api.mdx +24 -24
  192. package/docs/zh/plugin/cli-plugins/life-cycle.mdx +2 -0
  193. package/docs/zh/plugin/introduction.mdx +6 -6
  194. package/docs/zh/plugin/official/cli-plugins/plugin-bff.mdx +1 -1
  195. package/docs/zh/plugin/official/cli-plugins/plugin-ssg.mdx +1 -1
  196. package/docs/zh/plugin/plugin-system.mdx +19 -26
  197. package/docs/zh/plugin/runtime-plugins/life-cycle.mdx +2 -0
  198. package/docs/zh/plugin/server-plugins/api.mdx +11 -14
  199. package/docs/zh/plugin/server-plugins/life-cycle.mdx +2 -0
  200. package/package.json +11 -13
  201. package/{rspress.config.ts → rstack.config.mts} +7 -10
  202. package/src/components/Footer/styles.module.scss +1 -1
  203. package/src/components/SolutionCards/index.module.scss +3 -1
@@ -2,7 +2,7 @@
2
2
  sidebar_position: 15
3
3
  ---
4
4
 
5
- import { PackageManagerTabs } from '@theme'
5
+ import { PackageManagerTabs } from '@theme';
6
6
 
7
7
  # 使用 Storybook
8
8
 
@@ -33,14 +33,14 @@ Modern.js 基于此工具实现了 `storybook-addon-modernjs`,该插件会加
33
33
  ## 配置 `.storybook/main.ts`
34
34
 
35
35
  ```ts
36
- import type { StorybookConfig } from 'storybook-react-rsbuild'
36
+ import type { StorybookConfig } from 'storybook-react-rsbuild';
37
37
 
38
38
  const config: StorybookConfig = {
39
39
  stories: ['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
40
40
  addons: ['storybook-addon-modernjs'],
41
41
  framework: 'storybook-react-rsbuild',
42
- }
43
- export default config
42
+ };
43
+ export default config;
44
44
  ```
45
45
 
46
46
  ## Storybook 中进行 BFF 一体化调用
@@ -55,7 +55,7 @@ export default config
55
55
  {
56
56
  "scripts": {
57
57
  "dev:api": "modern dev --api-only",
58
- "storybook": "BFF_PROXY=1 storybook dev -p 6006 --no-open",
58
+ "storybook": "BFF_PROXY=1 storybook dev -p 6006 --no-open"
59
59
  }
60
60
  }
61
61
  ```
@@ -72,7 +72,6 @@ function App() {
72
72
 
73
73
  :::
74
74
 
75
-
76
75
  ## 自定义环境变量
77
76
 
78
77
  环境变量支持通过 `shell` 和 `.env` 文件两种方式指定。
@@ -20,9 +20,8 @@ Modern.js 约定,在 `src/` 或入口目录下,可以创建 `Document.tsx`
20
20
  ├── entry-a
21
21
  │ ├── Document.tsx
22
22
  │ └── routes
23
- ├── entry-b
24
- │ └── routes
25
- └── modern-app-env.d.ts
23
+ └── entry-b
24
+ └── routes
26
25
  ```
27
26
 
28
27
  `entry-a` 会优先使用当前入口下的 `Document.tsx` 文件。如果当前入口没有 `Document.tsx` 文件,例如 `entry-b`,则会查找根目录下的 `Document.tsx` 文件。
@@ -8,21 +8,21 @@ Modern.js 支持多种渲染模式,不同的渲染模式适用于不同的场
8
8
 
9
9
  ## 渲染模式速览
10
10
 
11
- | 渲染模式 | 特点 | 适用场景 |
12
- |---------|------|---------|
13
- | **CSR** | 在浏览器端执行 JavaScript 渲染页面 | 交互性强、对 SEO 要求不高的应用 |
14
- | **SSR** | 在服务端预先渲染完整 HTML 页面 | 对首屏性能和 SEO 要求高的网站 |
15
- | **Streaming SSR** | 边渲染边返回,更快显示初始 UI | 需要更快首屏感知速度的应用(**SSR 默认模式**) |
16
- | **RSC** | 组件在服务端渲染,减少客户端 JS 体积;数据与组件逻辑高内聚,减少状态传递 | 追求极致性能、需要减少客户端代码的项目 |
17
- | **SSG** | 构建时生成静态页面,可被 CDN 缓存 | 内容相对静态的网站,如博客、文档站点 |
11
+ | 渲染模式 | 特点 | 适用场景 |
12
+ | ----------------- | ------------------------------------------------------------------------ | ---------------------------------------------- |
13
+ | **CSR** | 在浏览器端执行 JavaScript 渲染页面 | 交互性强、对 SEO 要求不高的应用 |
14
+ | **SSR** | 在服务端预先渲染完整 HTML 页面 | 对首屏性能和 SEO 要求高的网站 |
15
+ | **Streaming SSR** | 边渲染边返回,更快显示初始 UI | 需要更快首屏感知速度的应用(**SSR 默认模式**) |
16
+ | **RSC** | 组件在服务端渲染,减少客户端 JS 体积;数据与组件逻辑高内聚,减少状态传递 | 追求极致性能、需要减少客户端代码的项目 |
17
+ | **SSG** | 构建时生成静态页面,可被 CDN 缓存 | 内容相对静态的网站,如博客、文档站点 |
18
18
 
19
19
  ## 性能对比
20
20
 
21
- | 渲染技术 | 核心优势 | 主要瓶颈 |
22
- |---------|---------|---------|
23
- | **SSR** | 服务端预渲染,有利于 SEO | 需等待所有数据加载完成才能响应 |
24
- | **Streaming SSR** | 边渲染边返回,更快首屏 | JS 体积仍然较大 |
25
- | **Streaming SSR + RSC** | 减少客户端 JS 体积 | - |
21
+ | 渲染技术 | 核心优势 | 主要瓶颈 |
22
+ | ----------------------- | ------------------------ | ------------------------------ |
23
+ | **SSR** | 服务端预渲染,有利于 SEO | 需等待所有数据加载完成才能响应 |
24
+ | **Streaming SSR** | 边渲染边返回,更快首屏 | JS 体积仍然较大 |
25
+ | **Streaming SSR + RSC** | 减少客户端 JS 体积 | - |
26
26
 
27
27
  ## 如何选择
28
28
 
@@ -42,7 +42,6 @@ Modern.js 支持多种渲染模式组合使用:
42
42
  - **SSG + SSR**:部分页面静态,部分页面动态
43
43
  - **CSR + RSC**:客户端渲染 + 部分 Server Component
44
44
 
45
-
46
45
  ## 相关文档
47
46
 
48
47
  - [服务端渲染(SSR)](/guides/basic-features/render/ssr)
@@ -239,12 +239,12 @@ export default function DashboardPage() {
239
239
 
240
240
  ### 两种数据获取方式对比
241
241
 
242
- | 特性 | Server Component 中获取 | Data Loader 中获取 |
243
- | --- | --- | --- |
244
- | 避免请求瀑布 | 需要手动优化 | ✅ 自动并行执行 |
245
- | 组件内聚性 | ✅ 数据和 UI 在同一处 | 数据逻辑分离到单独文件 |
246
- | 维护性 | ✅ 更易理解和维护 | 需要维护额外文件 |
247
- | 类型安全 | ✅ 天然类型推断 | 需要手动管理类型 |
242
+ | 特性 | Server Component 中获取 | Data Loader 中获取 |
243
+ | ------------ | ----------------------- | ---------------------- |
244
+ | 避免请求瀑布 | 需要手动优化 | ✅ 自动并行执行 |
245
+ | 组件内聚性 | ✅ 数据和 UI 在同一处 | 数据逻辑分离到单独文件 |
246
+ | 维护性 | ✅ 更易理解和维护 | 需要维护额外文件 |
247
+ | 类型安全 | ✅ 天然类型推断 | 需要手动管理类型 |
248
248
 
249
249
  **一般情况下,我们推荐在 Server Component 中获取数据**,因为在服务端瀑布请求对性能的影响较小,这种方式使组件更加内聚,数据获取逻辑和 UI 渲染在同一处,更易于理解和维护。但如果你的页面有多个独立的数据源,且希望完全避免请求瀑布问题,Data Loader 的并行执行特性会更有优势。
250
250
 
@@ -268,7 +268,11 @@ export default function DashboardPage() {
268
268
 
269
269
  ```tsx title="routes/user/page.tsx"
270
270
  // Server Component 通过 props 接收 loaderData
271
- export default function UserPage({ loaderData }: { loaderData: { name: string } }) {
271
+ export default function UserPage({
272
+ loaderData,
273
+ }: {
274
+ loaderData: { name: string };
275
+ }) {
272
276
  return <div>Welcome, {loaderData.name}</div>;
273
277
  }
274
278
  ```
@@ -276,7 +280,11 @@ export default function UserPage({ loaderData }: { loaderData: { name: string }
276
280
  ```tsx title="routes/user/page.tsx"
277
281
  'use client';
278
282
  // Client Component 同样可以通过 props 接收 loaderData
279
- export default function UserPage({ loaderData }: { loaderData: { name: string } }) {
283
+ export default function UserPage({
284
+ loaderData,
285
+ }: {
286
+ loaderData: { name: string };
287
+ }) {
280
288
  return <div>Welcome, {loaderData.name}</div>;
281
289
  }
282
290
  ```
@@ -600,7 +608,6 @@ export default function ProfilePage() {
600
608
 
601
609
  import DeployTip from '@site-docs/components/rsc-deploy-tip';
602
610
 
603
-
604
611
  <DeployTip />
605
612
 
606
613
  ## 常见问题
@@ -74,10 +74,8 @@ export default () => {
74
74
  };
75
75
  ```
76
76
 
77
-
78
77
  ### 使用 Client Loader
79
78
 
80
-
81
79
  默认情况下,在 SSR 应用中,`loader` 函数只会在服务端执行。但有些场景下,开发者可能期望在浏览器端发送的请求不经过 SSR 服务,直接请求数据源,例如:
82
80
 
83
81
  1. 在浏览器端希望减少网络消耗,直接请求数据源。
@@ -96,12 +94,10 @@ export async function loader({ params }) {
96
94
  const data = await res.json();
97
95
  return {
98
96
  message: data.message,
99
- }
97
+ };
100
98
  }
101
99
  ```
102
100
 
103
-
104
-
105
101
  ## SSR 降级
106
102
 
107
103
  在 Modern.js 中,如果应用在 SSR 过程中出现异常,Modern.js 会自动降级到 CSR 模式,并在 CSR 重新发起数据请求,保证页面能够正常展示。SSR 降级的原因主要分为两种:
@@ -133,11 +129,7 @@ const Page = () => {
133
129
  const undefinedVars = data.unDefined;
134
130
  const definedVars = data.defined;
135
131
 
136
- return (
137
- <div>
138
- {isNode ? undefinedVars.msg : definedVars.msg}
139
- </div>
140
- );
132
+ return <div>{isNode ? undefinedVars.msg : definedVars.msg}</div>;
141
133
  };
142
134
 
143
135
  export default Page;
@@ -222,7 +214,7 @@ document.addEventListener('load', () => {
222
214
  console.log('document load');
223
215
  });
224
216
 
225
- export const doSomething = () => {}
217
+ export const doSomething = () => {};
226
218
  ```
227
219
 
228
220
  如果直接引用到组件中,会造成 SSR 加载报错,即使你已经使用环境变量进行判断,但仍然无法移除依赖中副作用的执行。
@@ -234,8 +226,8 @@ export const Page = () => {
234
226
  if (process.env.MODERN_TARGET === 'browser') {
235
227
  doSomething();
236
228
  }
237
- return <div>Hello World</div>
238
- }
229
+ return <div>Hello World</div>;
230
+ };
239
231
  ```
240
232
 
241
233
  Modern.js 也支持通过 `.server.` 后缀的文件来区分 SSR Bundle 和 CSR Bundle 产物的打包文件。可以创建同名的 `.ts` 和 `.server.ts` 文件做一层代理:
@@ -251,12 +243,12 @@ export const doSomething: any = () => {};
251
243
  在文件中直接引入 `./a`,此时 SSR 打包下会优先使用 `.server.ts` 后缀的文件,CSR 打包下会使用 `.ts` 后缀的文件。
252
244
 
253
245
  ```tsx title="routes/page.tsx"
254
- import { doSomething } from './a'
246
+ import { doSomething } from './a';
255
247
 
256
248
  export const Page = () => {
257
249
  doSomething();
258
- return <div>Hello World</div>
259
- }
250
+ return <div>Hello World</div>;
251
+ };
260
252
  ```
261
253
 
262
254
  ## 常见问题
@@ -331,4 +323,3 @@ export default function Test() {
331
323
  在浏览器端,这段代码不会造成任何问题,但是在 SSR 时,Middleware 实例会一直无法被销毁。每次渲染组件,调用 `epicMiddleware.run(rootEpic)` 时,都会在内部添加新的事件绑定,导致整个对象不断变大,最终对应用性能造成影响。
332
324
 
333
325
  CSR 中这类问题不易被发觉,因此从 CSR 切换到 SSR 时,如果不确定应用是否存在这类隐患,可以对应用进行压测。
334
-
@@ -6,7 +6,6 @@ sidebar_position: 3
6
6
 
7
7
  默认情况下,Modern.js 推荐使用 [约定式路由](./routes.mdx) 作为路由定义的方式。同时,Modern.js 也提供了一个配置式路由的能力,其可以和约定式路由一起使用,或两者分别单独使用。
8
8
 
9
-
10
9
  ## 何时使用配置式路由
11
10
 
12
11
  配置式路由在以下场景中特别有用:
@@ -22,27 +21,26 @@ sidebar_position: 3
22
21
  在 `src` 或每个入口目录下,你可以定义一个 `modern.routes.ts` 文件,通过该文件,你可以对路由进行配置:
23
22
 
24
23
  ```ts
25
- import { defineRoutes } from '@modern-js/runtime/config-routes'
24
+ import { defineRoutes } from '@modern-js/runtime/config-routes';
26
25
 
27
26
  export default defineRoutes(({ route, layout, page, $ }, fileRoutes) => {
28
- return [
29
- route("home.tsx", "/"),
30
- ]
31
- })
27
+ return [route('home.tsx', '/')];
28
+ });
32
29
  ```
33
30
 
34
31
  ### 函数签名说明
35
32
 
36
33
  `defineRoutes` 接受一个回调函数,该回调函数有两个参数:
34
+
37
35
  1. `routeFunctions`:包含 `route`、`layout`、`page`、`$` 函数的对象
38
36
  2. `fileRoutes`:约定式路由生成的路由配置数组
39
37
 
40
38
  路由函数的基本签名:
39
+
41
40
  - 第一个参数:相对于 `modern.routes.ts` 的文件路径
42
41
  - 第二个参数:路由路径(可选,必须是字符串)
43
42
  - 第三个参数:子路由数组(可选)
44
43
 
45
-
46
44
  ## 路由函数
47
45
 
48
46
  Modern.js 提供了四个主要的路由配置函数:
@@ -50,6 +48,7 @@ Modern.js 提供了四个主要的路由配置函数:
50
48
  :::tip 路径说明
51
49
 
52
50
  所有路由函数的第一个参数(路径)都是**相对路径**,会与父级路径拼接生成最终的路由路径:
51
+
53
52
  - **根路径**:`"/"` 或 "" 表示当前层级的根路径
54
53
  - **相对路径**:子路由的路径会相对于父级路径进行拼接
55
54
  - **动态路径**:使用 `:param` 语法表示动态参数
@@ -57,7 +56,6 @@ Modern.js 提供了四个主要的路由配置函数:
57
56
 
58
57
  :::
59
58
 
60
-
61
59
  :::info
62
60
 
63
61
  - `route`、`layout`、`page`、`$` 等函数的第一个参数(组件文件路径)必须指向当前项目中的真实文件,暂不支持 `node_modules` 及 Monorepo 下其他仓库中的文件
@@ -73,27 +71,28 @@ Modern.js 提供了四个主要的路由配置函数:
73
71
  export default defineRoutes(({ route }, fileRoutes) => {
74
72
  return [
75
73
  // 无子路由时,自动生成页面路由
76
- route("home.tsx", "/"),
77
- route("about.tsx", "about"),
74
+ route('home.tsx', '/'),
75
+ route('about.tsx', 'about'),
78
76
 
79
77
  // 有子路由时,自动生成布局路由
80
78
  // dashboard/layout.tsx 需要包含 <Outlet> 来渲染子路由
81
- route("dashboard/layout.tsx", "dashboard", [
82
- route("dashboard/overview.tsx", "overview"), // 生成路径:/dashboard/overview
83
- route("dashboard/settings.tsx", "settings"), // 生成路径:/dashboard/settings
79
+ route('dashboard/layout.tsx', 'dashboard', [
80
+ route('dashboard/overview.tsx', 'overview'), // 生成路径:/dashboard/overview
81
+ route('dashboard/settings.tsx', 'settings'), // 生成路径:/dashboard/settings
84
82
  ]),
85
83
 
86
84
  // 动态路由
87
- route("products/detail.tsx", "products/:id"),
85
+ route('products/detail.tsx', 'products/:id'),
88
86
 
89
87
  // 多路径指向同一组件
90
- route("user/profile.tsx", "user"),
91
- route("user/profile.tsx", "profile"),
92
- ]
93
- })
88
+ route('user/profile.tsx', 'user'),
89
+ route('user/profile.tsx', 'profile'),
90
+ ];
91
+ });
94
92
  ```
95
93
 
96
94
  **使用场景**:
95
+
97
96
  - 快速配置路由,无需明确指定是页面还是布局
98
97
  - 简化路由配置的复杂度
99
98
 
@@ -105,15 +104,16 @@ export default defineRoutes(({ route }, fileRoutes) => {
105
104
  export default defineRoutes(({ layout, page }, fileRoutes) => {
106
105
  return [
107
106
  // 生成布局路由,路径为 "/auth",必须包含子路由
108
- layout("auth/layout.tsx", "auth", [
109
- page("auth/login/page.tsx", "login"), // 生成路径:/auth/login
110
- page("auth/register/page.tsx", "register"), // 生成路径:/auth/register
107
+ layout('auth/layout.tsx', 'auth', [
108
+ page('auth/login/page.tsx', 'login'), // 生成路径:/auth/login
109
+ page('auth/register/page.tsx', 'register'), // 生成路径:/auth/register
111
110
  ]),
112
- ]
113
- })
111
+ ];
112
+ });
114
113
  ```
115
114
 
116
115
  **使用场景**:
116
+
117
117
  - 需要明确指定某个组件为布局组件
118
118
  - 为多个页面提供共同的布局结构
119
119
  - 需要在多个路由间共享导航、侧边栏等UI组件
@@ -125,15 +125,16 @@ export default defineRoutes(({ layout, page }, fileRoutes) => {
125
125
  ```ts
126
126
  export default defineRoutes(({ layout, page }, fileRoutes) => {
127
127
  return [
128
- layout("dashboard/layout.tsx", "dashboard", [
129
- page("dashboard/overview.tsx", "overview"), // 生成路径:/dashboard/overview
130
- page("dashboard/settings.tsx", "settings"), // 生成路径:/dashboard/settings
128
+ layout('dashboard/layout.tsx', 'dashboard', [
129
+ page('dashboard/overview.tsx', 'overview'), // 生成路径:/dashboard/overview
130
+ page('dashboard/settings.tsx', 'settings'), // 生成路径:/dashboard/settings
131
131
  ]),
132
- ]
133
- })
132
+ ];
133
+ });
134
134
  ```
135
135
 
136
136
  **使用场景**:
137
+
137
138
  - 需要明确指定某个组件为页面组件
138
139
  - 确保组件不包含 `<Outlet>` 子组件渲染
139
140
  - 提供更清晰的语义表达
@@ -145,16 +146,17 @@ export default defineRoutes(({ layout, page }, fileRoutes) => {
145
146
  ```ts
146
147
  export default defineRoutes(({ layout, page, $ }, fileRoutes) => {
147
148
  return [
148
- layout("blog/layout.tsx", "blog", [
149
- page("blog/page.tsx", ""), // 生成路径:/blog
150
- page("blog/[id]/page.tsx", ":id"), // 生成路径:/blog/:id
151
- $("blog/$.tsx", "*"), // 通配路由,匹配 /blog 下的所有未匹配路径
149
+ layout('blog/layout.tsx', 'blog', [
150
+ page('blog/page.tsx', ''), // 生成路径:/blog
151
+ page('blog/[id]/page.tsx', ':id'), // 生成路径:/blog/:id
152
+ $('blog/$.tsx', '*'), // 通配路由,匹配 /blog 下的所有未匹配路径
152
153
  ]),
153
- ]
154
- })
154
+ ];
155
+ });
155
156
  ```
156
157
 
157
158
  **使用场景**:
159
+
158
160
  - 自定义 404 页面
159
161
  - 处理特定路径下的所有未匹配请求
160
162
 
@@ -170,11 +172,11 @@ export default defineRoutes(({ layout, page, $ }, fileRoutes) => {
170
172
  export default defineRoutes(({ page }, fileRoutes) => {
171
173
  return [
172
174
  // 使用 page 函数明确指定页面路由
173
- page("home.tsx", "/"),
174
- page("about.tsx", "about"),
175
- page("contact.tsx", "contact"),
176
- ]
177
- })
175
+ page('home.tsx', '/'),
176
+ page('about.tsx', 'about'),
177
+ page('contact.tsx', 'contact'),
178
+ ];
179
+ });
178
180
  ```
179
181
 
180
182
  ### 无路径路由
@@ -186,15 +188,16 @@ export default defineRoutes(({ layout, page }, fileRoutes) => {
186
188
  return [
187
189
  // 使用 layout 函数明确指定布局路由
188
190
  // auth/layout.tsx 需要包含 <Outlet> 来渲染子路由
189
- layout("auth/layout.tsx", [
190
- page("login/page.tsx", "login"),
191
- page("register/page.tsx", "register"),
191
+ layout('auth/layout.tsx', [
192
+ page('login/page.tsx', 'login'),
193
+ page('register/page.tsx', 'register'),
192
194
  ]),
193
- ]
194
- })
195
+ ];
196
+ });
195
197
  ```
196
198
 
197
199
  上述配置会生成:
200
+
198
201
  - `/login` → `auth/layout.tsx` + `login/page.tsx`
199
202
  - `/register` → `auth/layout.tsx` + `register/page.tsx`
200
203
 
@@ -203,11 +206,11 @@ export default defineRoutes(({ layout, page }, fileRoutes) => {
203
206
  ```ts
204
207
  export default defineRoutes(({ page }, fileRoutes) => {
205
208
  return [
206
- page("user.tsx", "user"),
207
- page("user.tsx", "profile"),
208
- page("user.tsx", "account"),
209
- ]
210
- })
209
+ page('user.tsx', 'user'),
210
+ page('user.tsx', 'profile'),
211
+ page('user.tsx', 'account'),
212
+ ];
213
+ });
211
214
  ```
212
215
 
213
216
  ### 动态路由
@@ -218,12 +221,12 @@ export default defineRoutes(({ page }, fileRoutes) => {
218
221
  export default defineRoutes(({ page }, fileRoutes) => {
219
222
  return [
220
223
  // 必需参数
221
- page("blog/detail.tsx", "blog/:id"),
224
+ page('blog/detail.tsx', 'blog/:id'),
222
225
 
223
226
  // 可选参数
224
- page("blog/index.tsx", "blog/:slug?"),
225
- ]
226
- })
227
+ page('blog/index.tsx', 'blog/:slug?'),
228
+ ];
229
+ });
227
230
  ```
228
231
 
229
232
  ## 路由相关文件自动查找
@@ -234,10 +237,10 @@ export default defineRoutes(({ page }, fileRoutes) => {
234
237
  // modern.routes.ts
235
238
  export default defineRoutes(({ route }, fileRoutes) => {
236
239
  return [
237
- route("pages/profile.tsx", "profile"),
238
- route("pages/user/detail.tsx", "user/:id"),
239
- ]
240
- })
240
+ route('pages/profile.tsx', 'profile'),
241
+ route('pages/user/detail.tsx', 'user/:id'),
242
+ ];
243
+ });
241
244
  ```
242
245
 
243
246
  Modern.js 会自动查找并加载:
@@ -259,7 +262,6 @@ Modern.js 会自动查找并加载:
259
262
 
260
263
  :::
261
264
 
262
-
263
265
  ## 路由合并
264
266
 
265
267
  配置式路由可以与约定式路由一起使用,你可以通过修改 `fileRoutes` 参数来实现路由的合并:
@@ -274,7 +276,6 @@ Modern.js 会自动查找并加载:
274
276
 
275
277
  :::
276
278
 
277
-
278
279
  ### 合并示例
279
280
 
280
281
  以下示例展示了配置式路由与约定式路由的合并方式:
@@ -312,6 +313,7 @@ export default defineRoutes(({ page }, fileRoutes) => {
312
313
  return fileRoutes;
313
314
  });
314
315
  ```
316
+
315
317
  ## 调试路由
316
318
 
317
319
  由于路由合并后的最终结构可能不够直观,Modern.js 提供了调试命令来帮助你查看完整路由信息:
@@ -42,16 +42,22 @@ export default () => <Logo />;
42
42
 
43
43
  ## 修改默认导出
44
44
 
45
- 你可以通过 [output.svgDefaultExport](/configure/app/output/svg-default-export) 配置项来修改 SVG 文件默认导出的内容,比如把默认导出的内容设置为 React 组件:
45
+ 你可以通过 [tools.svgr](/configure/app/tools/svgr) 的 `svgrOptions.exportType` 来修改 SVG 文件默认导出的内容,比如把默认导出的内容设置为 React 组件:
46
46
 
47
47
  ```ts
48
48
  export default {
49
- output: {
50
- svgDefaultExport: 'component',
49
+ tools: {
50
+ svgr: {
51
+ svgrOptions: {
52
+ exportType: 'default',
53
+ },
54
+ },
51
55
  },
52
56
  };
53
57
  ```
54
58
 
59
+ 旧的 [output.svgDefaultExport](/configure/app/output/svg-default-export) 配置项仍然生效,但已废弃。
60
+
55
61
  此时再使用默认导入,你会得到一个 React 组件,而不是 URL:
56
62
 
57
63
  ```tsx title="src/component/Logo.tsx"
@@ -80,12 +86,12 @@ export default () => <Logo />;
80
86
 
81
87
  默认情况下,在 JS 文件中引用 SVG 资源时,Modern.js 会调用 SVGR,将 SVG 图片转换为一个 React 组件。
82
88
 
83
- 如果你确定项目内的所有 SVG 资源都没有当成 React 组件使用时,可以通过将 [disableSvgr](/configure/app/output/disable-svgr) 设置为 true 来关闭此项转换,以提升构建性能。
89
+ 如果你确定项目内的所有 SVG 资源都没有当成 React 组件使用时,可以通过将 [tools.svgr](/configure/app/tools/svgr) 设置为 `false` 来关闭此项转换,以提升构建性能。
84
90
 
85
91
  ```js
86
92
  export default {
87
- output: {
88
- disableSvgr: true,
93
+ tools: {
94
+ svgr: false,
89
95
  },
90
96
  };
91
97
  ```
@@ -153,21 +159,27 @@ declare module '*.svg' {
153
159
  }
154
160
  ```
155
161
 
156
- 如果需要修改 SVGR 配置,可通过如下方式:
162
+ 如果需要修改 SVGR 配置,可通过 [tools.svgr](/configure/app/tools/svgr) 的 `svgrOptions` 设置。传入的 `svgoConfig.plugins` 会按插件名与默认配置深度合并,因此只需写出要改动的部分:
157
163
 
158
164
  ```js
159
165
  export default {
160
166
  tools: {
161
- bundlerChain: (chain, { CHAIN_ID }) => {
162
- chain.module
163
- .rule(CHAIN_ID.RULE.SVG)
164
- .oneOf(CHAIN_ID.ONE_OF.SVG)
165
- .use(CHAIN_ID.USE.SVGR)
166
- .tap(options => {
167
- // modify svgoConfig
168
- options.svgoConfig.plugins[0].params.overrides.removeUselessDefs = false;
169
- return options;
170
- });
167
+ svgr: {
168
+ svgrOptions: {
169
+ svgoConfig: {
170
+ plugins: [
171
+ {
172
+ name: 'preset-default',
173
+ params: {
174
+ overrides: {
175
+ // 在默认的 preset-default 之上追加一项 override
176
+ removeUselessDefs: false,
177
+ },
178
+ },
179
+ },
180
+ ],
181
+ },
182
+ },
171
183
  },
172
184
  },
173
185
  };
@@ -6,8 +6,13 @@ Playwright 是一个测试框架,它允许你使用单一的 API,自动的
6
6
 
7
7
  import { PackageManagerTabs } from '@theme';
8
8
 
9
- <PackageManagerTabs command={{ npm: "npm init playwright", yarn: "yarn create playwright", pnpm: "pnpm create playwright" }} />
10
-
9
+ <PackageManagerTabs
10
+ command={{
11
+ npm: 'npm init playwright',
12
+ yarn: 'yarn create playwright',
13
+ pnpm: 'pnpm create playwright',
14
+ }}
15
+ />
11
16
 
12
17
  上述命令会自动安装 Playwright 依赖,并通过一系列提示帮助你在项目中安装和配置,包括添加一个 `playwright.config.ts` 文件。
13
18
 
@@ -75,18 +80,18 @@ export default Index;
75
80
  接下来,添加测试用例,来保证你页面的链接能够正常工作。
76
81
 
77
82
  ```ts title="tests/example.spec.ts"
78
- import { test, expect } from '@playwright/test'
79
-
83
+ import { test, expect } from '@playwright/test';
84
+
80
85
  test('should navigate to the about page', async ({ page }) => {
81
86
  // Start from the index page (the baseURL is set via the webServer in the playwright.config.ts)
82
- await page.goto('http://localhost:8080/')
87
+ await page.goto('http://localhost:8080/');
83
88
  // Find an element with the text 'About' and click on it
84
- await page.click('text=About')
89
+ await page.click('text=About');
85
90
  // The new URL should be "/about" (baseURL is used there)
86
- await expect(page).toHaveURL('http://localhost:8080/about')
91
+ await expect(page).toHaveURL('http://localhost:8080/about');
87
92
  // The new page should contain an h1 with "About"
88
- await expect(page.locator('h1')).toContainText('About')
89
- })
93
+ await expect(page.locator('h1')).toContainText('About');
94
+ });
90
95
  ```
91
96
 
92
97
  ## 运行测试用例
@@ -109,4 +114,4 @@ Running 3 tests using 3 workers
109
114
  To open last HTML report run:
110
115
 
111
116
  npx playwright show-report
112
- ```
117
+ ```
@@ -84,9 +84,9 @@ test('Page', async () => {
84
84
  </Router>,
85
85
  );
86
86
 
87
- await expect.element(
88
- page.getByRole('heading', { level: 1, name: 'Home' }),
89
- ).toBeVisible();
87
+ await expect
88
+ .element(page.getByRole('heading', { level: 1, name: 'Home' }))
89
+ .toBeVisible();
90
90
  });
91
91
  ```
92
92
 
@@ -181,12 +181,14 @@ First install and use the migrate-to-rstest skill. If it is not installed, insta
181
181
  npx skills add rstackjs/agent-skills --skill migrate-to-rstest
182
182
 
183
183
  Follow the migrate-to-rstest skill instructions and the official Rstest migration guides:
184
+
184
185
  - Jest: https://rstest.rs/guide/migration/jest
185
186
  - Vitest: https://rstest.rs/guide/migration/vitest
186
187
 
187
188
  Modern.js-specific requirement:
189
+
188
190
  - Install and use @modern-js/adapter-rstest together with @rstest/core.
189
191
  - Create or update rstest.config.ts to import withModernConfig from @modern-js/adapter-rstest.
190
192
  - Reuse the Modern.js app configuration with extends: withModernConfig().
191
193
  - Do not replace this with a plain Rstest config unless the project explicitly does not need Modern.js config integration.`}
192
- />
194
+ />