@modern-js/main-doc 2.0.0-beta.5 → 2.0.0-beta.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/en/docusaurus-plugin-content-docs/current/apis/app/hooks/src/index_.md +1 -1
  3. package/en/docusaurus-plugin-content-docs/current/apis/app/hooks/src/pages.md +1 -1
  4. package/en/docusaurus-plugin-content-docs/current/apis/app/hooks/src/routes.md +86 -0
  5. package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/core/use-module-apps.md +1 -1
  6. package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/router/router.md +176 -373
  7. package/en/docusaurus-plugin-content-docs/current/components/enable-bff.md +36 -0
  8. package/en/docusaurus-plugin-content-docs/current/components/global-proxy-config.md +74 -0
  9. package/en/docusaurus-plugin-content-docs/current/components/global-proxy.md +28 -0
  10. package/en/docusaurus-plugin-content-docs/current/components/router-legacy-tip.md +1 -0
  11. package/en/docusaurus-plugin-content-docs/current/configure/app/auto-load-plugin.md +62 -0
  12. package/en/docusaurus-plugin-content-docs/current/configure/app/dev/proxy.md +2 -72
  13. package/en/docusaurus-plugin-content-docs/current/configure/app/runtime/router.md +17 -2
  14. package/en/docusaurus-plugin-content-docs/current/configure/app/source/entries.md +0 -2
  15. package/en/docusaurus-plugin-content-docs/current/configure/app/tools/tailwindcss.md +16 -22
  16. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/_category_.json +8 -0
  17. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/bff-proxy.md +27 -0
  18. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/frameworks.md +150 -0
  19. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/function.md +222 -0
  20. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/index.md +20 -0
  21. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/type.md +43 -0
  22. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/code-split.md +77 -0
  23. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/compatibility.md +76 -0
  24. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/eslint.md +145 -0
  25. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/index.md +12 -0
  26. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/low-level.md +46 -0
  27. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/ssg.md +132 -0
  28. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/ssr.md +306 -0
  29. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/testing.md +46 -0
  30. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/web-server.md +57 -0
  31. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/alias.md +67 -0
  32. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/tailwindcss.md +30 -35
  33. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/data-fetch.md +400 -0
  34. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/env-vars.md +166 -0
  35. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/html.md +235 -0
  36. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/mock.md +78 -0
  37. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/proxy.md +60 -0
  38. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/routes.md +0 -2
  39. package/en/docusaurus-plugin-content-docs/current/guides/get-started/quick-start.md +2 -4
  40. package/package.json +4 -4
  41. package/zh/apis/app/hooks/src/index_.md +1 -1
  42. package/zh/apis/app/hooks/src/pages.md +1 -1
  43. package/zh/apis/app/hooks/src/routes.md +89 -0
  44. package/zh/apis/app/runtime/core/use-module-apps.md +1 -1
  45. package/zh/apis/app/runtime/router/router.md +170 -368
  46. package/zh/components/debug-app.md +1 -2
  47. package/zh/components/enable-bff.md +36 -0
  48. package/zh/components/global-proxy-config.md +70 -0
  49. package/zh/components/micro-master-manifest-config.md +15 -0
  50. package/zh/components/router-legacy-tip.md +1 -0
  51. package/zh/configure/app/auto-load-plugin.md +62 -0
  52. package/zh/configure/app/deploy/microFrontend.md +0 -10
  53. package/zh/configure/app/dev/proxy.md +2 -70
  54. package/zh/configure/app/runtime/master-app.md +2 -16
  55. package/zh/configure/app/runtime/router.md +17 -3
  56. package/zh/configure/app/source/entries.md +1 -3
  57. package/zh/configure/app/tools/_category_.json +1 -1
  58. package/zh/configure/app/tools/tailwindcss.md +16 -23
  59. package/zh/guides/advanced-features/bff/frameworks.md +2 -0
  60. package/zh/guides/advanced-features/bff/function.md +44 -24
  61. package/zh/guides/advanced-features/code-split.md +28 -20
  62. package/zh/guides/advanced-features/compatibility.md +24 -14
  63. package/zh/guides/advanced-features/ssg.md +5 -47
  64. package/zh/guides/advanced-features/ssr.md +1 -1
  65. package/zh/guides/advanced-features/testing.md +2 -2
  66. package/zh/guides/basic-features/alias.md +5 -5
  67. package/zh/guides/basic-features/css/tailwindcss.md +31 -35
  68. package/zh/guides/basic-features/data-fetch.md +7 -6
  69. package/zh/guides/basic-features/env-vars.md +2 -2
  70. package/zh/guides/basic-features/html.md +62 -137
  71. package/zh/guides/basic-features/mock.md +8 -9
  72. package/zh/guides/basic-features/proxy.md +2 -2
  73. package/zh/guides/basic-features/routes.md +37 -6
  74. package/zh/guides/get-started/quick-start.md +1 -2
  75. package/zh/guides/topic-detail/framework-plugin/implement.md +54 -6
  76. package/zh/guides/topic-detail/micro-frontend/c02-development.md +2 -2
  77. package/zh/guides/topic-detail/micro-frontend/c03-main-app.md +1 -1
  78. package/en/docusaurus-plugin-content-docs/current/configure/app/dev/with-master-app.md +0 -31
  79. package/zh/configure/app/dev/with-master-app.md +0 -32
@@ -0,0 +1,132 @@
1
+ ---
2
+ title: Static Site Generation
3
+ sidebar_position: 4
4
+ ---
5
+
6
+ Static Site Generation is a solution for rendering complete static web pages at build time based on data and templates.
7
+
8
+ First need to execute `pnpm run new` to enable the SSG features:
9
+
10
+ ```bash
11
+ ? 请选择你想要的操作 启用可选功能
12
+ ? 启用可选功能 启用「SSG」功能
13
+ ```
14
+
15
+ After execute script,register SSG plugin in `modern.config.ts`:
16
+
17
+ ```ts title="modern.config.ts"
18
+ import SSGPlugin from '@modern-js/plugin-ssg';
19
+ // https://modernjs.dev/docs/apis/app/config
20
+ export default defineConfig({
21
+ ...,
22
+ output: {
23
+ ...,
24
+ ssg: true,
25
+ },
26
+ plugins: [..., SSGPlugin()],
27
+ });
28
+ ```
29
+
30
+ SSG in **Conventional Routing** and **Self-control Routing** has different usage.
31
+
32
+ ### Conventional Routing
33
+
34
+ Modern.js generate routes based on the file structure under the entry, so the framework can collect complete routing information.
35
+
36
+ For example, the following is a project directory structure using conventional routing:
37
+
38
+ ```bash
39
+ .
40
+ ├── src
41
+ │   └── routes
42
+ │   ├── layout.tsx
43
+ │   ├── page.tsx
44
+ │   └── user
45
+ │   ├── layout.tsx
46
+ │   ├── page.tsx
47
+ │   └── profile
48
+ │   └── page.tsx
49
+ ```
50
+
51
+ The above file directory will generate the following three routes:
52
+
53
+ - `/`
54
+ - `/user`
55
+ - `/user/profile`
56
+
57
+ :::note
58
+ If you don't know the rules for routing, you can first check [routes](/docs/guides/basic-features/routes).
59
+ :::
60
+
61
+ add component to `src/routes/page.tsx`:
62
+
63
+ ```jsx title="src/routes/page.tsx"
64
+ export default () => {
65
+ return <div>Index Page</div>
66
+ }
67
+ ```
68
+
69
+ SSG is also render in Node.js. So we can enable SSR in developmenet env, expose code problems in advance and verify SSG rendering effect:
70
+
71
+ ```typescript title="modern.config.ts"
72
+ export default defineConfig({
73
+ server: {
74
+ ssr: process.env.NODE_ENV === 'development',
75
+ }
76
+ }
77
+ ```
78
+
79
+ Execute the `pnpm run dev` command in the project to view the `dist/` directory, and only generate an HTML file `main/index.html`.
80
+
81
+ Execute the `pnpm run build` command in the root path of the project. After the construction is completed, view the `dist/` directory, and generate `main/index.html`, `main/user/index.html` and `main/user/profile/index.html` three HTML files, the content corresponds to the above three routes.
82
+
83
+ Using **Conventional Routing**, each route will generate a HTML file. Looking at the `main/index.html`, we can find the text content containing the `Index Page`, which is exactly the effect of SSG.
84
+
85
+ After executing `pnpm run serve` to start the project, visit the page in the Network, view the document returned by the request. The document contains the complete page content rendered by the component.
86
+
87
+ ### Self-control Routing
88
+
89
+ **Self-controlled routing** is a custom routing through component code, which requires the application to run to obtain accurate routing information. Therefore, the SSG function cannot be used out of the box. At this time, the user needs to inform the Modern.js framework in advance which routes need to enable the SSG.
90
+
91
+ For example, there is the following code, which contains multiple routes. When setting `output.ssg` to `true`, only the entry route '/' will be rendered by default:
92
+
93
+ ```tsx title="src/App.tsx"
94
+ import { useRuntimeContext } from '@modern-js/runtime';
95
+ import { Routes, Route, BrowserRouter } from '@modern-js/runtime/router';
96
+ import { StaticRouter } from '@modern-js/runtime/router/server';
97
+
98
+ const Router = typeof window === 'undefined' ? StaticRouter : BrowserRouter;
99
+
100
+ export default () => {
101
+ const { context } = useRuntimeContext();
102
+ return (
103
+ <Router location={context.request.pathname}>
104
+ <Routes>
105
+ <Route index element={<div>index</div>} />
106
+ <Route path="about" element={<div>about</div>} />
107
+ </Routes>
108
+ </Router>
109
+ );
110
+ };
111
+ ```
112
+
113
+ If we want to enable the SSG of `/about` at the same time, we can configure the `output.ssg` to tell Modern.js to enable the SSG of the specified route.
114
+
115
+ ```typescript title="modern.config.ts"
116
+ export default defineConfig({
117
+ output: {
118
+ ssg: {
119
+ routes: ['/', '/about'],
120
+ },
121
+ },
122
+ })
123
+ ```
124
+
125
+ run `pnpm run build` and `pnpm run serve`,access `http://localhost:8080/about`. In the Preview view, you can see that the page has been rendered。
126
+
127
+ Looking at the bundle file, a new `main/about/index.html` file has been added in the `dist/` directory.
128
+
129
+ :::info
130
+ The above only introduces the single entry, more related content can be viewed [SSG API](/docs/configure/app/output/ssg)。
131
+ :::
132
+
@@ -0,0 +1,306 @@
1
+ ---
2
+ title: Server-side rendering
3
+ sidebar_position: 3
4
+ ---
5
+
6
+ In Modern.js, SSR also works out of the box. Developers do not need to write complex server level logic for SSR, nor do they need to care about the operation and maintenance of SSR, or create services. Modern.js have a comprehensive SSR degradation strategy to ensure that pages can run safely.
7
+
8
+ Enabling SSR is very easy, just set ['server.ssr'](/docs/configure/app/server/ssr) to `true`:
9
+
10
+ ```json
11
+ {
12
+ "server": {
13
+ "ssr": true
14
+ }
15
+ }
16
+ ```
17
+
18
+ ## SSR Data Fetch
19
+
20
+ Modern.js provides Data Loader, which is convenient for developers to fetch data under SSR and CSR. Each routing module, such as `layout.tsx` and `page.tsx`, can define its own Data Loader:
21
+
22
+ ```ts title="src/routes/page.tsx"
23
+ export const loader = () => {
24
+ return {
25
+ message: 'Hello World',
26
+ };
27
+ };
28
+ ```
29
+
30
+ in the component, the data returned by the `loader` function can be get data through the Hooks API:
31
+
32
+ ```tsx
33
+ export default () => {
34
+ const data = useLoaderData();
35
+ return <div>{data.message}</div>;
36
+ }
37
+ ```
38
+
39
+ Modern.js break the traditional SSR development model and provide users with a user-friendly SSR development experience.
40
+
41
+ And it provides elegant degradation processing. Once the SSR request fails, it will automatically downgrade and restart the request on the browser side.
42
+
43
+ However, developers still need to pay attention to the fallback of data, such as `null` values or data returns that do not as expect. Avoid React rendering errors or messy rendering results when SSR.
44
+
45
+ :::info
46
+ When using Data Loader, data fetching happens before rendering, Modern.js still supports fetching data when the component is rendered. See [Data Fetch](/docs/guides/basic-features/data-fetch)。
47
+ :::
48
+
49
+ ## Keep Rendering Consistent
50
+
51
+ In some businesses, it is usually necessary to display different UI displays according to the current operating container environment characteristics, such as [UA](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) information.
52
+
53
+ If the processing is not careful enough, the rendering results may do not meet the expectations at this time.
54
+
55
+ Here is an example to show the problem when SSR and CSR rendering are inconsistent, add the following code to the component:
56
+
57
+ ```tsx
58
+ {
59
+ typeof window !== 'undefined' ? (
60
+ <div>
61
+ browser content
62
+ </div>
63
+ ) : null;
64
+ }
65
+ ```
66
+
67
+ After starting the app, visit the page and will find that the browser console throws a warning message:
68
+
69
+ ```sh
70
+ Warning: Expected server HTML to contain a matching <div> in <div>.
71
+ ```
72
+
73
+ This is caused by the inconsistency between the rendering result and the SSR rendering result when React executes the hydrate logic on the client side. Although the page performs normally, in complex applications, it is likely to cause problems such as DOM hierarchy confusion and style confusion.
74
+
75
+ :::info
76
+ For hydrate logic, please refer to [here](https://reactjs.org/docs/react-dom.html#hydrate).
77
+ :::
78
+
79
+ Applications need to maintain the consistency of SSR and CSR rendering results. If there are inconsistencies, it means that this part of the content does not need to be rendered in SSR.
80
+
81
+ Modern.js provide [`<NoSSR>`](/docs/apis/app/runtime/core/use-runtime-context) for such content that does not need to be rendered in SSR:
82
+
83
+ ```ts
84
+ import { NoSSR } from '@modern-js/runtime/ssr';
85
+ ```
86
+
87
+ Outside of elements that do not require SSR, wrap with a `NoSSR` component:
88
+
89
+ ```tsx
90
+ <NoSSR>
91
+ <div>
92
+ client content
93
+ </div>
94
+ </NoSSR>
95
+ ```
96
+
97
+ After modifying the code, refresh page found that the previous Waring disappeared. Open the Network window of the browser developer tool to see that the returned HTML document does not contain the content of the `NoSSR` component package.
98
+
99
+ :::info
100
+ ['useRuntimeContext'](/docs/apis/app/runtime/core/use-runtime-context) can get complete request information, which can be used to ensure that the rendering results of SSR and CSR are consistent.
101
+ :::
102
+
103
+ ## Concerned Memory Leaks
104
+
105
+ :::warning
106
+ In the SSR, developers need to pay special attention to the problem of memory leaks. Even small memory leaks can affect services..
107
+ :::
108
+
109
+ In SSR, every request triggers the component rendering. So, you need to avoid defining any potentially growing global data, or subscribing to events globally, or creating streams that will not be destroyed.
110
+
111
+ For example, the following code, when using [redux-observable](https://redux-observable.js.org/), developers used to code like this:
112
+
113
+ ```tsx
114
+ import { createEpicMiddleware, combineEpics } from 'redux-observable';
115
+
116
+ const epicMiddleware = createEpicMiddleware();
117
+ const rootEpic = combineEpics();
118
+
119
+ export default function Test() {
120
+ epicMiddleware.run(rootEpic);
121
+ return <div>Hello Modern.js</div>;
122
+ }
123
+ ```
124
+
125
+ Create a Middleware instance `epicMiddleware` outside the component and call epicMiddleware.run inside the component.
126
+
127
+ On the browser side, this code does not cause any problems. But in SSR, the Middleware instance will never be destroyed. Every time the component is rendered and `rootEpic` is called, new event bindings are added internally, causing the entire object to continue to grow larger, which ultimately affects application performance.
128
+
129
+ Such problems in CSR are not easy to detect, so when switching from CSR to SSR, if you are not sure whether the application has such hidden dangers, you can press the application.
130
+
131
+ ## Crop SSR Data
132
+
133
+ In order to keep the data requested in the SSR phase, it can be used directly on the browser side, Modern.js inject the data and state that collected during the rendering process into the HTML.
134
+
135
+ As a result, CSR applications often have a large amount of interface data and the state of the components is not crop. If SSR is used directly, the rendered HTML size may be too large.
136
+
137
+ At this time, SSR not only cannot bring an improvement in the user experience, but may have the opposite effect.
138
+
139
+ Therefore, when using SSR, **developers need to do reasonable weight loss for the application**:
140
+
141
+ 1. Pay attention to the first screen, you can only request the data needed for the first screen in SSR, and render the rest on the browser side.
142
+ 2. Removes the data independent with render from the data returned by the interface.
143
+
144
+ ## Serverless Pre-render
145
+
146
+ Modern.js provide Serverless Pre-rendering(SPR) to improve SSR performance.
147
+
148
+ SPR uses pre-rendering and caching to provide the responsive performance of static Web for SSR pages. It allows SSR applications to have the responsiveness and stability of static Web pages, while keeping data dynamically updated.
149
+
150
+ Using SPR in the Modern.js is very simple, just add the `<PreRender>` component, and the page where the component is located will automatically open SPR.
151
+
152
+ This mock a component that uses the `useLoaderData` API, and the request in the Data Loader takes 2s.
153
+
154
+ ```jsx
155
+ import { useLoaderData } from '@modern-js/runtime/router';
156
+
157
+ export const loader = async () => {
158
+ await new Promise((resolve, reject) => {
159
+ setTimeout(() => {
160
+ resolve(null);
161
+ }, 2000);
162
+ });
163
+
164
+ return {
165
+ message: 'Hello Modern.js',
166
+ };
167
+ };
168
+
169
+ export default () => {
170
+ const data = useLoaderData();
171
+ return <div>{data?.message}</div>;
172
+ };
173
+ ```
174
+
175
+ After executing the `dev` command and opening the page, it is obvious that the page needs to wait 2s before returning.
176
+
177
+ The next is to use the `<PreRender>` component, which can be exported directly from `@modern-js/runtime/ssr `:
178
+
179
+ ```ts
180
+ import { PreRender } from '@modern-js/runtime/ssr';
181
+ ```
182
+
183
+ Use the `PreRender` component in the routing component and set the parameter `interval` to indicate that the expiration time of the rendering result is 5s:
184
+
185
+ ```tsx
186
+ <PreRender interval={5} />
187
+ ```
188
+
189
+ After modification, execute `pnpm run build && pnpm run serve` to start the application and open the page.
190
+
191
+ When open page for the first time, it is no different from the previous rendering, and there is also a 2s delay.
192
+
193
+ Refresh page, and the page opens instantly, but at this time, the page data has not changed due to the refresh, because the cache has not expired.
194
+
195
+ Wait 5s, refresh the page again, the data of the page is still unchanged. Refresh the page again The data changes, but the page still responds almost instantaneously.
196
+
197
+ This is because in the previous request, the SPR has asynchronously obtained the new rendering result in the background, and the page requested this time is the version that has been cached in the server.
198
+
199
+ It is conceivable that when `interval` is set to 1, users can have the responsive experience of a static page.
200
+
201
+ :::info
202
+ For more detail, see [`<PreRender>`](/docs/apis/app/runtime/ssr/pre-render)。
203
+ :::
204
+
205
+ ## Treeshaking
206
+
207
+ When SSR is enabled, Modern.js will use the same entry to build both the SSR Bundle and the CSR Bundle. Therefore, the Web API in the SSR Bundle, or the Node API in the CSR Bundle, can lead to runtime errors.
208
+
209
+ Web API into a component is usually to do some global listening, or to get browser-related data, such as:
210
+
211
+ ```tsx
212
+ document.addEventListener('load', () => {
213
+ console.log('document load');
214
+ });
215
+ const App = () => {
216
+ return <div>Hello World</div>
217
+ }
218
+ export default App;
219
+ ```
220
+
221
+ The Node API is introduced in the component file, usually because of the use of Data Loader, for example:
222
+
223
+ ```ts
224
+ import fse from 'fs-extra';
225
+ export const loader = () => {
226
+ const file = fse.readFileSync('./myfile');
227
+ return {
228
+ ...
229
+ };
230
+ };
231
+ ```
232
+
233
+ ### Use Environment Variables
234
+
235
+ For the first case, we can directly use Modern.js built-in environment variables `MODERN_TARGET` to remove useless code at build time:
236
+
237
+ ```ts
238
+ if (process.env.MODERN_TARGET === 'browser') {
239
+ document.addEventListener('load', () => {
240
+ console.log('document load');
241
+ });
242
+ }
243
+ ```
244
+
245
+ :::note
246
+ For more information, see [environment variables](/docs/guides/basic-features/env-vars).
247
+ :::
248
+
249
+ ### Use File Suffix
250
+
251
+ In the second case, the Treeshaking method does not guarantee that the code is completely separated. Modern.js also supports the packaging file of SSR Bundle and CSR Bundle products through the file suffixed with `.node.`.
252
+
253
+ For example, the import of `fs-extra` in the code, when it is directly referenced to the component, will cause the CSR to load an error. You can create `.ts` and `.node.ts` files of the same name as a layer of proxy:
254
+
255
+ ```ts title="compat.ts"
256
+ export { readFileSync } from 'fs-extra';
257
+ ```
258
+
259
+ ```ts title="compat.node.ts"
260
+ export const readFileSync: any = () => {};
261
+ ```
262
+
263
+ use `./compat` directly into the file. At this time, files with the `.node.ts` suffix will be used first in the SSR environment, and files with the `.ts` suffix will be used in the CSR environment.
264
+
265
+ ```ts title="App.tsx"
266
+ import { readFileSync } from './compat'
267
+
268
+ export const loader = () => {
269
+ const file = readFileSync('./myfile');
270
+ return {
271
+ ...
272
+ };
273
+ };
274
+ ```
275
+
276
+ ### Independent File
277
+
278
+ Both of the above methods will bring some burden to the developer. Modern.js based on [Nested Routing](/docs/guides/basic-features/routes) developed and designed [Data Fetch](/docs/guides/basic-features/data-fetch) to separate CSR and SSR code。
279
+
280
+ ## Remote Request
281
+
282
+ When initiating remote requests in SSR, developers sometimes use request tools. Some interfaces need to pass user cookies, which developers can get through the ['useRuntimeContext'](/docs/guides/basic-features/data-fetch#route-loader) API to achieve.
283
+
284
+ It should be noted, the request header of the HTML request is obtained, which may not be applicable to remote requests, so **must not** pass through all request headers.
285
+
286
+ In addition, some backend interfaces, or general gateways, will verify according to the information in the request header, and full pass-through is prone to various problems that are difficult to debug. It is recommended that **pass-through on demand**.
287
+
288
+ Be sure to filter the `host` field if you really need to pass through all request headers.
289
+
290
+ ## Stream SSR
291
+
292
+ Modern.js supports streaming rendering in React 18, the default rendering mode can be modified with the following configuration:
293
+
294
+ ```json
295
+ {
296
+ "server": {
297
+ "ssr": {
298
+ "mode": "stream"
299
+ }
300
+ }
301
+ }
302
+ ```
303
+
304
+ :::note
305
+ At present Modern.js built-in data fetch does not support streaming rendering. If app need it, developers can build it according to the demo of React Stream SSR.
306
+ :::
@@ -0,0 +1,46 @@
1
+ ---
2
+ sidebar_position: 10
3
+ title: Testing
4
+ ---
5
+
6
+ Modern.js inherits the testing capabilities of [Jest](https://jestjs.io/) by default.
7
+
8
+ First need to execute `pnpm run new` enable [unit test/integration test] features:
9
+
10
+ ```
11
+ ? 请选择你想要的操作: 启用可选功能
12
+ ? 启用可选功能: 启用「单元测试 / 集成测试」功能
13
+ ```
14
+
15
+ After executing the above command, the `"test": "modern test"` command will be automatically generated in package.json.
16
+
17
+ register plugin in `modern.config.ts`:
18
+
19
+ ```ts title="modern.config.ts"
20
+ import TestPlugin from '@modern-js/plugin-testing';
21
+ // https://modernjs.dev/docs/apis/app/config
22
+ export default defineConfig({
23
+ ...,
24
+ plugins: [..., TestPlugin()],
25
+ });
26
+ ```
27
+
28
+ ## Test file
29
+
30
+ Modern.js default recognized test file paths are: `<rootDir>/src/**/*.test.[jt]s?(x)` and `<rootDir>/tests/**/*.test.[jt]s?(x)`。
31
+
32
+ If you need to customize the test directory, you can configure it with [tools.jest](/docs/configure/app/tools/jest).
33
+
34
+ ## Usage
35
+
36
+ Modern.js test support [testing-library](https://testing-library.com/docs/). API can be imported from `@modern-js/runtime/testing`.
37
+
38
+ ```
39
+ import { render, screen } from '@modern-js/runtime/testing';
40
+ ```
41
+
42
+ Other Modern.js supported testing APIs can be found [here](/docs/apis/app/runtime/testing/cleanup)。
43
+
44
+ ## transform
45
+
46
+ Modern.js tests use [babel-jest](https://www.npmjs.com/package/babel-jest) for source code compilation by default. If you need to use [ts-jest](https://github.com/kulshekhar/ts-jest), you can configure it through [testing.transform](/docs/configure/app/testing/transformer).
@@ -0,0 +1,57 @@
1
+ ---
2
+ title: Custom Web Server
3
+ sidebar_position: 2
4
+ ---
5
+
6
+ Modern.js 作为以客户端为中心的开发框架,对服务端的定制能力较弱。而在有些开发场景下,需要定制特殊的服务端逻辑,例如用户鉴权、请求预处理、添加页面渲染骨架等。
7
+
8
+ 因此 Modern.js 提供了一种功能,让项目可以在给定的范围内扩展 Modern.js 内置的 Web Server,来实现相应的需求。
9
+
10
+ ## 创建自定义 Web Server
11
+
12
+ 在项目根目录执行 `pnpm run new` 命令,按照如下选择,开启「自定义 Web Serve」功能:
13
+
14
+ ```bash
15
+ ? 请选择你想要的操作 创建工程元素
16
+ ? 创建工程元素 新建「自定义 Web Server」源码目录
17
+ ```
18
+
19
+ 执行命令后,在 `modern.config.ts` 中注册 Server 插件:
20
+
21
+ ```ts title="modern.config.ts"
22
+ import ServerPlugin from '@modern-js/plugin-server';
23
+ // https://modernjs.dev/docs/apis/app/config
24
+ export default defineConfig({
25
+ ...,
26
+ plugins: [..., ServerPlugin()],
27
+ });
28
+ ```
29
+
30
+ 项目目录下会新建 `server/index.ts` 文件,自定义逻辑在这个文件中编写。
31
+
32
+ ## 使用 API 扩展 Web Server
33
+
34
+ Modern.js 提供了 **Hook** 与 **Middleware** 两类 API 来扩展 Web Server。
35
+
36
+ ### Hook
37
+
38
+ Hook 可以控制 Web Server 对请求处理的内置逻辑,非 BFF 请求会经过 Hook 的处理。
39
+
40
+ Hook 不可以使用运行时框架拓展。
41
+
42
+ 详细 API 可以查看 [Hook](/docs/apis/app/runtime/web-server/hook)。
43
+
44
+
45
+ ### Middleware
46
+
47
+ Middleware 可以为 Web Server 添加前置中间件,只有 SSR 请求会经过 Middleware 的处理。
48
+
49
+ Middleware 可以使用运行时框架拓展。
50
+
51
+ 详细 API 可以查看 [Hook](/docs/apis/app/runtime/web-server/middleware)。
52
+
53
+ ## 完全自定义的 Web Server
54
+
55
+ :::note
56
+ 敬请期待
57
+ :::
@@ -0,0 +1,67 @@
1
+ ---
2
+ title: Alias
3
+ sidebar_position: 8
4
+ ---
5
+
6
+ Modern.js allow aliases in JS and CSS,and the following aliases are built in:
7
+
8
+ ```js
9
+ {
10
+ '@': '<appDirectory>/src',
11
+ '@shared': '<appDirectory>/shared',
12
+ }
13
+ ```
14
+
15
+ :::info
16
+ When the optional features is enable, the generator will also add built-in aliases dynamically. For example, when BFF is enabled, the `@api` alias will be added by default.
17
+ :::
18
+
19
+ For example, import the modules from the `src/common/` directory in the `src/App.tsx` file:
20
+
21
+ ```bash
22
+ .
23
+ ├── common
24
+ │   ├── styles
25
+ │   │   └── base.css
26
+ │   └── utils
27
+ │   └── index.ts
28
+ ├── App.tsx
29
+ ```
30
+
31
+ the code in `src/App.tsx`:
32
+
33
+ ```ts
34
+ import utils from '@/src/common/utils';
35
+ import '@/src/common/styles/base.css';
36
+ ```
37
+
38
+ Modern.js also provides a way to config aliases. Adding the `@common` alias as an example. For TypeScript projects, you only need to configure `compilerOptions.paths` under the project root directory `tsconfig.json` as follows:
39
+
40
+ ```json
41
+ {
42
+ "compilerOptions": {
43
+ "paths": {
44
+ "@/*": [
45
+ "./src/*"
46
+ ],
47
+ "@/common/*": [
48
+ "./src/common/*"
49
+ ]
50
+ }
51
+ },
52
+ }
53
+ ```
54
+
55
+ JavaScript project can config by [`source.alias`](/docs/configure/app/source/alias) in `modern.config.js`:
56
+
57
+ ```typescript title="modern.config.ts"
58
+ export default defineConfig({
59
+ source: {
60
+ alias: {
61
+ '@common': './src/common'
62
+ }
63
+ }
64
+ });
65
+ ```
66
+
67
+ for more detail, see 【[API - source.alias](/docs/configure/app/source/alias)】。