@modern-js/main-doc 2.58.2 → 2.59.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. package/docs/en/apis/app/runtime/core/use-loader.mdx +1 -1
  2. package/docs/en/community/blog/_meta.json +1 -6
  3. package/docs/en/components/deploy.mdx +1 -1
  4. package/docs/en/components/init-app.mdx +0 -1
  5. package/docs/en/components/init-rspack-app.mdx +0 -1
  6. package/docs/en/components/ssr-monitor.mdx +3 -0
  7. package/docs/en/configure/_meta.json +1 -1
  8. package/docs/en/configure/app/output/ssg.mdx +52 -141
  9. package/docs/en/configure/app/tools/swc.mdx +1 -1
  10. package/docs/en/configure/app/tools/tailwindcss.mdx +1 -1
  11. package/docs/en/guides/advanced-features/_meta.json +0 -8
  12. package/docs/en/guides/advanced-features/bff/_meta.json +1 -6
  13. package/docs/en/guides/advanced-features/rsbuild-plugin.mdx +2 -2
  14. package/docs/en/guides/advanced-features/rspack-start.mdx +7 -22
  15. package/docs/en/guides/basic-features/_meta.json +31 -9
  16. package/docs/en/guides/basic-features/css/_meta.json +1 -0
  17. package/docs/en/guides/basic-features/css/css-in-js.mdx +34 -0
  18. package/docs/en/guides/basic-features/{css-modules.mdx → css/css-modules.mdx} +0 -4
  19. package/docs/en/guides/basic-features/css/css.mdx +25 -0
  20. package/docs/en/guides/basic-features/{css.mdx → css/tailwindcss.mdx} +5 -66
  21. package/docs/en/guides/basic-features/data/_meta.json +1 -4
  22. package/docs/en/guides/basic-features/data/data-fetch.mdx +134 -235
  23. package/docs/en/guides/basic-features/data/data-write.mdx +66 -77
  24. package/docs/en/guides/basic-features/debug/_meta.json +1 -0
  25. package/docs/en/guides/basic-features/debug/rsdoctor.mdx +57 -0
  26. package/docs/en/guides/{advanced-features → basic-features/debug}/using-storybook.mdx +2 -0
  27. package/docs/en/guides/basic-features/render/_meta.json +1 -0
  28. package/docs/en/guides/basic-features/render/ssg.mdx +208 -0
  29. package/docs/en/guides/{advanced-features/ssr/cache.mdx → basic-features/render/ssr-cache.mdx} +38 -50
  30. package/docs/en/guides/basic-features/render/ssr.mdx +301 -0
  31. package/docs/en/guides/basic-features/render/streaming-ssr.mdx +230 -0
  32. package/docs/en/guides/basic-features/routes.mdx +275 -263
  33. package/docs/en/guides/basic-features/static-assets/_meta.json +1 -0
  34. package/docs/en/guides/basic-features/static-assets.mdx +1 -1
  35. package/docs/en/guides/basic-features/testing/_meta.json +1 -0
  36. package/docs/en/guides/basic-features/testing/cypress.mdx +95 -0
  37. package/docs/en/guides/basic-features/testing/jest.mdx +148 -0
  38. package/docs/en/guides/basic-features/testing/playwright.mdx +111 -0
  39. package/docs/en/guides/basic-features/testing/vitest.mdx +100 -0
  40. package/docs/en/guides/concept/_meta.json +1 -4
  41. package/docs/en/guides/concept/entries.mdx +78 -47
  42. package/docs/en/guides/get-started/_meta.json +1 -7
  43. package/docs/en/guides/get-started/introduction.mdx +1 -1
  44. package/docs/en/guides/get-started/quick-start.mdx +1 -2
  45. package/docs/en/guides/get-started/tech-stack.mdx +4 -6
  46. package/docs/en/guides/get-started/upgrade.mdx +16 -2
  47. package/docs/en/guides/topic-detail/framework-plugin/_meta.json +1 -1
  48. package/docs/en/guides/topic-detail/generator/_meta.json +1 -1
  49. package/docs/en/guides/topic-detail/generator/create/_meta.json +1 -5
  50. package/docs/en/guides/topic-detail/generator/create/config.mdx +0 -10
  51. package/docs/en/guides/topic-detail/generator/create/use.mdx +0 -1
  52. package/docs/en/guides/topic-detail/generator/new/_meta.json +1 -5
  53. package/docs/en/guides/topic-detail/generator/plugin/_meta.json +1 -1
  54. package/docs/en/guides/troubleshooting/_meta.json +1 -6
  55. package/docs/en/tutorials/first-app/c03-css.mdx +1 -1
  56. package/docs/zh/apis/app/runtime/core/use-loader.mdx +1 -1
  57. package/docs/zh/community/blog/_meta.json +1 -6
  58. package/docs/zh/components/deploy.mdx +1 -1
  59. package/docs/zh/components/init-app.mdx +0 -1
  60. package/docs/zh/components/init-rspack-app.mdx +0 -1
  61. package/docs/zh/components/ssr-monitor.mdx +3 -0
  62. package/docs/zh/configure/_meta.json +1 -1
  63. package/docs/zh/configure/app/output/ssg.mdx +49 -139
  64. package/docs/zh/configure/app/tools/swc.mdx +1 -1
  65. package/docs/zh/configure/app/tools/tailwindcss.mdx +1 -1
  66. package/docs/zh/guides/advanced-features/_meta.json +0 -8
  67. package/docs/zh/guides/advanced-features/bff/_meta.json +1 -6
  68. package/docs/zh/guides/advanced-features/rsbuild-plugin.mdx +2 -2
  69. package/docs/zh/guides/advanced-features/rspack-start.mdx +8 -24
  70. package/docs/zh/guides/basic-features/_meta.json +31 -9
  71. package/docs/zh/guides/basic-features/css/_meta.json +1 -0
  72. package/docs/zh/guides/basic-features/css/css-in-js.mdx +34 -0
  73. package/docs/zh/guides/basic-features/css/css.mdx +25 -0
  74. package/docs/zh/guides/basic-features/{css.mdx → css/tailwindcss.mdx} +3 -64
  75. package/docs/zh/guides/basic-features/data/_meta.json +1 -4
  76. package/docs/zh/guides/basic-features/data/data-fetch.mdx +98 -214
  77. package/docs/zh/guides/basic-features/data/data-write.mdx +54 -55
  78. package/docs/zh/guides/basic-features/debug/_meta.json +1 -0
  79. package/docs/zh/guides/basic-features/debug/rsdoctor.mdx +57 -0
  80. package/docs/zh/guides/{advanced-features → basic-features/debug}/using-storybook.mdx +1 -1
  81. package/docs/zh/guides/basic-features/render/_meta.json +1 -0
  82. package/docs/zh/guides/basic-features/render/ssg.mdx +210 -0
  83. package/docs/zh/guides/{advanced-features/ssr/cache.mdx → basic-features/render/ssr-cache.mdx} +16 -26
  84. package/docs/zh/guides/basic-features/render/ssr.mdx +309 -0
  85. package/docs/zh/guides/{advanced-features/ssr/stream.mdx → basic-features/render/streaming-ssr.mdx} +22 -37
  86. package/docs/zh/guides/basic-features/routes.mdx +252 -237
  87. package/docs/zh/guides/basic-features/static-assets/_meta.json +1 -0
  88. package/docs/zh/guides/basic-features/static-assets.mdx +2 -6
  89. package/docs/zh/guides/basic-features/testing/_meta.json +1 -0
  90. package/docs/zh/guides/basic-features/testing/cypress.mdx +95 -0
  91. package/docs/zh/guides/basic-features/testing/jest.mdx +148 -0
  92. package/docs/zh/guides/basic-features/testing/playwright.mdx +112 -0
  93. package/docs/zh/guides/basic-features/testing/vitest.mdx +100 -0
  94. package/docs/zh/guides/concept/_meta.json +1 -4
  95. package/docs/zh/guides/concept/entries.mdx +80 -58
  96. package/docs/zh/guides/get-started/_meta.json +1 -7
  97. package/docs/zh/guides/get-started/introduction.mdx +2 -2
  98. package/docs/zh/guides/get-started/quick-start.mdx +1 -2
  99. package/docs/zh/guides/get-started/tech-stack.mdx +8 -10
  100. package/docs/zh/guides/get-started/upgrade.mdx +15 -1
  101. package/docs/zh/guides/topic-detail/framework-plugin/_meta.json +1 -1
  102. package/docs/zh/guides/topic-detail/generator/_meta.json +1 -1
  103. package/docs/zh/guides/topic-detail/generator/create/_meta.json +1 -5
  104. package/docs/zh/guides/topic-detail/generator/create/config.mdx +0 -10
  105. package/docs/zh/guides/topic-detail/generator/create/use.mdx +0 -1
  106. package/docs/zh/guides/topic-detail/generator/new/_meta.json +1 -5
  107. package/docs/zh/guides/topic-detail/generator/plugin/_meta.json +1 -1
  108. package/docs/zh/guides/troubleshooting/_meta.json +1 -6
  109. package/docs/zh/tutorials/first-app/c03-css.mdx +1 -1
  110. package/i18n.json +16 -4
  111. package/package.json +6 -6
  112. package/rspress.config.ts +1 -1
  113. package/src/components/ContentCard/index.tsx +1 -1
  114. package/src/components/Sandpack/index.tsx +1 -1
  115. package/src/components/ShowcaseList/index.tsx +1 -1
  116. package/src/i18n/index.ts +1 -1
  117. package/src/pages/index.tsx +2 -2
  118. package/docs/en/apis/app/hooks/config/storybook.mdx +0 -37
  119. package/docs/en/guides/advanced-features/ssg.mdx +0 -116
  120. package/docs/en/guides/advanced-features/ssr/_meta.json +0 -5
  121. package/docs/en/guides/advanced-features/ssr/index.mdx +0 -23
  122. package/docs/en/guides/advanced-features/ssr/stream.mdx +0 -248
  123. package/docs/en/guides/advanced-features/ssr/usage.mdx +0 -341
  124. package/docs/en/guides/advanced-features/ssr.mdx +0 -555
  125. package/docs/zh/apis/app/hooks/config/storybook.mdx +0 -38
  126. package/docs/zh/guides/advanced-features/ssg.mdx +0 -116
  127. package/docs/zh/guides/advanced-features/ssr/_meta.json +0 -5
  128. package/docs/zh/guides/advanced-features/ssr/index.mdx +0 -23
  129. package/docs/zh/guides/advanced-features/ssr/usage.mdx +0 -329
  130. /package/docs/en/guides/basic-features/{mock.mdx → debug/mock.mdx} +0 -0
  131. /package/docs/en/guides/basic-features/{proxy.mdx → debug/proxy.mdx} +0 -0
  132. /package/docs/en/guides/basic-features/{json-files.mdx → static-assets/json-files.mdx} +0 -0
  133. /package/docs/en/guides/basic-features/{svg-assets.mdx → static-assets/svg-assets.mdx} +0 -0
  134. /package/docs/en/guides/basic-features/{wasm-assets.mdx → static-assets/wasm-assets.mdx} +0 -0
  135. /package/docs/zh/guides/basic-features/{css-modules.mdx → css/css-modules.mdx} +0 -0
  136. /package/docs/zh/guides/basic-features/{mock.mdx → debug/mock.mdx} +0 -0
  137. /package/docs/zh/guides/basic-features/{proxy.mdx → debug/proxy.mdx} +0 -0
  138. /package/docs/zh/guides/basic-features/{json-files.mdx → static-assets/json-files.mdx} +0 -0
  139. /package/docs/zh/guides/basic-features/{svg-assets.mdx → static-assets/svg-assets.mdx} +0 -0
  140. /package/docs/zh/guides/basic-features/{wasm-assets.mdx → static-assets/wasm-assets.mdx} +0 -0
@@ -0,0 +1 @@
1
+ ["json-files", "svg-assets", "wasm-assets"]
@@ -1,7 +1,3 @@
1
- ---
2
- sidebar_position: 10
3
- ---
4
-
5
1
  # 引用静态资源
6
2
 
7
3
  Modern.js 支持在代码中引用图片、字体、媒体类型的静态资源。
@@ -21,7 +17,7 @@ Modern.js 支持在代码中引用图片、字体、媒体类型的静态资源
21
17
  如果你需要引用其他格式的静态资源,请参考 [扩展静态资源类型](#扩展静态资源类型)。
22
18
 
23
19
  :::tip SVG 图片
24
- SVG 图片是一种特殊情况,Modern.js 提供了 SVG 转 React 组件的能力,对 SVG 进行单独处理,详见 [引用 SVG 资源](/guides/basic-features/svg-assets.html)。
20
+ SVG 图片是一种特殊情况,Modern.js 提供了 SVG 转 React 组件的能力,对 SVG 进行单独处理,详见 [引用 SVG 资源](/guides/basic-features/static-assets/svg-assets.html)。
25
21
  :::
26
22
 
27
23
  ## 在 JS 文件中引用
@@ -162,4 +158,4 @@ console.log(myFile); // "/static/myFile.6c12aba3.pdf"
162
158
  | PNG | 无损压缩,不会丢失图片细节,不失真,支持半透明 | 不适合色表复杂的图片 | 适合颜色数量少,边界层次分明的图片,适合用在 logo、icon、透明图等场景 |
163
159
  | JPG | 颜色丰富 | 有损压缩,会导致图片失真,不支持透明度 | 适合颜色数量多,颜色带有渐变、过度复杂的图片,适合用在人像照片、风景图等场景 |
164
160
  | WebP | 同时支持有损压缩与无损压缩,支持透明度,体积比 PNG 和 JPG 小很多 | iOS 兼容性不好 | 几乎任何场景的像素图片,支持 WebP 的宿主环境,都应该首选 WebP 图片格式 |
165
- | SVG | 无损格式,不失真,支持透明度 | 不适合复杂图形 | 适合矢量图,适合用于 icon |
161
+ | SVG | 无损格式,不失真,支持透明度 | 不适合复杂图形 | 适合矢量图,适合用于 icon |
@@ -0,0 +1 @@
1
+ ["playwright", "vitest", "jest", "cypress"]
@@ -0,0 +1,95 @@
1
+ # Cypress
2
+
3
+ Cypress 是一个用于 E2E 测试和组件测试的框架。
4
+
5
+ 在 Modern.js 中使用 Cypress 需要先安装依赖,可以执行以下命令:
6
+
7
+ import { PackageManagerTabs } from '@theme';
8
+
9
+ <PackageManagerTabs command={{ npm: "npm install -D cypress", yarn: "yarn add -D cypress", pnpm: "pnpm install -D cypress" }} />
10
+
11
+ 接下来,创建 `cypress.config.ts` 文件,并添加以下内容:
12
+
13
+ ```ts
14
+ import { defineConfig } from 'cypress'
15
+
16
+ export default defineConfig({
17
+ e2e: {
18
+ setupNodeEvents(on, config) {},
19
+ },
20
+ })
21
+ ```
22
+
23
+ ## 编写测试用例
24
+
25
+ 现在,使用 Cypress 来编写一个 E2E 用例,首先创建两张 Modern.js 的页面。
26
+
27
+ ```tsx title="routes/page.tsx"
28
+ import { Link } from '@modern-js/runtime/router';
29
+
30
+ const Index = () => (
31
+ <div>
32
+ <h1>Home</h1>
33
+ <Link to="/about">About</Link>
34
+ </div>
35
+ );
36
+
37
+ export default Index;
38
+ ```
39
+
40
+ ```tsx title="routes/about/page.tsx"
41
+ import { Link } from '@modern-js/runtime/router';
42
+
43
+ const Index = () => (
44
+ <div>
45
+ <h1>About</h1>
46
+ <Link to="/">Home</Link>
47
+ </div>
48
+ );
49
+
50
+ export default Index;
51
+ ```
52
+
53
+ 接下来,创建测试用例文件:
54
+
55
+ ```ts title="cypress/e2e/app.cy.ts"
56
+ describe('Navigation', () => {
57
+ it('should navigate to the about page', () => {
58
+ // Start from the index page
59
+ cy.visit('http://localhost:8080/')
60
+
61
+ // Find a link with an href attribute containing "about" and click it
62
+ cy.get('a[href*="about"]').click()
63
+
64
+ // The new url should include "/about"
65
+ cy.url().should('include', '/about')
66
+
67
+ // The new page should contain an h1 with "About"
68
+ cy.get('h1').contains('About')
69
+ })
70
+ })
71
+ ```
72
+
73
+ 测试文件可能会缺少 API 的类型,你可以参考 [Cypress - Typescript](https://docs.cypress.io/guides/tooling/typescript-support#Configure-tsconfigjson) 文档解决。
74
+
75
+ 你可以将命令添加到 `package.json` 中:
76
+
77
+ ```json title="package.json"
78
+ {
79
+ "scripts": {
80
+ "test": "cypress open"
81
+ }
82
+ }
83
+ ```
84
+
85
+ ## 运行测试用例
86
+
87
+ 执行上述 `test` 命令,运行测试用例:
88
+
89
+ ```bash
90
+ DevTools listening on ws://127.0.0.1:55203/devtools/browser/xxxxx
91
+ ```
92
+
93
+ Cypress 会打开一个无头浏览器,按照提示你可以找到对应的测试文件,并自动运行 E2E 测试:
94
+
95
+ ![cypress](https://lf3-static.bytednsdoc.com/obj/eden-cn/nuvjhpqnuvr/cypress.jpg)
@@ -0,0 +1,148 @@
1
+ # Jest
2
+
3
+ Jest 是一个 JavaScript 测试框架,它主要和 React Testing Library 一起用于单元测试和 Snapshot 测试。
4
+
5
+ 在 Modern.js 中使用 Jest 需要先安装依赖,可以执行以下命令:
6
+
7
+ import { PackageManagerTabs } from '@theme';
8
+
9
+ <PackageManagerTabs command={{
10
+ npm: "npm install -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom",
11
+ yarn: "yarn add -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom",
12
+ pnpm: "pnpm install -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom"
13
+ }} />
14
+
15
+ 随后,你可以运行以下命令,这将自动在项目中初始化 Jets,并生成一个基础的 `jest.config.[jt]s` 配置:
16
+
17
+ <PackageManagerTabs command={{
18
+ npm: "npm init jest@latest",
19
+ yarn: "yarn create jest@latest",
20
+ pnpm: "pnpm create jest@latest"
21
+ }} />
22
+
23
+ ## 配置文件
24
+
25
+ :::note
26
+ 本章节会使用 `.ts` 文件来完成 Jest 测试。
27
+ :::
28
+
29
+ 相比于其他的测试框架,Jest 在构建层面需要更多的配置,例如处理 JSX 和 ESM 语法,因此首先需要安装一些额外的依赖:
30
+
31
+ <PackageManagerTabs command={{
32
+ npm: "npm install -D babel-jest @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript",
33
+ yarn: "yarn add -D babel-jest @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript",
34
+ pnpm: "pnpm install -D babel-jest @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript"
35
+ }} />
36
+
37
+ ### 配置 Jest
38
+
39
+ 你需要进一步配置 `jest.config.ts` 文件,以便让 Jest 能够正确地编译和运行测试用例。下面是一个最基本的配置:
40
+
41
+ ```ts title="jest.config.ts"
42
+ import type { Config } from 'jest';
43
+
44
+ const config: Config = {
45
+ coverageProvider: 'babel',
46
+ setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
47
+ testEnvironment: 'jsdom',
48
+ transform: {
49
+ '^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
50
+ },
51
+ transformIgnorePatterns: [],
52
+ };
53
+
54
+ export default config;
55
+ ```
56
+
57
+ 配置中,将 `transformIgnorePatterns` 设置为了空数组,意味着所有的文件都会经过编译,如果你希望提升测试运行的速度,可以按需配置。
58
+
59
+ `setupFilesAfterEnv` 会在启动时执行,在 `jest.setup.ts` 中,可以引入 `@testing-library/jest-dom`。它包含了一组便捷的自定义匹配器,例如 `.toBeInTheDocument()`,使编写测试变得更容易:
60
+
61
+ ```ts title="jest.setup.ts"
62
+ import '@testing-library/jest-dom';
63
+ ```
64
+
65
+ ### 配置 Babel
66
+
67
+ 你需要配置 Babel 让 Jest 能够自动编译 JSX 等语法,下面是一个基本的配置:
68
+
69
+ ```js title="babel.config.js"
70
+ module.exports = {
71
+ presets: [
72
+ ['@babel/preset-env', { targets: { node: 'current' } }],
73
+ ['@babel/preset-react', { runtime: 'automatic' }],
74
+ '@babel/preset-typescript',
75
+ ],
76
+ };
77
+ ```
78
+
79
+ ## 编写测试用例
80
+
81
+ 现在,你可以开始编写测试用了,首先在 `package.json` 中添加一个 `test` 命令:
82
+
83
+ ```json title="package.json"
84
+ {
85
+ "scripts": {
86
+ "test": "jest"
87
+ }
88
+ }
89
+ ```
90
+
91
+ 创建一个简单的页面用于测试:
92
+
93
+ ```tsx title="routes/page.tsx"
94
+ import { Link } from '@modern-js/runtime/router';
95
+
96
+ const Index = () => (
97
+ <div>
98
+ <h1>Home</h1>
99
+ <Link to="/about">About</Link>
100
+ </div>
101
+ );
102
+
103
+ export default Index;
104
+ ```
105
+
106
+ 添加测试用例,检测页面中是否有预期的文本:
107
+
108
+ ```tsx title="__tests__/page.test.tsx"
109
+ import '@testing-library/jest-dom';
110
+ import { render, screen } from '@testing-library/react';
111
+ import { BrowserRouter as Router } from '@modern-js/runtime/router';
112
+ import Page from '../routes/page';
113
+
114
+ describe('Page', () => {
115
+ it('renders a heading', () => {
116
+ render(
117
+ <Router>
118
+ <Page />
119
+ </Router>,
120
+ );
121
+
122
+ const heading = screen.getByRole('heading', { level: 1 });
123
+
124
+ expect(heading).toBeInTheDocument();
125
+ });
126
+ });
127
+ ```
128
+
129
+ 上述用例中,我们从 `@modern-js/runtime/router` 引入了 `<Router>` 组件,这是因为 React Router 在渲染部分路由相关组件时,必须要有对应的上下文。
130
+
131
+ :::note
132
+ 直接在 Modern.js 应用中运行时,`<Router>` 组件会自动注入。
133
+ :::
134
+
135
+ ## 运行测试用例
136
+
137
+ 执行上述 `test` 命令,运行测试用例:
138
+
139
+ ```bash
140
+ PASS src/__tests__/page.test.tsx
141
+ Page
142
+ ✓ renders a heading (31 ms)
143
+
144
+ Test Suites: 1 passed, 1 total
145
+ Tests: 1 passed, 1 total
146
+ Snapshots: 0 total
147
+ Time: 0.959 s, estimated 1 s
148
+ ```
@@ -0,0 +1,112 @@
1
+ # Playwright
2
+
3
+ Playwright 是一个测试框架,它允许你使用单一的 API,自动的在 Chromium、Firefox 和 WebKit 环境中运行测试用例,你可以使用它来**编写 E2E 测试**。
4
+
5
+ 在 Modern.js 中使用 Playwright 需要先安装依赖,可以执行以下命令:
6
+
7
+ import { PackageManagerTabs } from '@theme';
8
+
9
+ <PackageManagerTabs command={{ npm: "npm init playwright", yarn: "yarn create playwright", pnpm: "pnpm create playwright" }} />
10
+
11
+
12
+ 上述命令会自动安装 Playwright 依赖,并通过一系列提示帮助你在项目中安装和配置,包括添加一个 `playwright.config.ts` 文件。
13
+
14
+ :::info
15
+ 参考 Playwright 官方文档,[安装 Playwright](https://playwright.dev/docs/intro#installation) 查阅更详细的指南。
16
+ :::
17
+
18
+ 按照默认配置创建后,可以在项目中看到以下文件:
19
+
20
+ ```ts title="tests/example.spec.ts"
21
+ import { test, expect } from '@playwright/test';
22
+
23
+ test('has title', async ({ page }) => {
24
+ await page.goto('https://playwright.dev/');
25
+
26
+ // Expect a title "to contain" a substring.
27
+ await expect(page).toHaveTitle(/Playwright/);
28
+ });
29
+
30
+ test('get started link', async ({ page }) => {
31
+ await page.goto('https://playwright.dev/');
32
+
33
+ // Click the get started link.
34
+ await page.getByRole('link', { name: 'Get started' }).click();
35
+
36
+ // Expects page to have a heading with the name of Installation.
37
+ await expect(
38
+ page.getByRole('heading', { name: 'Installation' }),
39
+ ).toBeVisible();
40
+ });
41
+ ```
42
+
43
+ 这是默认的测试文件,现在创建一些新的页面,并测试它们。
44
+
45
+ ## 创建 E2E 测试
46
+
47
+ 首先创建两张 Modern.js 的页面。
48
+
49
+ ```tsx title="routes/page.tsx"
50
+ import { Link } from '@modern-js/runtime/router';
51
+
52
+ const Index = () => (
53
+ <div>
54
+ <h1>Home</h1>
55
+ <Link to="/about">About</Link>
56
+ </div>
57
+ );
58
+
59
+ export default Index;
60
+ ```
61
+
62
+ ```tsx title="routes/about/page.tsx"
63
+ import { Link } from '@modern-js/runtime/router';
64
+
65
+ const Index = () => (
66
+ <div>
67
+ <h1>About</h1>
68
+ <Link to="/">Home</Link>
69
+ </div>
70
+ );
71
+
72
+ export default Index;
73
+ ```
74
+
75
+ 接下来,添加测试用例,来保证你页面的链接能够正常工作。
76
+
77
+ ```ts title="tests/example.spec.ts"
78
+ import { test, expect } from '@playwright/test'
79
+
80
+ test('should navigate to the about page', async ({ page }) => {
81
+ // Start from the index page (the baseURL is set via the webServer in the playwright.config.ts)
82
+ await page.goto('http://localhost:8080/')
83
+ // Find an element with the text 'About' and click on it
84
+ await page.click('text=About')
85
+ // The new URL should be "/about" (baseURL is used there)
86
+ await expect(page).toHaveURL('http://localhost:8080/about')
87
+ // The new page should contain an h1 with "About"
88
+ await expect(page.locator('h1')).toContainText('About')
89
+ })
90
+ ```
91
+
92
+ ## 运行测试用例
93
+
94
+ Playwright 需要你的 Modern.js 服务器保持运行。我们推荐在生产环境产物下运行你的测试用例,你可以执行 `pnpm run build` 和 `pnpm run serve` 在本地模拟生产环境。
95
+
96
+ ```bash
97
+ info Starting production server...
98
+
99
+ > Local: http://localhost:8080/
100
+ > Network: http://10.94.59.30:8080/
101
+ ```
102
+
103
+ 当项目正常构建运行后,可以在另一个终端内执行 `npx playwright test`,运行 Playwright 用例:
104
+
105
+ ```bash
106
+ Running 3 tests using 3 workers
107
+ 3 passed (2.0s)
108
+
109
+ To open last HTML report run:
110
+
111
+ npx playwright show-report
112
+ ```
@@ -0,0 +1,100 @@
1
+ # Vitest
2
+
3
+ Vitest 是由 Vite 驱动的测试框架,和 React Testing Library 配合可以用于单元测试。
4
+
5
+ 在 Modern.js 中使用 Vitest 需要先安装依赖,可以执行以下命令:
6
+
7
+ import { PackageManagerTabs } from '@theme';
8
+
9
+ <PackageManagerTabs command={{
10
+ npm: "npm install -D vitest @vitejs/plugin-react jsdom @testing-library/react @testing-library/dom",
11
+ yarn: "yarn add -D vitest @vitejs/plugin-react jsdom @testing-library/react @testing-library/dom",
12
+ pnpm: "pnpm install -D vitest @vitejs/plugin-react jsdom @testing-library/react @testing-library/dom",
13
+ bun: "bun add -D vitest @vitejs/plugin-react jsdom @testing-library/react @testing-library/dom"
14
+ }} />
15
+
16
+ 接下来,你需要创建一个 Vitest 配置文件 `vitest.config.ts`,内容如下:
17
+
18
+ ```ts title="vitest.config.ts"
19
+ import { defineConfig } from 'vitest/config'
20
+ import react from '@vitejs/plugin-react'
21
+
22
+ export default defineConfig({
23
+ plugins: [react()],
24
+ test: {
25
+ environment: 'jsdom',
26
+ },
27
+ })
28
+ ```
29
+
30
+ 更多关于 Vitest 配置的信息,可以参考 [Vitest 配置文档](https://vitest.dev/config/#configuration)。
31
+
32
+ 你可以选择性的将 `vitest` 命令添加到 `package.json` 中:
33
+
34
+ ```json title="package.json"
35
+ {
36
+ "scripts": {
37
+ "test": "vitest"
38
+ }
39
+ }
40
+ ```
41
+
42
+ 运行该命令后,Vitest 会自动监听你的文件变化,并重新运行用例。
43
+
44
+ ## 创建单元测试
45
+
46
+ 首先,创建一个简单的页面用于测试:
47
+
48
+ ```tsx title="routes/page.tsx"
49
+ import { Link } from '@modern-js/runtime/router';
50
+
51
+ const Index = () => (
52
+ <div>
53
+ <h1>Home</h1>
54
+ <Link to="/about">About</Link>
55
+ </div>
56
+ );
57
+
58
+ export default Index;
59
+ ```
60
+
61
+ 添加测试用例,检测页面中是否有预期的文本:
62
+
63
+ ```tsx title="__tests__/page.test.tsx"
64
+ import { expect, test } from 'vitest';
65
+ import { render, screen } from '@testing-library/react';
66
+ import { BrowserRouter as Router } from '@modern-js/runtime/router';
67
+ import Page from '../routes/page';
68
+
69
+ test('Page', () => {
70
+ render(
71
+ <Router>
72
+ <Page />
73
+ </Router>,
74
+ );
75
+ expect(screen.getByRole('heading', { level: 1, name: 'Home' })).toBeDefined();
76
+ });
77
+ ```
78
+
79
+ 上述用例中,我们从 `@modern-js/runtime/router` 引入了 `<Router>` 组件,这是因为 React Router 在渲染部分路由相关组件时,必须要有对应的上下文。
80
+
81
+ :::note
82
+ 直接在 Modern.js 应用中运行时,`<Router>` 组件会自动注入。
83
+ :::
84
+
85
+ ## 运行测试用例
86
+
87
+ 执行上述 `test` 命令,运行测试用例:
88
+
89
+ ```bash
90
+ ✓ src/__tests__/page.test.tsx (1)
91
+ ✓ Page
92
+
93
+ Test Files 1 passed (1)
94
+ Tests 1 passed (1)
95
+ Start at 15:37:12
96
+ Duration 999ms (transform 119ms, setup 0ms, collect 365ms, tests 33ms, environment 421ms, prepare 44ms)
97
+
98
+
99
+ PASS Waiting for file changes...
100
+ ```
@@ -1,4 +1 @@
1
- [
2
- "entries",
3
- "builder"
4
- ]
1
+ ["entries", "builder"]