@modern-js/main-doc 2.35.1 → 2.36.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. package/docs/en/apis/app/hooks/src/routes.mdx +1 -1
  2. package/docs/en/components/debug-app.mdx +1 -1
  3. package/docs/en/components/turtorials-example-list.mdx +2 -0
  4. package/docs/en/configure/app/source/entries.mdx +7 -6
  5. package/docs/en/guides/advanced-features/bff/sdk.mdx +119 -0
  6. package/docs/en/guides/advanced-features/rspack-start.mdx +1 -1
  7. package/docs/en/guides/advanced-features/ssr.mdx +17 -17
  8. package/docs/en/guides/basic-features/data/_category_.json +4 -0
  9. package/docs/en/guides/basic-features/{data-fetch.mdx → data/data-fetch.mdx} +35 -27
  10. package/docs/en/guides/basic-features/data/data-write.mdx +241 -0
  11. package/docs/en/guides/basic-features/routes.mdx +7 -7
  12. package/docs/en/guides/concept/entries.mdx +31 -30
  13. package/docs/en/guides/get-started/quick-start.mdx +1 -1
  14. package/docs/en/guides/topic-detail/framework-plugin/extend.mdx +0 -1
  15. package/docs/en/guides/topic-detail/framework-plugin/hook-list.mdx +0 -1
  16. package/docs/en/guides/topic-detail/framework-plugin/hook.mdx +1 -1
  17. package/docs/en/guides/topic-detail/framework-plugin/implement.mdx +1 -2
  18. package/docs/en/guides/topic-detail/framework-plugin/introduction.mdx +1 -1
  19. package/docs/en/guides/topic-detail/framework-plugin/lifecycle.mdx +1 -1
  20. package/docs/en/guides/topic-detail/framework-plugin/plugin-api.mdx +31 -11
  21. package/docs/en/guides/topic-detail/framework-plugin/relationship.mdx +2 -2
  22. package/docs/en/guides/topic-detail/generator/new/config.md +0 -5
  23. package/docs/en/guides/topic-detail/micro-frontend/c03-main-app.mdx +2 -2
  24. package/docs/en/tutorials/first-app/c05-loader.mdx +2 -2
  25. package/docs/en/tutorials/first-app/c06-model.mdx +4 -4
  26. package/docs/en/tutorials/first-app/c07-container.mdx +3 -3
  27. package/docs/en/tutorials/foundations/introduction.mdx +3 -2
  28. package/docs/zh/apis/app/hooks/src/routes.mdx +1 -1
  29. package/docs/zh/components/debug-app.mdx +1 -1
  30. package/docs/zh/components/micro-runtime-config.mdx +2 -2
  31. package/docs/zh/components/turtorials-example-list.mdx +2 -0
  32. package/docs/zh/configure/app/source/entries.mdx +7 -6
  33. package/docs/zh/guides/advanced-features/bff/sdk.mdx +119 -0
  34. package/docs/zh/guides/advanced-features/rspack-start.mdx +1 -1
  35. package/docs/zh/guides/advanced-features/ssr.mdx +16 -16
  36. package/docs/zh/guides/basic-features/data/_category_.json +4 -0
  37. package/docs/zh/guides/basic-features/{data-fetch.mdx → data/data-fetch.md} +31 -27
  38. package/docs/zh/guides/basic-features/data/data-write.mdx +236 -0
  39. package/docs/zh/guides/basic-features/routes.mdx +7 -7
  40. package/docs/zh/guides/concept/entries.mdx +34 -32
  41. package/docs/zh/guides/get-started/quick-start.mdx +1 -1
  42. package/docs/zh/guides/topic-detail/framework-plugin/extend.mdx +0 -1
  43. package/docs/zh/guides/topic-detail/framework-plugin/hook-list.mdx +0 -1
  44. package/docs/zh/guides/topic-detail/framework-plugin/hook.mdx +1 -1
  45. package/docs/zh/guides/topic-detail/framework-plugin/implement.mdx +0 -1
  46. package/docs/zh/guides/topic-detail/framework-plugin/introduction.mdx +1 -1
  47. package/docs/zh/guides/topic-detail/framework-plugin/lifecycle.mdx +1 -1
  48. package/docs/zh/guides/topic-detail/framework-plugin/plugin-api.mdx +31 -11
  49. package/docs/zh/guides/topic-detail/framework-plugin/relationship.mdx +1 -1
  50. package/docs/zh/guides/topic-detail/generator/new/config.md +0 -5
  51. package/docs/zh/guides/topic-detail/micro-frontend/c03-main-app.mdx +2 -2
  52. package/docs/zh/guides/topic-detail/monorepo/create-sub-project.mdx +0 -14
  53. package/docs/zh/guides/topic-detail/monorepo/sub-project-interface.mdx +7 -43
  54. package/docs/zh/tutorials/first-app/c05-loader.mdx +2 -2
  55. package/docs/zh/tutorials/first-app/c06-model.mdx +3 -3
  56. package/docs/zh/tutorials/first-app/c07-container.mdx +3 -3
  57. package/docs/zh/tutorials/foundations/introduction.mdx +3 -2
  58. package/package.json +7 -7
@@ -0,0 +1,241 @@
1
+ ---
2
+ title: Data writing
3
+ sidebar_position: 4
4
+ ---
5
+
6
+ # Data writing
7
+
8
+ In the Data Loader chapter, the way Modern.js fetch data is introduced. You may encounter two problems.:
9
+ 1. How to update the data in Data Loader?
10
+ 2. How to write new data to the server?
11
+
12
+ EdenX's solution for this is DataAction.
13
+
14
+ ## Basic Example
15
+
16
+ Data Action, like Data Loader, is also based on convention routing. Through Modern.js's [nested routing](/guides/basic-features/routes#routing-file-convention), each routing component (`layout.ts`, `page.ts` or `$.tsx`) can have a `data` file with the same name, and a function named `action` can be exported in the `data` file.
17
+ ```bash
18
+ .
19
+ └── routes
20
+ └── user
21
+ ├── layout.tsx
22
+ └── layout.data.ts
23
+ ```
24
+ Define the following code in the file:
25
+ ```ts title="routes/user/layout.data.ts"
26
+ import type { ActionFunction } from '@modern-js/runtime/router';
27
+
28
+ export const action: ActionFunction = ({ request }) => {
29
+ const newUser = await request.json();
30
+ const name = newUser.name;
31
+ return updateUserProfile(name);
32
+ }
33
+ ```
34
+
35
+ ```tsx title="routes/user/layout.tsx"
36
+ import {
37
+ useFetcher,
38
+ useLoaderData,
39
+ useParams,
40
+ Outlet
41
+ } from '@modern-js/runtime/router';
42
+
43
+ export default () => {
44
+ const userInfo = useLoaderData();
45
+ const { submit } = useFetcher();
46
+ const editUser = () => {
47
+ const newUser = {
48
+ name: 'Modern.js'
49
+ }
50
+ return submit(newUser, {
51
+ method: 'post',
52
+ encType: 'application/json',
53
+ })
54
+ }
55
+ return (
56
+ <div>
57
+ <button onClick={editUser}>edit user</button>
58
+ <div className="user-profile">
59
+ {userInfo}
60
+ </div>
61
+ <Outlet context={userInfo}></Outlet>
62
+ </div>
63
+ )
64
+ }
65
+ ```
66
+
67
+ Here, when the submit is executed, the defined action function will be triggered; in the action function, the submitted data can be obtained through request (request.json, request.formData, etc.), and the data can be obtained, and then the data can be sent to the server.
68
+
69
+ After the action function is executed, the loader function code will be executed and the corresponding data and views will be updated.
70
+
71
+ ![action flow](https://lf3-static.bytednsdoc.com/obj/eden-cn/ulkl/ljhwZthlaukjlkulzlp/action-flow.png)
72
+
73
+
74
+
75
+ ## Why provide Data Action?
76
+
77
+ Data Action is mainly provided in Modern.js to keep the state of the UI and the server in sync, which can reduce the burden of state management.
78
+
79
+ The traditional state management method will hold the state on the client side and remotely respectively::
80
+
81
+ ![traditional state manage](https://lf3-static.bytednsdoc.com/obj/eden-cn/ulkl/ljhwZthlaukjlkulzlp/action-state-manage.png)
82
+
83
+ In Modern.js, we hope to help developers automatically synchronize the state of the client and server through Loader and Action::
84
+
85
+ ![state manage](https://lf3-static.bytednsdoc.com/obj/eden-cn/ulkl/ljhwZthlaukjlkulzlp/action-state-manage1.png)
86
+
87
+ If the data shared by the components in the project are the state of the main server, there is no need to introduce a client state management library in the project, request data through Data Loader, through [`useRouteLoaderData`](/guides/basic-fe Atures/data/data-fetch.md) shares data in subcomponents,
88
+
89
+ Modify and synchronize the state of the server through Data Action.
90
+
91
+
92
+
93
+ ## `action` function
94
+
95
+ Like the `loader` function, the `action` function has two parameters, `params` and `request`:
96
+
97
+ ### `params`
98
+
99
+ When the routing file passes through `[]`, it will be used as [dynamic routing](/guides/basic-features/routes#dynamic routing), and the dynamic routing fragment will be passed into the `action` function as a parameter::
100
+
101
+ ```tsx
102
+ // routes/user/[id]/page.data.ts
103
+ import { ActionFunctionArgs } from '@modern-js/runtime/router';
104
+
105
+ export const action = async ({ params }: ActionFunctionArgs) => {
106
+ const { id } = params;
107
+ const res = await fetch(`https://api/user/${id}`);
108
+ return res.json();
109
+ };
110
+ ```
111
+
112
+ When accessing `/user/123`, the parameter of the `action` function is `{ params: { id: '123' } }`.
113
+
114
+
115
+ ### `request`
116
+
117
+ Through `request`, you can fetch data submitted by the client in the action function, such as `request.json()`, `request.formData()`, `request.json()`, etc.
118
+
119
+ For the specific API, please refer to [data type] (#data-type).
120
+
121
+ ```tsx
122
+ // routes/user/[id]/page.data.ts
123
+ import { ActionFunctionArgs } from '@modern-js/runtime/router';
124
+
125
+ export const action = async ({ request }: ActionFunctionArgs) => {
126
+ const newUser = await request.json();
127
+ return updateUser(newUser);
128
+ };
129
+ ```
130
+
131
+ ### Return Value
132
+
133
+ The return value of the `action` function can be any serializable value or a [Fetch Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) instance,
134
+
135
+ The data in the response can be accessed through [`useActionData`](https://reactrouter.com/en/main/hooks/use-action-data).
136
+
137
+
138
+ ## useSubmit 和 useFetcher
139
+
140
+ ### Differences
141
+
142
+ You can use [`useSubmit`](https://reactrouter.com/en/main/hooks/use-submit) or [`useFetcher`](https://reactrouter.com/en/main/hooks/use-fetcher) calls action, and the difference between them is through
143
+
144
+ `useSubmit` calls action, which will trigger the browser's navigation, and `useFetcher` will not trigger the browser's navigation.
145
+
146
+ useSubmit:
147
+
148
+ ```ts
149
+ const submit = useSubmit();
150
+ submit(null, { method: "post", action: "/logout" });
151
+ ```
152
+
153
+ useFetcher:
154
+ ```ts
155
+ const { submit } = useFetcher();
156
+ submit(null, { method: "post", action: "/logout" });
157
+ ```
158
+
159
+ The `submit` function has two input parameters, `method` and `action`. `method` is equivalent to `method` at the time of form submission. In most scenarios where data is written,the `method` can be passed into `post`.
160
+
161
+ `action` is used to specify which routing component `action` is triggered. If the `action` parameter is not passed in, the action of the current routing component will be triggered by default, that is,
162
+ the execution of submit in the `user/page.tsx` component or subcomponent will trigger the action defined in `user/page.data.ts`.
163
+
164
+
165
+ :::info
166
+ For more information about these two APIs, please refer to the relevant documents:
167
+ - [`useSubmit`](https://reactrouter.com/en/main/hooks/use-submit)
168
+ - [`useFetcher`](https://reactrouter.com/en/main/hooks/use-fetcher)
169
+
170
+ :::
171
+
172
+
173
+ ### Type of data
174
+
175
+ The first parameter of the `submit` function can accept different types of values.
176
+ Such as `FormData`:
177
+ ```ts
178
+ let formData = new FormData();
179
+ formData.append("cheese", "gouda");
180
+ submit(formData);
181
+ // In the action, you can get the data by request.json
182
+ ```
183
+
184
+ Or the value of type `URLSearchParams`:
185
+ ```ts
186
+ let searchParams = new URLSearchParams();
187
+ searchParams.append("cheese", "gouda");
188
+ submit(searchParams);
189
+ // In the action, you can get the data by request.json
190
+ ```
191
+
192
+ Or any acceptable value of the `URLSearchParams` constructor:
193
+ ```ts
194
+ submit("cheese=gouda&toasted=yes");
195
+ submit([
196
+ ["cheese", "gouda"],
197
+ ["toasted", "yes"],
198
+ ]);
199
+ // In the action, you can get the data by request.json
200
+ ```
201
+
202
+ By default, if the first parameter in the `submit` function is an object, the corresponding data will be encoded as `formData`:
203
+
204
+ ```ts
205
+ submit(
206
+ { key: "value" },
207
+ {
208
+ method: "post",
209
+ encType: "application/x-www-form-urlencoded",
210
+ }
211
+ );
212
+
213
+ // In the action, you can get the data by request.formData
214
+ ```
215
+
216
+ it can also be specified as json encoding:
217
+
218
+ ```tsx
219
+ submit(
220
+ { key: "value" },
221
+ { method: "post", encType: "application/json" }
222
+ );
223
+
224
+ submit('{"key":"value"}', {
225
+ method: "post",
226
+ encType: "application/json",
227
+ });
228
+
229
+ // In the action, you can get the data by request.json
230
+ ```
231
+
232
+ or submit plain text:
233
+ ```ts
234
+ submit("value", { method: "post", encType: "text/plain" });
235
+ // In the action, you can get the data by request.text
236
+ ```
237
+
238
+
239
+ ## CSR 和 SSR
240
+
241
+ Like Data Loader, in the SSR project, Data Action is executed on the server (the framework will automatically send a request to trigger Data Action), while in the CSR project, Data Action is executed on the client.
@@ -161,7 +161,7 @@ These properties as defined are available via the [`useMatches`](https://reactro
161
161
 
162
162
  ```ts title="routes/layout.ts"
163
163
  export default () => {
164
- const matches = useMatches;
164
+ const matches = useMatches();
165
165
  const breadcrumbs = matches.map(
166
166
  matchedRoute => matchedRoute?.handle?.breadcrumbName,
167
167
  );
@@ -186,7 +186,7 @@ The `routes/[id]/page.tsx` file will be converted to the `/:id` route. Except fo
186
186
 
187
187
  In the component, you can use [useParams](/apis/app/runtime/router/router#useparams) to get the corresponding named parameter.
188
188
 
189
- In the loader, params will be passed as the input parameter of the [loader function](/guides/basic-features/data-fetch#loader-function), and you can get the parameter value through `params.xxx`.
189
+ In the loader, params will be passed as the input parameter of the [loader function](/guides/basic-features/data/data-fetch#loader-function), and you can get the parameter value through `params.xxx`.
190
190
 
191
191
  ### Dynamic Optional Routing
192
192
 
@@ -206,7 +206,7 @@ The `routes/user/[id$]/page.tsx` file will be converted to the `/user/:id?` rout
206
206
 
207
207
  In the component, you can use [useParams](/apis/app/runtime/router/router#useparams) to get the corresponding named parameter.
208
208
 
209
- In the loader, params will be passed as the input parameter of the [loader function](/guides/basic-features/data-fetch#loader-function), and you can get the parameter value through `params.xxx`.
209
+ In the loader, params will be passed as the input parameter of the [loader function](/guides/basic-features/data/data-fetch#loader-function), and you can get the parameter value through `params.xxx`.
210
210
 
211
211
  ### Catch-all Routing
212
212
 
@@ -351,12 +351,12 @@ Similarly, when the route jumps from `/` or `/blog` to `/blog/123`, if the JS Ch
351
351
 
352
352
  ### Redirect
353
353
 
354
- You can use a [Data Loader](/guides/basic-features/data-fetch) file to redirect a route. For example, if you have a `routes/user/page.tsx` file and want to redirect the corresponding route, you can create a `routes/user/page.loader.ts` file:
354
+ You can use a [Data Loader](/guides/basic-features/data/data-fetch) file to redirect a route. For example, if you have a `routes/user/page.tsx` file and want to redirect the corresponding route, you can create a `routes/user/page.data.ts` file:
355
355
 
356
- ```ts title="routes/user/page.loader.ts"
356
+ ```ts title="routes/user/page.data.ts"
357
357
  import { redirect } from '@modern-js/runtime/router';
358
358
 
359
- export default () => {
359
+ export const loader = () => {
360
360
  const user = await getUser();
361
361
  if (!user) {
362
362
  return redirect('/login');
@@ -502,7 +502,7 @@ To further improve the user experience and reduce loading time, Modern.js suppor
502
502
  :::info
503
503
 
504
504
  - This feature is currently only supported in Webpack projects and not yet supported in Rspack projects.
505
- - Preloading data currently only preloads the data returned by the [Data Loader](/guides/basic-features/data-fetch) in SSR projects.
505
+ - Preloading data currently only preloads the data returned by the [Data Loader](/guides/basic-features/data/data-fetch) in SSR projects.
506
506
 
507
507
  :::
508
508
 
@@ -32,7 +32,7 @@ The project initialized by Modern.js is a single entry (SPA) project, with the f
32
32
 
33
33
  In a Modern.js project, you can easily switch from single entry to multiple entries by running `pnpm run new` in the project directory and creating an entry:
34
34
 
35
- ```bash
35
+ ```text
36
36
  ? Please select the operation you want: Create Element
37
37
  ? Please select the type of element to create: New "entry"
38
38
  ? Please fill in the entry name: new-entry
@@ -56,7 +56,7 @@ After running the command, Modern.js will automatically generate a new entry dir
56
56
 
57
57
  The original entry code has been moved to a directory with the same name as the `name` field in `package.json`, and a `new-entry` entry directory has been created.
58
58
 
59
- After running `pnpm run dev`, you can see a new route named `/new-entry` has been added, and the migrated code route has not changed.
59
+ You can run `pnpm run dev` to start the development server. At this point, you will see a new route named `/new-entry` added, and the existing page routes remain unchanged.
60
60
 
61
61
  :::tip
62
62
  Modern.js will use the entry with the same name as the `name` field in `package.json` as the main entry. The route of the main entry is `/`, and the route of other entries is `/{entryName}`.
@@ -76,7 +76,9 @@ import EntryMode from '@site-docs-en/components/entry-mode.mdx';
76
76
  By default, Modern.js scans the files under `src/` before starting the project, identifies the entry, and generates the corresponding server-side route.
77
77
 
78
78
  :::tip
79
- You can modify the directory for entry identification by using the [source.entriesDir](/configure/app/source/entries-dir) config.
79
+
80
+ - You can custom the recognition directory for page entries by using [source.entriesDir](/configure/app/source/entries-dir).
81
+ - If you need to customize the entry points, please refer to [Custom Entries](#custom-entries).
80
82
 
81
83
  :::
82
84
 
@@ -98,7 +100,7 @@ When the project is not a single entry application, Modern.js will further look
98
100
 
99
101
  ### Framework Mode Entry
100
102
 
101
- Framework mode refers to the need to use Modern.js framework capabilities, such as Router, SSR, integrated calls, etc. Under this type of entry convention, the entry defined by the developer is not a real webpack compilation entry. Modern.js will generate a wrapped entry during startup, and you can find the real entry in `node_modules/.modern/{entryName}/index.js`.
103
+ The framework mode refers to the need to use the framework capabilities of Modern.js, such as nested routing, SSR, and integrated BFF, etc. Under this kind of entry convention, the entry defined by the developer is not the actual compilation entry. When Modern.js is launched, it generates a wrapped entry, and the real entry can be found at `node_modules/.modern/[entryName]/index.js`.
102
104
 
103
105
  #### Conventional Routing
104
106
 
@@ -146,7 +148,7 @@ export default (App: React.ComponentType, bootstrap: () => void) => {
146
148
  // do something before bootstrap...
147
149
  initSomething().then(() => {
148
150
  bootstrap();
149
- })
151
+ });
150
152
  };
151
153
  ```
152
154
 
@@ -181,9 +183,11 @@ export default AppWrapper;
181
183
 
182
184
  ### Build Mode Entry
183
185
 
184
- Build mode refers to not using any Modern.js runtime capabilities and completely defining the project's webpack entry by the developer.
186
+ Build mode refers to the mode where the entry point of the page is not automatically generated by Modern.js, but is fully defined by the developers themselves.
187
+
188
+ When there is an `index.[jt]sx` file in the entry directory and it is not exported as a function using `export default`, this type of file will be recognized as the entry module for webpack or Rspack.
185
189
 
186
- If there is an `index.[jt]sx` file in the entry and it does not export a default function, then this file is the real webpack entry file. Similar to [Create React App](https://github.com/facebook/create-react-app), you need to mount the component to the DOM node by yourself, add hot update code, etc. For example:
190
+ In this case, Modern.js will not generate the entry code automatically. Therefore, you need to manually mount the component to the DOM node, for example:
187
191
 
188
192
  ```js title=src/index.jsx
189
193
  import React from 'react';
@@ -193,42 +197,39 @@ import App from './App';
193
197
  ReactDOM.render(<App />, document.getElementById('root'));
194
198
  ```
195
199
 
196
- Modern.js **does not recommend** using this method for new projects, as it loses some of the framework's capabilities, such as the `runtime` configuration in the `modern.config.js` file will no longer take effect. However, this method can be very useful when migrating projects from other frameworks to Modern.js, such as CRA, or manually building webpack.
200
+ This approach is equivalent to enabling the [source.entries.disableMount](/configure/app/source/entries) option in Modern.js. When you use this approach, **you will not be able to use the runtime capabilities of the Modern.js framework**, such as the `runtime` configuration in the modern.config.js file will no longer take effect.
197
201
 
198
- ## Specifying Entry Using Configuration
202
+ ## Custom Entries
199
203
 
200
- Most existing projects are not built according to the directory structure of Modern.js. If you want to change to the directory structure of Modern.js, there will be certain migration costs.
204
+ In some cases, you may need to customize the entry configuration instead of using the entry conventions provided by Modern.js.
201
205
 
202
- In this case, in addition to using file conventions to generate entries, you can manually configure the entry in `modern.config.[jt]s`.
206
+ For example, if you want to migrate a non-Modern.js project to Modern.js and it is not structured according to Modern.js directory structure, there might be some migration costs involved in changing it to the conventional structure. In such cases, you can custom the entries.
203
207
 
204
- ```ts title="modern.config.ts"
205
- export default defineConfig({
206
- source: {
207
- entries: {
208
- // Specify a new entry named entry_customize
209
- entry_customize: './src/home/test/index.ts',
210
- },
211
- // Disable default ingress scanning
212
- disableDefaultEntries: true,
213
- },
214
- });
215
- ```
208
+ Modern.js provides the following configuration options that you can set in [modern.config.ts](/configure/app/usage):
216
209
 
217
- ### Disable Default Entry Scanning
210
+ - [source.entries](/configure/app/source/entries): Used to set custom entry objects.
211
+ - [source.disableDefaultEntries](/configure/app/source/disable-default-entries): Used to disable Modern.js's default entry scanning behavior. When you use custom entries, parts of your project structure might coincidentally match the Modern.js conventional directory structure, but you may not want Modern.js to generate entry configurations for them. Enabling this option can help avoid this issue.
218
212
 
219
- When using custom entries, part of the project structure may coincidentally hit the directory conventions of Modern.js, but in fact, this part of the directory is not the real entry.
213
+ ### Example
220
214
 
221
- Modern.js provides the `disableDefaultEntries` configuration to disable the default entry scanning rules. When you need to customize the entry, you generally need to use `disableDefaultEntries` in combination with `entries`. This way, some existing projects can be quickly migrated without modifying the directory structure.
215
+ Here is an example of a custom entry point. You can also refer to the documentation of the corresponding configuration options for more usage.
222
216
 
223
217
  ```ts title="modern.config.ts"
224
218
  export default defineConfig({
225
219
  source: {
220
+ entries: {
221
+ // Specify an entry named 'my-entry'
222
+ 'my-entry': {
223
+ // Path to the entry module
224
+ entry: './src/my-page/index.tsx',
225
+ // Disable automatic generation of entry code by Modern.js
226
+ disableMount: true,
227
+ },
228
+ },
229
+ // Disable entry scanning behavior
226
230
  disableDefaultEntries: true,
227
231
  },
228
232
  });
229
233
  ```
230
234
 
231
- :::tip
232
- For detailed usage, please refer to [source.entries](/configure/app/source/entries) and [source.disableDefaultEntries](/configure/app/source/disable-default-entries).
233
-
234
- :::
235
+ Note that when you enable `disableMount`, **you won't be able to use the runtime capabilities of the Modern.js framework**, such as the `runtime` configuration in the modern.config.ts file.
@@ -92,7 +92,7 @@ $ pnpm run build
92
92
  > modern build
93
93
 
94
94
  info Staring production build...
95
- ready Client compiled in 50ms
95
+ ready Client compiled in 50 ms
96
96
  info Production file sizes:
97
97
 
98
98
  File Size Gzipped
@@ -1,5 +1,4 @@
1
1
  ---
2
- title: Extending
3
2
  sidebar_position: 5
4
3
  ---
5
4
 
@@ -1,5 +1,4 @@
1
1
  ---
2
- title: Hook List
3
2
  sidebar_position: 8
4
3
  ---
5
4
 
@@ -1,7 +1,7 @@
1
1
  ---
2
- title: Hook Model
3
2
  sidebar_position: 2
4
3
  ---
4
+
5
5
  # Hook Model
6
6
 
7
7
  First, let's introduce some content about the basic plugin system in Modern.js, including the working mode of the Hook model, the operating mode of each Hook model, and the working mode of the Manager.
@@ -1,9 +1,8 @@
1
1
  ---
2
- title: Develop Plugins
3
2
  sidebar_position: 3
4
3
  ---
5
4
 
6
- # How to Develop Plugins
5
+ # Develop Plugins
7
6
 
8
7
  The previous section introduced the Hook models used by Modern.js plugins, while this section describes how to develop plugins.
9
8
 
@@ -1,7 +1,7 @@
1
1
  ---
2
- title: Introduction
3
2
  sidebar_position: 1
4
3
  ---
4
+
5
5
  # Introduction
6
6
 
7
7
  ## Modern.js Plugin System
@@ -1,7 +1,7 @@
1
1
  ---
2
- title: Lifecycle
3
2
  sidebar_position: 1
4
3
  ---
4
+
5
5
  # Lifecycle
6
6
 
7
7
  Modern.js application has a complete lifecycle, including CLI, Server Side and Runtime three stages.
@@ -1,5 +1,4 @@
1
1
  ---
2
- title: Plugin API
3
2
  sidebar_position: 6
4
3
  ---
5
4
 
@@ -79,26 +78,43 @@ Used to retrieve the runtime context of the application.
79
78
  const useAppContext: () => IAppContext;
80
79
 
81
80
  interface IAppContext {
81
+ /** Root directory of the current project */
82
82
  appDirectory: string;
83
+ /** Source code directory */
84
+ srcDirectory: string;
85
+ /** Directory for output files */
86
+ distDirectory: string;
87
+ /** Directory for shared modules */
88
+ sharedDirectory: string;
89
+ /** Directory for framework temp files */
90
+ internalDirectory: string;
91
+ /** node_modules directory */
92
+ nodeModulesDirectory: string;
93
+ /** Path to the configuration file */
83
94
  configFile: string | false;
95
+ /** IPv4 address of the current machine */
84
96
  ip?: string;
97
+ /** Port number of the development server */
85
98
  port?: number;
86
- distDirectory: string;
99
+ /** Name of the current project's package.json */
87
100
  packageName: string;
88
- srcDirectory: string;
89
- sharedDirectory: string;
90
- nodeModulesDirectory: string;
91
- internalDirectory: string;
92
- plugins: {
93
- cli?: any;
94
- server?: any;
95
- }[];
101
+ /** Currently registered plugins */
102
+ plugins: any[];
103
+ /** Information for entry points */
96
104
  entrypoints: Entrypoint[];
105
+ /** Information for server routes */
97
106
  serverRoutes: ServerRoute[];
98
- htmlTemplates: HtmlTemplates;
107
+ /** Tools type of the current project */
108
+ toolsType?: 'app-tools' | 'module-tools' | 'monorepo-tools';
109
+ /** Type of the bundler being used */
110
+ bundlerType?: 'webpack' | 'rspack' | 'esbuild';
99
111
  }
100
112
  ```
101
113
 
114
+ :::tip
115
+ Some fields in the AppContext are dynamically set and will change as the program runs. Therefore, when plugins read these fields at different times, they may get different values.
116
+ :::
117
+
102
118
  ### useHookRunners
103
119
 
104
120
  Used to retrieve the executor of Hooks and trigger the execution of specific Hooks.
@@ -116,3 +132,7 @@ export const myPlugin = (): CliPlugin => ({
116
132
  },
117
133
  });
118
134
  ```
135
+
136
+ :::tip
137
+ Please avoid executing the built-in hooks, as it may break the internal execution logic of the framework.
138
+ :::
@@ -1,8 +1,8 @@
1
1
  ---
2
- title: Relationship
3
2
  sidebar_position: 4
4
3
  ---
5
- # Relationship between Plugins
4
+
5
+ # Relationship
6
6
 
7
7
  The plugin configuration object in Modern.js provides a series of fields to control plugin order, mutual exclusion, and other capabilities. The available fields are as follows:
8
8
 
@@ -129,13 +129,8 @@ Question: Please select the type of project you want to create.
129
129
  Options:
130
130
 
131
131
  - Web App -- mwa
132
-
133
- - Web App (Test)-- mwa_test
134
-
135
132
  - Npm Module -- module
136
133
 
137
- - Npm Module (Inner) -- inner_module
138
-
139
134
  ### packageName
140
135
 
141
136
  Question: Please fill in the project name
@@ -44,12 +44,12 @@ defineConfig(App, {
44
44
  return [
45
45
  {
46
46
  name: 'Table',
47
- entry: 'http://localhost:8001',
47
+ entry: 'http://localhost:8081',
48
48
  // activeWhen: '/table'
49
49
  },
50
50
  {
51
51
  name: 'Dashboard',
52
- entry: 'http://localhost:8002',
52
+ entry: 'http://localhost:8082',
53
53
  // activeWhen: '/dashboard'
54
54
  },
55
55
  ];
@@ -18,7 +18,7 @@ pnpm add faker@5
18
18
  pnpm add @types/faker@5 -D
19
19
  ```
20
20
 
21
- Create `src/routes/page.loader.ts`:
21
+ Create `src/routes/page.data.ts`:
22
22
 
23
23
  ```tsx
24
24
  import { name, internet } from 'faker';
@@ -32,7 +32,7 @@ type LoaderData = {
32
32
  }[];
33
33
  };
34
34
 
35
- export default async (): Promise<LoaderData> => {
35
+ export const loader = async (): Promise<LoaderData> => {
36
36
  const data = new Array(20).fill(0).map(() => {
37
37
  const firstName = name.firstName();
38
38
  return {
@@ -195,9 +195,9 @@ const Item = ({
195
195
  export default Item;
196
196
  ```
197
197
 
198
- Next, we add `src/routes.page.loader` and modify `src/routes/page.tsx` to pass more parameters to the `<Item>` component:
198
+ Next, we add `src/routes.page.data` and modify `src/routes/page.tsx` to pass more parameters to the `<Item>` component:
199
199
 
200
- ```tsx title="src/routes/page.loader.ts"
200
+ ```tsx title="src/routes/page.data.ts"
201
201
  export type LoaderData = {
202
202
  code: number;
203
203
  data: {
@@ -207,7 +207,7 @@ export type LoaderData = {
207
207
  }[];
208
208
  };
209
209
 
210
- export default async (): Promise<LoaderData> => {
210
+ export const loader = async (): Promise<LoaderData> => {
211
211
  const data = new Array(20).fill(0).map(() => {
212
212
  const firstName = name.firstName();
213
213
  return {
@@ -233,7 +233,7 @@ import { List } from 'antd';
233
233
  import { name, internet } from 'faker';
234
234
  import Item from '../components/Item';
235
235
  import contacts from '../models/contacts';
236
- import type { LoaderData } from './page.loader';
236
+ import type { LoaderData } from './page.data';
237
237
 
238
238
  function Index() {
239
239
  const { data } = useLoaderData() as LoaderData;