@modern-js/main-doc 3.0.4 → 3.1.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/components/rsc-deploy-tip.mdx +1 -0
- package/docs/en/guides/basic-features/debug/using-storybook.mdx +52 -0
- package/docs/en/guides/basic-features/render/rsc.mdx +5 -0
- package/docs/en/guides/basic-features/testing/_meta.json +1 -1
- package/docs/en/guides/basic-features/testing/rstest.mdx +100 -31
- package/docs/en/guides/upgrade/other.mdx +8 -0
- package/docs/zh/components/rsc-deploy-tip.mdx +1 -0
- package/docs/zh/guides/basic-features/debug/using-storybook.mdx +44 -0
- package/docs/zh/guides/basic-features/render/rsc.mdx +5 -0
- package/docs/zh/guides/basic-features/testing/_meta.json +1 -1
- package/docs/zh/guides/basic-features/testing/rstest.mdx +101 -32
- package/docs/zh/guides/upgrade/other.md +8 -0
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -43,6 +43,58 @@ const config: StorybookConfig = {
|
|
|
43
43
|
export default config
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
|
|
47
|
+
## BFF Integrated Calls in Storybook
|
|
48
|
+
|
|
49
|
+
When you want to call BFF APIs directly in Storybook components (for example `/api/**`), start the BFF service and configure a proxy in Storybook's dev server to avoid CORS issues.
|
|
50
|
+
|
|
51
|
+
### 1. Add scripts
|
|
52
|
+
|
|
53
|
+
Add the following scripts to `package.json` to start the BFF server and Storybook separately. The `BFF_PROXY` environment variable ensures the proxy is only enabled during Storybook build:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"scripts": {
|
|
58
|
+
"dev:api": "modern dev --api-only",
|
|
59
|
+
"storybook": "BFF_PROXY=1 storybook dev -p 6006 --no-open",
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 2. Configure proxy
|
|
65
|
+
|
|
66
|
+
Add the following config in `modern.config.ts` to proxy requests to the BFF service only during Storybook build:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
export default applyBaseConfig({
|
|
70
|
+
dev: process.env.BFF_PROXY
|
|
71
|
+
? {
|
|
72
|
+
server: {
|
|
73
|
+
proxy: {
|
|
74
|
+
'/api': 'http://localhost:8080',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
}
|
|
78
|
+
: {},
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Proxy path and port follow this logic:
|
|
83
|
+
|
|
84
|
+
- If `dev.server.proxy` is configured, use that configuration
|
|
85
|
+
- If not configured, the proxy path falls back to `bff.prefix`, otherwise `/api`
|
|
86
|
+
- If not configured, the target port falls back to `server.port`, otherwise `8080`
|
|
87
|
+
- The final target is `http://localhost:<port>`
|
|
88
|
+
|
|
89
|
+
### 3. Start
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pnpm dev:api
|
|
93
|
+
pnpm storybook
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Now you can request the path configured in `bff.prefix`; if not configured, use `/api/**`.
|
|
97
|
+
|
|
46
98
|
## Example
|
|
47
99
|
|
|
48
100
|
You can check out the [example](https://github.com/rspack-contrib/storybook-rsbuild/tree/main/sandboxes/modernjs-react) to learn how to use Storybook in Modern.js.
|
|
@@ -513,6 +513,11 @@ export default function ProfilePage() {
|
|
|
513
513
|
|
|
514
514
|
When using React 19, you no longer need to use Helmet. We recommend directly using the [components](https://react.dev/reference/react-dom/components) provided by React.
|
|
515
515
|
|
|
516
|
+
import DeployTip from '@site-docs/components/rsc-deploy-tip';
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
<DeployTip />
|
|
520
|
+
|
|
516
521
|
## Common Issues
|
|
517
522
|
|
|
518
523
|
### `This entry point is not yet supported outside of experimental channels`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
["playwright", "vitest", "jest", "cypress"]
|
|
1
|
+
["playwright", "rstest", "vitest", "jest", "cypress"]
|
|
@@ -1,31 +1,33 @@
|
|
|
1
1
|
# Rstest
|
|
2
2
|
|
|
3
|
-
Rstest is a testing framework developed by the Rspack team
|
|
3
|
+
[Rstest](https://rstest.rs) is a testing framework developed by the Rspack team and built on top of Rspack for fast test execution.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This guide explains how to integrate Rstest with Modern.js for web app testing.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
Install the base dependencies first:
|
|
6
10
|
|
|
7
11
|
import { PackageManagerTabs } from '@theme';
|
|
8
12
|
|
|
9
|
-
<PackageManagerTabs command=
|
|
10
|
-
npm: "npm install -D @rstest/core jsdom @testing-library/react @testing-library/dom",
|
|
11
|
-
yarn: "yarn add -D @rstest/core jsdom @testing-library/react @testing-library/dom",
|
|
12
|
-
pnpm: "pnpm install -D @rstest/core jsdom @testing-library/react @testing-library/dom",
|
|
13
|
-
bun: "bun add -D @rstest/core jsdom @testing-library/react @testing-library/dom"
|
|
14
|
-
}} />
|
|
13
|
+
<PackageManagerTabs command="add @rstest/core @modern-js/adapter-rstest -D" />
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
Then create `rstest.config.ts`:
|
|
17
16
|
|
|
18
17
|
```ts title="rstest.config.ts"
|
|
19
18
|
import { defineConfig } from '@rstest/core';
|
|
19
|
+
import { withModernConfig } from '@modern-js/adapter-rstest';
|
|
20
20
|
|
|
21
21
|
export default defineConfig({
|
|
22
|
-
|
|
22
|
+
extends: withModernConfig(),
|
|
23
23
|
});
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
`@modern-js/adapter-rstest` lets Rstest inherit your existing Modern.js config so your test setup stays aligned with your app.
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
For more configuration details, refer to the [Rstest configuration documentation](https://rstest.rs/config).
|
|
29
|
+
|
|
30
|
+
You can run tests with `npx rstest`, or add a script in `package.json`:
|
|
29
31
|
|
|
30
32
|
```json title="package.json"
|
|
31
33
|
{
|
|
@@ -35,31 +37,99 @@ You can optionally add the `rstest` command to `package.json`:
|
|
|
35
37
|
}
|
|
36
38
|
```
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
## Testing Web UI
|
|
41
|
+
|
|
42
|
+
For web UI tests in Modern.js, there are two common approaches:
|
|
43
|
+
|
|
44
|
+
- Use Rstest browser mode, which runs tests in a real browser. This is the recommended option in most cases, although it is currently experimental.
|
|
45
|
+
- Use a simulated DOM environment with `happy-dom` and Testing Library. This matches the default web test environment provided by `@modern-js/adapter-rstest`.
|
|
46
|
+
|
|
47
|
+
We generally recommend browser mode because it uses real browser APIs and behavior, supports cases that simulated DOM environments cannot fully cover, and offers a better debugging experience when UI behavior does not match expectations.
|
|
48
|
+
|
|
49
|
+
### Browser mode (experimental)
|
|
50
|
+
|
|
51
|
+
If you want to test in a real browser instead of a simulated DOM, install the browser mode dependencies:
|
|
52
|
+
|
|
53
|
+
<PackageManagerTabs command="add @rstest/browser @rstest/browser-react playwright -D" />
|
|
54
|
+
|
|
55
|
+
Then enable browser mode in `rstest.config.ts`:
|
|
56
|
+
|
|
57
|
+
```ts title="rstest.config.ts"
|
|
58
|
+
import { defineConfig } from '@rstest/core';
|
|
59
|
+
import { withModernConfig } from '@modern-js/adapter-rstest';
|
|
60
|
+
|
|
61
|
+
export default defineConfig({
|
|
62
|
+
extends: withModernConfig(),
|
|
63
|
+
browser: {
|
|
64
|
+
enabled: true,
|
|
65
|
+
provider: 'playwright',
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Example test:
|
|
71
|
+
|
|
72
|
+
```tsx title="__tests__/page.browser.test.tsx"
|
|
73
|
+
import { BrowserRouter as Router } from '@modern-js/runtime/router';
|
|
74
|
+
import { page } from '@rstest/browser';
|
|
75
|
+
import { render } from '@rstest/browser-react';
|
|
76
|
+
import { expect, test } from '@rstest/core';
|
|
77
|
+
import Page from '../routes/page';
|
|
78
|
+
|
|
79
|
+
test('Page', async () => {
|
|
80
|
+
await render(
|
|
81
|
+
<Router>
|
|
82
|
+
<Page />
|
|
83
|
+
</Router>,
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
await expect.element(
|
|
87
|
+
page.getByRole('heading', { level: 1, name: 'Home' }),
|
|
88
|
+
).toBeVisible();
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
For more browser mode setup, Locator APIs, and assertions, refer to the [Rstest documentation](https://rstest.rs/guide/browser-testing/).
|
|
93
|
+
|
|
94
|
+
### DOM simulation with `happy-dom`
|
|
39
95
|
|
|
40
|
-
|
|
96
|
+
Install the DOM testing dependencies:
|
|
97
|
+
|
|
98
|
+
<PackageManagerTabs command="add happy-dom @testing-library/react @testing-library/dom -D" />
|
|
99
|
+
|
|
100
|
+
Update `rstest.config.ts` to use `happy-dom`:
|
|
101
|
+
|
|
102
|
+
```ts title="rstest.config.ts"
|
|
103
|
+
import { defineConfig } from '@rstest/core';
|
|
104
|
+
import { withModernConfig } from '@modern-js/adapter-rstest';
|
|
105
|
+
|
|
106
|
+
export default defineConfig({
|
|
107
|
+
extends: withModernConfig(),
|
|
108
|
+
testEnvironment: 'happy-dom',
|
|
109
|
+
});
|
|
110
|
+
```
|
|
41
111
|
|
|
42
112
|
First, create a simple page for testing:
|
|
43
113
|
|
|
44
114
|
```tsx title="routes/page.tsx"
|
|
45
115
|
import { Link } from '@modern-js/runtime/router';
|
|
46
116
|
|
|
47
|
-
const
|
|
117
|
+
const Page = () => (
|
|
48
118
|
<div>
|
|
49
119
|
<h1>Home</h1>
|
|
50
120
|
<Link to="/about">About</Link>
|
|
51
121
|
</div>
|
|
52
122
|
);
|
|
53
123
|
|
|
54
|
-
export default
|
|
124
|
+
export default Page;
|
|
55
125
|
```
|
|
56
126
|
|
|
57
|
-
|
|
127
|
+
Then add a test case:
|
|
58
128
|
|
|
59
129
|
```tsx title="__tests__/page.test.tsx"
|
|
130
|
+
import { BrowserRouter as Router } from '@modern-js/runtime/router';
|
|
60
131
|
import { expect, test } from '@rstest/core';
|
|
61
132
|
import { render, screen } from '@testing-library/react';
|
|
62
|
-
import { BrowserRouter as Router } from '@modern-js/runtime/router';
|
|
63
133
|
import Page from '../routes/page';
|
|
64
134
|
|
|
65
135
|
test('Page', () => {
|
|
@@ -68,27 +138,26 @@ test('Page', () => {
|
|
|
68
138
|
<Page />
|
|
69
139
|
</Router>,
|
|
70
140
|
);
|
|
141
|
+
|
|
71
142
|
expect(screen.getByRole('heading', { level: 1, name: 'Home' })).toBeDefined();
|
|
72
143
|
});
|
|
73
144
|
```
|
|
74
145
|
|
|
75
|
-
In the above test case, we imported the `<Router>` component from `@modern-js/runtime/router` because React Router requires the corresponding context when rendering route-related components.
|
|
76
|
-
|
|
77
|
-
:::note
|
|
78
|
-
When running directly in a Modern.js application, the `<Router>` component is automatically injected.
|
|
79
|
-
:::
|
|
80
|
-
|
|
81
146
|
## Running Test Cases
|
|
82
147
|
|
|
83
|
-
Execute the `test` command above to run
|
|
148
|
+
Execute the `test` command above to run your tests:
|
|
84
149
|
|
|
85
150
|
```bash
|
|
86
|
-
✓
|
|
151
|
+
✓ __tests__/page.test.tsx (1)
|
|
87
152
|
✓ Page
|
|
88
153
|
|
|
89
|
-
Test Files
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
PASS Waiting for file changes...
|
|
154
|
+
Test Files 1 passed
|
|
155
|
+
Tests 1 passed
|
|
156
|
+
Duration 510ms (build 145ms, tests 365ms)
|
|
94
157
|
```
|
|
158
|
+
|
|
159
|
+
## Node Mode
|
|
160
|
+
|
|
161
|
+
If you need node mode tests for server-side logic such as `bff`, refer to the [Rstest documentation](https://rstest.rs) directly.
|
|
162
|
+
|
|
163
|
+
Modern.js mainly targets web apps, so this guide focuses on web UI testing and browser mode.
|
|
@@ -170,6 +170,14 @@ antd v5 uses a CSS-in-JS solution and natively supports on-demand loading, so `s
|
|
|
170
170
|
For more details, refer to [Rsbuild - source.transformImport](https://v2.rsbuild.rs/config/source/transform-import).
|
|
171
171
|
:::
|
|
172
172
|
|
|
173
|
+
## `node_modules` Resolution Behavior Removed
|
|
174
|
+
|
|
175
|
+
In Modern.js v1, there was an internal workaround that redirected `node_modules` module resolution to the project root directory. This behavior has been removed in Modern.js 3.0.
|
|
176
|
+
|
|
177
|
+
This workaround was not a standard practice and could lead to unpredictable dependency resolution — for example, packages not explicitly declared in a project's `package.json` might still resolve successfully, masking missing dependency declarations.
|
|
178
|
+
|
|
179
|
+
If your project relied on this behavior, ensure that all required dependencies are explicitly declared in your `package.json` and installed locally.
|
|
180
|
+
|
|
173
181
|
## ESLint Rule Sets
|
|
174
182
|
|
|
175
183
|
Modern.js previously provided complete ESLint rule sets, covering @modern-js (Lint rules for Node.js projects) and @modern-js-app (Lint rules for frontend projects). In [v2.60.0](https://github.com/web-infra-dev/modern.js/releases/tag/v2.60.0), we officially removed these rule sets. We encourage developers to choose appropriate code specification tools according to their needs, directly use ESLint combined with community-recommended rules, or use Biome to improve code formatting performance.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -43,6 +43,50 @@ const config: StorybookConfig = {
|
|
|
43
43
|
export default config
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
## Storybook 中进行 BFF 一体化调用
|
|
47
|
+
|
|
48
|
+
当你希望在 Storybook 的组件中直接调用 BFF 接口(例如请求 `/api/**`)时,需要同时启动 BFF 服务并在 Storybook 的开发服务器中设置代理,避免跨域问题。
|
|
49
|
+
|
|
50
|
+
### 1. 增加 scripts
|
|
51
|
+
|
|
52
|
+
在 `package.json` 中增加以下脚本,用于单独启动 BFF 服务和 Storybook,同时通过 `BFF_PROXY` 环境变量确保代理配置仅在 Storybook 构建时生效:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"scripts": {
|
|
57
|
+
"dev:api": "modern dev --api-only",
|
|
58
|
+
"storybook": "BFF_PROXY=1 storybook dev -p 6006 --no-open",
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 2. 配置代理解决跨域
|
|
64
|
+
|
|
65
|
+
在 `modern.config.ts` 中增加以下配置,仅在 Storybook 构建时将请求代理到 BFF 服务:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
export default applyBaseConfig({
|
|
69
|
+
dev: process.env.BFF_PROXY
|
|
70
|
+
? {
|
|
71
|
+
server: {
|
|
72
|
+
proxy: {
|
|
73
|
+
`${bff.prefix || '/api'}`: `http://localhost:${server.port || '8080'}`,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
: {},
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 3. 启动方式
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pnpm dev:api
|
|
85
|
+
pnpm storybook
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
此时在组件中直接请求 `bff.prefix` 对应的路径即可完成 BFF 一体化调用;如果未配置,则请求 `/api/**`。
|
|
89
|
+
|
|
46
90
|
## 示例
|
|
47
91
|
|
|
48
92
|
你可以查看 [示例](https://github.com/rspack-contrib/storybook-rsbuild/tree/main/sandboxes/modernjs-react) 了解 Modern.js 中使用 Storybook 的方式。
|
|
@@ -598,6 +598,11 @@ export default function ProfilePage() {
|
|
|
598
598
|
|
|
599
599
|
当使用 react19 时,无需再使用 Helmet,推荐直接使用 react 提供的[组件](https://react.dev/reference/react-dom/components)。
|
|
600
600
|
|
|
601
|
+
import DeployTip from '@site-docs/components/rsc-deploy-tip';
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
<DeployTip />
|
|
605
|
+
|
|
601
606
|
## 常见问题
|
|
602
607
|
|
|
603
608
|
### `This entry point is not yet supported outside of experimental channels`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
["playwright", "vitest", "jest", "cypress"]
|
|
1
|
+
["playwright", "rstest", "vitest", "jest", "cypress"]
|
|
@@ -1,31 +1,33 @@
|
|
|
1
1
|
# Rstest
|
|
2
2
|
|
|
3
|
-
Rstest 是由 Rspack 团队开发的测试框架,基于 Rspack
|
|
3
|
+
[Rstest](https://rstest.rs) 是由 Rspack 团队开发的测试框架,基于 Rspack 构建,具备很快的测试执行速度。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
本指南介绍如何在 Modern.js 中集成 Rstest,并用于 web app 测试。
|
|
6
|
+
|
|
7
|
+
## 快速开始
|
|
8
|
+
|
|
9
|
+
先安装基础依赖:
|
|
6
10
|
|
|
7
11
|
import { PackageManagerTabs } from '@theme';
|
|
8
12
|
|
|
9
|
-
<PackageManagerTabs command=
|
|
10
|
-
npm: "npm install -D @rstest/core jsdom @testing-library/react @testing-library/dom",
|
|
11
|
-
yarn: "yarn add -D @rstest/core jsdom @testing-library/react @testing-library/dom",
|
|
12
|
-
pnpm: "pnpm install -D @rstest/core jsdom @testing-library/react @testing-library/dom",
|
|
13
|
-
bun: "bun add -D @rstest/core jsdom @testing-library/react @testing-library/dom"
|
|
14
|
-
}} />
|
|
13
|
+
<PackageManagerTabs command="add @rstest/core @modern-js/adapter-rstest -D" />
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
然后创建 `rstest.config.ts`:
|
|
17
16
|
|
|
18
17
|
```ts title="rstest.config.ts"
|
|
19
18
|
import { defineConfig } from '@rstest/core';
|
|
19
|
+
import { withModernConfig } from '@modern-js/adapter-rstest';
|
|
20
20
|
|
|
21
21
|
export default defineConfig({
|
|
22
|
-
|
|
22
|
+
extends: withModernConfig(),
|
|
23
23
|
});
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
`@modern-js/adapter-rstest` 可以让 Rstest 继承你现有的 Modern.js 配置,使测试环境和应用配置保持一致。
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
更多配置项可以参考 [Rstest 配置文档](https://rstest.rs/config)。
|
|
29
|
+
|
|
30
|
+
你可以通过 `npx rstest` 运行测试,也可以在 `package.json` 中添加脚本:
|
|
29
31
|
|
|
30
32
|
```json title="package.json"
|
|
31
33
|
{
|
|
@@ -35,31 +37,99 @@ export default defineConfig({
|
|
|
35
37
|
}
|
|
36
38
|
```
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
## 测试 Web UI
|
|
41
|
+
|
|
42
|
+
在 Modern.js 中测试 Web UI,通常有两种方案:
|
|
43
|
+
|
|
44
|
+
- 使用 Rstest 的 browser mode,直接在真实浏览器中运行测试。大多数场景更推荐这种方式,但目前仍处于实验性阶段。
|
|
45
|
+
- 使用 `happy-dom` 和 Testing Library 提供一个模拟 DOM 环境,这种方式也符合 `@modern-js/adapter-rstest` 默认的 web 测试环境。
|
|
46
|
+
|
|
47
|
+
我们整体更推荐 browser mode,因为它使用的是真实浏览器 API 和行为,能覆盖模拟 DOM 难以完整支持的场景,同时在排查 UI 行为问题时也更容易调试。
|
|
48
|
+
|
|
49
|
+
### Browser mode(实验性)
|
|
50
|
+
|
|
51
|
+
如果你希望直接在真实浏览器中测试,而不是使用模拟 DOM,可以安装 browser mode 相关依赖:
|
|
52
|
+
|
|
53
|
+
<PackageManagerTabs command="add @rstest/browser @rstest/browser-react playwright -D" />
|
|
54
|
+
|
|
55
|
+
然后在 `rstest.config.ts` 中启用 browser mode:
|
|
56
|
+
|
|
57
|
+
```ts title="rstest.config.ts"
|
|
58
|
+
import { defineConfig } from '@rstest/core';
|
|
59
|
+
import { withModernConfig } from '@modern-js/adapter-rstest';
|
|
60
|
+
|
|
61
|
+
export default defineConfig({
|
|
62
|
+
extends: withModernConfig(),
|
|
63
|
+
browser: {
|
|
64
|
+
enabled: true,
|
|
65
|
+
provider: 'playwright',
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
示例测试如下:
|
|
71
|
+
|
|
72
|
+
```tsx title="__tests__/page.browser.test.tsx"
|
|
73
|
+
import { BrowserRouter as Router } from '@modern-js/runtime/router';
|
|
74
|
+
import { page } from '@rstest/browser';
|
|
75
|
+
import { render } from '@rstest/browser-react';
|
|
76
|
+
import { expect, test } from '@rstest/core';
|
|
77
|
+
import Page from '../routes/page';
|
|
78
|
+
|
|
79
|
+
test('Page', async () => {
|
|
80
|
+
await render(
|
|
81
|
+
<Router>
|
|
82
|
+
<Page />
|
|
83
|
+
</Router>,
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
await expect.element(
|
|
87
|
+
page.getByRole('heading', { level: 1, name: 'Home' }),
|
|
88
|
+
).toBeVisible();
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
关于 browser mode 的更多配置、Locator API 和断言能力,可以直接参考 [Rstest 文档](https://rstest.rs/guide/browser-testing/)。
|
|
93
|
+
|
|
94
|
+
### 使用 `happy-dom` 模拟 DOM
|
|
39
95
|
|
|
40
|
-
|
|
96
|
+
先安装 DOM 测试相关依赖:
|
|
41
97
|
|
|
42
|
-
|
|
98
|
+
<PackageManagerTabs command="add happy-dom @testing-library/react @testing-library/dom -D" />
|
|
99
|
+
|
|
100
|
+
然后在 `rstest.config.ts` 中启用 `happy-dom`:
|
|
101
|
+
|
|
102
|
+
```ts title="rstest.config.ts"
|
|
103
|
+
import { defineConfig } from '@rstest/core';
|
|
104
|
+
import { withModernConfig } from '@modern-js/adapter-rstest';
|
|
105
|
+
|
|
106
|
+
export default defineConfig({
|
|
107
|
+
extends: withModernConfig(),
|
|
108
|
+
testEnvironment: 'happy-dom',
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
先创建一个简单页面用于测试:
|
|
43
113
|
|
|
44
114
|
```tsx title="routes/page.tsx"
|
|
45
115
|
import { Link } from '@modern-js/runtime/router';
|
|
46
116
|
|
|
47
|
-
const
|
|
117
|
+
const Page = () => (
|
|
48
118
|
<div>
|
|
49
119
|
<h1>Home</h1>
|
|
50
120
|
<Link to="/about">About</Link>
|
|
51
121
|
</div>
|
|
52
122
|
);
|
|
53
123
|
|
|
54
|
-
export default
|
|
124
|
+
export default Page;
|
|
55
125
|
```
|
|
56
126
|
|
|
57
|
-
|
|
127
|
+
然后添加测试用例:
|
|
58
128
|
|
|
59
129
|
```tsx title="__tests__/page.test.tsx"
|
|
130
|
+
import { BrowserRouter as Router } from '@modern-js/runtime/router';
|
|
60
131
|
import { expect, test } from '@rstest/core';
|
|
61
132
|
import { render, screen } from '@testing-library/react';
|
|
62
|
-
import { BrowserRouter as Router } from '@modern-js/runtime/router';
|
|
63
133
|
import Page from '../routes/page';
|
|
64
134
|
|
|
65
135
|
test('Page', () => {
|
|
@@ -68,27 +138,26 @@ test('Page', () => {
|
|
|
68
138
|
<Page />
|
|
69
139
|
</Router>,
|
|
70
140
|
);
|
|
141
|
+
|
|
71
142
|
expect(screen.getByRole('heading', { level: 1, name: 'Home' })).toBeDefined();
|
|
72
143
|
});
|
|
73
144
|
```
|
|
74
145
|
|
|
75
|
-
上述用例中,我们从 `@modern-js/runtime/router` 引入了 `<Router>` 组件,这是因为 React Router 在渲染部分路由相关组件时,必须要有对应的上下文。
|
|
76
|
-
|
|
77
|
-
:::note
|
|
78
|
-
直接在 Modern.js 应用中运行时,`<Router>` 组件会自动注入。
|
|
79
|
-
:::
|
|
80
|
-
|
|
81
146
|
## 运行测试用例
|
|
82
147
|
|
|
83
|
-
|
|
148
|
+
执行上面的 `test` 命令即可运行测试:
|
|
84
149
|
|
|
85
150
|
```bash
|
|
86
|
-
✓
|
|
151
|
+
✓ __tests__/page.test.tsx (1)
|
|
87
152
|
✓ Page
|
|
88
153
|
|
|
89
|
-
Test Files
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
PASS Waiting for file changes...
|
|
154
|
+
Test Files 1 passed
|
|
155
|
+
Tests 1 passed
|
|
156
|
+
Duration 510ms (build 145ms, tests 365ms)
|
|
94
157
|
```
|
|
158
|
+
|
|
159
|
+
## Node Mode
|
|
160
|
+
|
|
161
|
+
如果你需要测试 `bff` 等 server-side logic,建议直接参考 [Rstest 文档](https://rstest.rs) 中关于 node mode 的说明。
|
|
162
|
+
|
|
163
|
+
Modern.js 主要面向 web app,因此这里重点介绍的是 Web UI 测试,以及更贴近真实运行环境的 browser mode。
|
|
@@ -171,6 +171,14 @@ antd v5 使用了 CSS-in-JS 方案,已原生支持按需加载,无需配置
|
|
|
171
171
|
更多用法请参考 [Rsbuild - source.transformImport](https://v2.rsbuild.rs/config/source/transform-import)。
|
|
172
172
|
:::
|
|
173
173
|
|
|
174
|
+
## 移除 `node_modules` 解析重定向行为
|
|
175
|
+
|
|
176
|
+
在 Modern.js v1 版本中,框架内部存在一个 hack,会将 `node_modules` 的模块解析路径强制指向项目根目录。在 Modern.js 3.0 中,我们移除了这一行为。
|
|
177
|
+
|
|
178
|
+
这一做法并非标准实践,可能导致不可预期的依赖解析问题——例如,未在 `package.json` 中显式声明的依赖包可能仍能被解析,从而掩盖了缺失的依赖声明。
|
|
179
|
+
|
|
180
|
+
如果你的项目依赖了这一行为,请确保所有需要的依赖都已在 `package.json` 中显式声明并安装到本地。
|
|
181
|
+
|
|
174
182
|
## Eslint 规则集
|
|
175
183
|
|
|
176
184
|
Modern.js 之前提供了 ESLint 的完整规则集,涵盖了 @modern-js(针对 Node.js 项目的 Lint 规则)和 @modern-js-app(针对前端项目的 Lint 规则)。在 [v2.60.0](https://github.com/web-infra-dev/modern.js/releases/tag/v2.60.0) 版本中,我们正式移除了这些规则集。我们鼓励开发者根据自身需求选择合适的代码规范工具,直接使用 ESLint 并结合社区推荐的规则,或使用 Biome 以提升代码格式化的性能。
|
package/package.json
CHANGED
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
"modern",
|
|
17
17
|
"modern.js"
|
|
18
18
|
],
|
|
19
|
-
"version": "3.0
|
|
19
|
+
"version": "3.1.0",
|
|
20
20
|
"publishConfig": {
|
|
21
21
|
"registry": "https://registry.npmjs.org/",
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"mermaid": "^11.12.3",
|
|
26
|
-
"@modern-js/sandpack-react": "3.0
|
|
26
|
+
"@modern-js/sandpack-react": "3.1.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@rsbuild/plugin-sass": "1.5.0",
|