@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.
- package/docs/en/apis/app/hooks/api/lambda.mdx +2 -1
- package/docs/en/apis/app/hooks/config/html.mdx +1 -0
- package/docs/en/apis/app/hooks/config/mock.mdx +1 -0
- package/docs/en/apis/app/hooks/config/public.mdx +1 -0
- package/docs/en/apis/app/hooks/config/upload.mdx +2 -3
- package/docs/en/apis/app/hooks/modern-config.mdx +1 -0
- package/docs/en/apis/app/hooks/shared.mdx +1 -0
- package/docs/en/apis/app/hooks/src/modern.runtime.mdx +1 -0
- package/docs/en/apis/app/hooks/src/routes.mdx +1 -0
- package/docs/en/apis/app/hooks/src/server.mdx +2 -1
- package/docs/en/apis/app/runtime/bff/use-hono-context.mdx +1 -0
- package/docs/en/apis/app/runtime/core/create-root.mdx +4 -1
- package/docs/en/apis/app/runtime/core/render.mdx +6 -2
- package/docs/en/apis/app/runtime/core/runtime-context.mdx +17 -17
- package/docs/en/apis/app/runtime/router/router.mdx +9 -6
- package/docs/en/apis/app/runtime/ssr/no-ssr.mdx +1 -0
- package/docs/en/apis/app/runtime/utility/head.mdx +1 -0
- package/docs/en/apis/app/runtime/utility/loadable.mdx +1 -0
- package/docs/en/community/blog/v3-release-note.mdx +36 -27
- package/docs/en/community/contributing-guide.mdx +15 -33
- package/docs/en/components/default-browserslist.mdx +0 -1
- package/docs/en/components/deploy-command.mdx +1 -1
- package/docs/en/components/deploy.mdx +1 -1
- package/docs/en/components/entry-scan-logic.mdx +1 -1
- package/docs/en/components/init-app.mdx +9 -3
- package/docs/en/components/international/custom-instance-code.mdx +0 -1
- package/docs/en/components/micro-runtime-config.mdx +12 -9
- package/docs/en/components/nodeVersion.mdx +2 -2
- package/docs/en/components/rsc-deploy-tip.mdx +0 -1
- package/docs/en/components/ssr-monitor.mdx +1 -1
- package/docs/en/configure/app/bff/cross-project.mdx +2 -2
- package/docs/en/configure/app/bff/prefix.mdx +1 -1
- package/docs/en/configure/app/dev/lazy-compilation.mdx +17 -1
- package/docs/en/configure/app/dev/start-url.mdx +0 -1
- package/docs/en/configure/app/output/css-modules.mdx +1 -5
- package/docs/en/configure/app/output/disable-svgr.mdx +4 -0
- package/docs/en/configure/app/output/dist-path.mdx +0 -1
- package/docs/en/configure/app/output/inline-scripts.mdx +1 -2
- package/docs/en/configure/app/output/inline-styles.mdx +1 -2
- package/docs/en/configure/app/output/split-route-chunks.mdx +1 -1
- package/docs/en/configure/app/output/ssg.mdx +1 -1
- package/docs/en/configure/app/output/ssgByEntries.mdx +1 -0
- package/docs/en/configure/app/output/svg-default-export.mdx +4 -0
- package/docs/en/configure/app/performance/chunk-split.mdx +1 -4
- package/docs/en/configure/app/runtime/plugins.mdx +6 -4
- package/docs/en/configure/app/server/rsc.mdx +1 -1
- package/docs/en/configure/app/server/ssr.mdx +7 -8
- package/docs/en/configure/app/server/tsconfig-path.mdx +2 -2
- package/docs/en/configure/app/tools/less.mdx +94 -19
- package/docs/en/configure/app/tools/sass.mdx +87 -18
- package/docs/en/configure/app/tools/svgr.mdx +93 -0
- package/docs/en/configure/app/usage.mdx +1 -5
- package/docs/en/guides/advanced-features/bff/cross-project.mdx +5 -4
- package/docs/en/guides/advanced-features/compatibility.mdx +0 -1
- package/docs/en/guides/advanced-features/international/advanced.mdx +1 -1
- package/docs/en/guides/advanced-features/international/api.mdx +34 -28
- package/docs/en/guides/advanced-features/international/best-practices.mdx +15 -15
- package/docs/en/guides/advanced-features/international/configuration.mdx +37 -37
- package/docs/en/guides/advanced-features/international/locale-detection.mdx +37 -28
- package/docs/en/guides/advanced-features/international/resource-loading.mdx +19 -17
- package/docs/en/guides/advanced-features/international/routing.mdx +8 -6
- package/docs/en/guides/advanced-features/international.mdx +8 -8
- package/docs/en/guides/advanced-features/server-monitor/logger.mdx +5 -5
- package/docs/en/guides/advanced-features/server-monitor/metrics.mdx +8 -8
- package/docs/en/guides/advanced-features/server-monitor/monitors.mdx +1 -3
- package/docs/en/guides/advanced-features/source-build.mdx +1 -1
- package/docs/en/guides/advanced-features/web-server.mdx +3 -3
- package/docs/en/guides/basic-features/data/data-fetch.mdx +1 -3
- package/docs/en/guides/basic-features/data/data-write.mdx +24 -28
- package/docs/en/guides/basic-features/debug/mock.mdx +2 -2
- package/docs/en/guides/basic-features/debug/using-storybook.mdx +5 -6
- package/docs/en/guides/basic-features/html.mdx +2 -3
- package/docs/en/guides/basic-features/output-files.mdx +1 -1
- package/docs/en/guides/basic-features/render/overview.mdx +12 -12
- package/docs/en/guides/basic-features/render/rsc.mdx +16 -9
- package/docs/en/guides/basic-features/render/ssr-cache.mdx +5 -5
- package/docs/en/guides/basic-features/render/ssr.mdx +8 -12
- package/docs/en/guides/basic-features/render/streaming-ssr.mdx +2 -1
- package/docs/en/guides/basic-features/routes/config-routes.mdx +60 -59
- package/docs/en/guides/basic-features/static-assets/svg-assets.mdx +29 -17
- package/docs/en/guides/basic-features/testing/playwright.mdx +14 -8
- package/docs/en/guides/basic-features/testing/rstest.mdx +6 -4
- package/docs/en/guides/get-started/ai-coding-agents.mdx +6 -6
- package/docs/en/guides/get-started/introduction.mdx +0 -1
- package/docs/en/guides/topic-detail/module-federation/deploy.mdx +2 -2
- package/docs/en/guides/topic-detail/module-federation/introduce.mdx +0 -1
- package/docs/en/guides/upgrade/config.mdx +12 -0
- package/docs/en/guides/upgrade/other.mdx +4 -4
- package/docs/en/guides/upgrade/tailwindcss.mdx +0 -1
- package/docs/en/guides/upgrade/web-server.md +34 -17
- package/docs/en/index.md +1 -0
- package/docs/en/plugin/cli-plugins/api.mdx +23 -23
- package/docs/en/plugin/cli-plugins/life-cycle.mdx +2 -0
- package/docs/en/plugin/introduction.mdx +6 -6
- package/docs/en/plugin/official/cli-plugins/plugin-bff.mdx +1 -1
- package/docs/en/plugin/official/cli-plugins/plugin-ssg.mdx +1 -1
- package/docs/en/plugin/plugin-system.mdx +19 -26
- package/docs/en/plugin/runtime-plugins/life-cycle.mdx +2 -0
- package/docs/en/plugin/server-plugins/api.mdx +11 -14
- package/docs/en/plugin/server-plugins/life-cycle.mdx +2 -0
- package/docs/zh/apis/app/hooks/api/lambda.mdx +1 -1
- package/docs/zh/apis/app/hooks/config/html.mdx +1 -0
- package/docs/zh/apis/app/hooks/config/mock.mdx +1 -0
- package/docs/zh/apis/app/hooks/config/public.mdx +1 -0
- package/docs/zh/apis/app/hooks/config/upload.mdx +2 -3
- package/docs/zh/apis/app/hooks/modern-config.mdx +1 -0
- package/docs/zh/apis/app/hooks/shared.mdx +1 -0
- package/docs/zh/apis/app/hooks/src/modern.runtime.mdx +1 -0
- package/docs/zh/apis/app/hooks/src/routes.mdx +1 -0
- package/docs/zh/apis/app/hooks/src/server.mdx +2 -1
- package/docs/zh/apis/app/runtime/bff/use-hono-context.mdx +1 -1
- package/docs/zh/apis/app/runtime/core/create-root.mdx +4 -1
- package/docs/zh/apis/app/runtime/core/render.mdx +6 -3
- package/docs/zh/apis/app/runtime/core/runtime-context.mdx +17 -17
- package/docs/zh/apis/app/runtime/router/router.mdx +10 -6
- package/docs/zh/apis/app/runtime/ssr/no-ssr.mdx +1 -0
- package/docs/zh/apis/app/runtime/utility/head.mdx +1 -0
- package/docs/zh/apis/app/runtime/utility/loadable.mdx +1 -0
- package/docs/zh/community/blog/v3-release-note.mdx +38 -29
- package/docs/zh/community/contributing-guide.mdx +16 -34
- package/docs/zh/components/default-browserslist.mdx +0 -1
- package/docs/zh/components/deploy-command.mdx +1 -1
- package/docs/zh/components/deploy.mdx +1 -1
- package/docs/zh/components/entry-scan-logic.mdx +1 -1
- package/docs/zh/components/init-app.mdx +9 -3
- package/docs/zh/components/international/custom-instance-code.mdx +0 -1
- package/docs/zh/components/international/install-command.mdx +0 -1
- package/docs/zh/components/micro-runtime-config.mdx +12 -9
- package/docs/zh/components/nodeVersion.mdx +2 -2
- package/docs/zh/components/rsc-deploy-tip.mdx +0 -1
- package/docs/zh/components/ssr-monitor.mdx +1 -1
- package/docs/zh/configure/app/bff/cross-project.mdx +2 -2
- package/docs/zh/configure/app/bff/prefix.mdx +1 -1
- package/docs/zh/configure/app/dev/lazy-compilation.mdx +17 -1
- package/docs/zh/configure/app/html/crossorigin.mdx +0 -1
- package/docs/zh/configure/app/html/favicon.mdx +0 -1
- package/docs/zh/configure/app/output/convert-to-rem.mdx +0 -1
- package/docs/zh/configure/app/output/css-modules.mdx +1 -5
- package/docs/zh/configure/app/output/disable-svgr.mdx +4 -0
- package/docs/zh/configure/app/output/inline-scripts.mdx +1 -2
- package/docs/zh/configure/app/output/inline-styles.mdx +1 -2
- package/docs/zh/configure/app/output/source-map.mdx +0 -2
- package/docs/zh/configure/app/output/split-route-chunks.mdx +1 -1
- package/docs/zh/configure/app/output/ssg.mdx +1 -0
- package/docs/zh/configure/app/output/ssgByEntries.mdx +1 -1
- package/docs/zh/configure/app/output/svg-default-export.mdx +4 -0
- package/docs/zh/configure/app/performance/chunk-split.mdx +1 -4
- package/docs/zh/configure/app/resolve/dedupe.mdx +0 -1
- package/docs/zh/configure/app/runtime/plugins.mdx +6 -4
- package/docs/zh/configure/app/server/rsc.mdx +1 -1
- package/docs/zh/configure/app/server/ssr.mdx +6 -7
- package/docs/zh/configure/app/server/tsconfig-path.mdx +2 -2
- package/docs/zh/configure/app/tools/less.mdx +93 -19
- package/docs/zh/configure/app/tools/sass.mdx +87 -16
- package/docs/zh/configure/app/tools/svgr.mdx +93 -0
- package/docs/zh/configure/app/usage.mdx +1 -5
- package/docs/zh/guides/advanced-features/bff.mdx +1 -0
- package/docs/zh/guides/advanced-features/international/advanced.mdx +1 -1
- package/docs/zh/guides/advanced-features/international/api.mdx +28 -27
- package/docs/zh/guides/advanced-features/international/best-practices.mdx +15 -15
- package/docs/zh/guides/advanced-features/international/configuration.mdx +38 -36
- package/docs/zh/guides/advanced-features/international/locale-detection.mdx +37 -28
- package/docs/zh/guides/advanced-features/international/resource-loading.mdx +20 -16
- package/docs/zh/guides/advanced-features/international/routing.mdx +6 -4
- package/docs/zh/guides/advanced-features/international.mdx +9 -9
- package/docs/zh/guides/advanced-features/server-monitor/logger.mdx +4 -6
- package/docs/zh/guides/advanced-features/server-monitor/metrics.mdx +9 -10
- package/docs/zh/guides/advanced-features/source-build.mdx +1 -1
- package/docs/zh/guides/advanced-features/web-server.mdx +3 -3
- package/docs/zh/guides/basic-features/data/data-fetch.mdx +1 -3
- package/docs/zh/guides/basic-features/data/data-write.mdx +25 -31
- package/docs/zh/guides/basic-features/debug/mock.mdx +2 -2
- package/docs/zh/guides/basic-features/debug/using-storybook.mdx +5 -5
- package/docs/zh/guides/basic-features/env-vars.mdx +0 -1
- package/docs/zh/guides/basic-features/html.mdx +2 -3
- package/docs/zh/guides/basic-features/render/overview.mdx +12 -13
- package/docs/zh/guides/basic-features/render/rsc.mdx +16 -9
- package/docs/zh/guides/basic-features/render/ssr.mdx +8 -17
- package/docs/zh/guides/basic-features/routes/config-routes.mdx +61 -59
- package/docs/zh/guides/basic-features/static-assets/svg-assets.mdx +29 -17
- package/docs/zh/guides/basic-features/testing/playwright.mdx +15 -10
- package/docs/zh/guides/basic-features/testing/rstest.mdx +6 -4
- package/docs/zh/guides/get-started/ai-coding-agents.mdx +7 -7
- package/docs/zh/guides/topic-detail/module-federation/deploy.mdx +2 -2
- package/docs/zh/guides/upgrade/config.mdx +12 -0
- package/docs/zh/guides/upgrade/other.md +4 -11
- package/docs/zh/guides/upgrade/overview.mdx +1 -4
- package/docs/zh/guides/upgrade/tailwindcss.mdx +0 -1
- package/docs/zh/guides/upgrade/web-server.md +34 -19
- package/docs/zh/index.md +1 -0
- package/docs/zh/plugin/cli-plugins/api.mdx +24 -24
- package/docs/zh/plugin/cli-plugins/life-cycle.mdx +2 -0
- package/docs/zh/plugin/introduction.mdx +6 -6
- package/docs/zh/plugin/official/cli-plugins/plugin-bff.mdx +1 -1
- package/docs/zh/plugin/official/cli-plugins/plugin-ssg.mdx +1 -1
- package/docs/zh/plugin/plugin-system.mdx +19 -26
- package/docs/zh/plugin/runtime-plugins/life-cycle.mdx +2 -0
- package/docs/zh/plugin/server-plugins/api.mdx +11 -14
- package/docs/zh/plugin/server-plugins/life-cycle.mdx +2 -0
- package/package.json +11 -13
- package/{rspress.config.ts → rstack.config.mts} +7 -10
- package/src/components/Footer/styles.module.scss +1 -1
- 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
|
```
|
|
@@ -20,9 +20,8 @@ Modern.js 约定,在 `src/` 或入口目录下,可以创建 `Document.tsx`
|
|
|
20
20
|
├── entry-a
|
|
21
21
|
│ ├── Document.tsx
|
|
22
22
|
│ └── routes
|
|
23
|
-
|
|
24
|
-
|
|
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**
|
|
14
|
-
| **SSR**
|
|
15
|
-
| **Streaming SSR** | 边渲染边返回,更快显示初始 UI
|
|
16
|
-
| **RSC**
|
|
17
|
-
| **SSG**
|
|
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**
|
|
24
|
-
| **Streaming SSR**
|
|
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
|
-
| 特性
|
|
243
|
-
|
|
|
244
|
-
| 避免请求瀑布 | 需要手动优化
|
|
245
|
-
| 组件内聚性
|
|
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({
|
|
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({
|
|
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
|
-
|
|
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(
|
|
77
|
-
route(
|
|
74
|
+
route('home.tsx', '/'),
|
|
75
|
+
route('about.tsx', 'about'),
|
|
78
76
|
|
|
79
77
|
// 有子路由时,自动生成布局路由
|
|
80
78
|
// dashboard/layout.tsx 需要包含 <Outlet> 来渲染子路由
|
|
81
|
-
route(
|
|
82
|
-
route(
|
|
83
|
-
route(
|
|
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(
|
|
85
|
+
route('products/detail.tsx', 'products/:id'),
|
|
88
86
|
|
|
89
87
|
// 多路径指向同一组件
|
|
90
|
-
route(
|
|
91
|
-
route(
|
|
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(
|
|
109
|
-
page(
|
|
110
|
-
page(
|
|
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(
|
|
129
|
-
page(
|
|
130
|
-
page(
|
|
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(
|
|
149
|
-
page(
|
|
150
|
-
page(
|
|
151
|
-
$(
|
|
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(
|
|
174
|
-
page(
|
|
175
|
-
page(
|
|
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(
|
|
190
|
-
page(
|
|
191
|
-
page(
|
|
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(
|
|
207
|
-
page(
|
|
208
|
-
page(
|
|
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(
|
|
224
|
+
page('blog/detail.tsx', 'blog/:id'),
|
|
222
225
|
|
|
223
226
|
// 可选参数
|
|
224
|
-
page(
|
|
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(
|
|
238
|
-
route(
|
|
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
|
-
你可以通过 [
|
|
45
|
+
你可以通过 [tools.svgr](/configure/app/tools/svgr) 的 `svgrOptions.exportType` 来修改 SVG 文件默认导出的内容,比如把默认导出的内容设置为 React 组件:
|
|
46
46
|
|
|
47
47
|
```ts
|
|
48
48
|
export default {
|
|
49
|
-
|
|
50
|
-
|
|
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 组件使用时,可以通过将 [
|
|
89
|
+
如果你确定项目内的所有 SVG 资源都没有当成 React 组件使用时,可以通过将 [tools.svgr](/configure/app/tools/svgr) 设置为 `false` 来关闭此项转换,以提升构建性能。
|
|
84
90
|
|
|
85
91
|
```js
|
|
86
92
|
export default {
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
|
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
|
|
88
|
-
page.getByRole('heading', { level: 1, name: 'Home' })
|
|
89
|
-
|
|
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
|
+
/>
|