@modern-js/main-doc 2.0.1 → 2.0.3-alpha.0
Sign up to get free protection for your applications and to get access to all the features.
- package/.turbo/turbo-build.log +1 -1
- package/en/docusaurus-plugin-content-docs/current/apis/app/runtime/model/Provider.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/components/debug-app.md +17 -0
- package/en/docusaurus-plugin-content-docs/current/components/enable-bff.md +6 -6
- package/en/docusaurus-plugin-content-docs/current/components/prerequisites.md +19 -0
- package/en/docusaurus-plugin-content-docs/current/configure/app/runtime/router.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/less-sass.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/tailwindcss.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/guides/get-started/quick-start.md +1 -1
- package/en/docusaurus-plugin-content-docs/current/tutorials/first-app/c01-start.md +17 -17
- package/en/docusaurus-plugin-content-docs/current/tutorials/first-app/c02-component.md +11 -11
- package/en/docusaurus-plugin-content-docs/current/tutorials/first-app/c03-css.md +48 -49
- package/en/docusaurus-plugin-content-docs/current/tutorials/first-app/c04-routes.md +22 -22
- package/en/docusaurus-plugin-content-docs/current/tutorials/first-app/c05-loader.md +10 -10
- package/en/docusaurus-plugin-content-docs/current/tutorials/first-app/c06-model.md +28 -28
- package/en/docusaurus-plugin-content-docs/current/tutorials/first-app/c07-container.md +20 -21
- package/en/docusaurus-plugin-content-docs/current/tutorials/first-app/c08-entries.md +31 -32
- package/en/docusaurus-plugin-content-docs/current.json +3 -47
- package/package.json +4 -4
- package/zh/components/enable-bff.md +6 -6
- package/zh/configure/app/runtime/intro.md +27 -0
- package/zh/guides/basic-features/routes.md +84 -0
@@ -1,23 +1,23 @@
|
|
1
1
|
---
|
2
|
-
title:
|
2
|
+
title: Add Loader
|
3
3
|
---
|
4
4
|
|
5
|
-
|
5
|
+
In the previous chapter, we learned how to add client route.
|
6
6
|
|
7
|
-
|
7
|
+
In this chapter, we will learn how to add **Loader** to the routing component.
|
8
8
|
|
9
|
-
|
9
|
+
By far, we have provided data to components through hardcoding. If you want to get data from the remote, you usually use `useEffect` to do it. But when SSR is enabled, `useEffect` will not be executed at the server level, so this SSR can only render a very limited UI.
|
10
10
|
|
11
|
-
Modern.js
|
11
|
+
Modern.js provides the ability of Data Loader to support homogeneous data acquisition in components to maximize the value of SSR.
|
12
12
|
|
13
|
-
|
13
|
+
Below we demonstrate how to add Data Loader to the routing component and simulate remote data acquisition. We use faker to mock the required data, first install dependency:
|
14
14
|
|
15
15
|
```bash
|
16
16
|
pnpm add faker@5
|
17
17
|
pnpm add @types/faker@5 -D
|
18
18
|
```
|
19
19
|
|
20
|
-
|
20
|
+
Modify `src/routes/page.tsx`:
|
21
21
|
|
22
22
|
```tsx
|
23
23
|
import { name, internet } from 'faker';
|
@@ -49,10 +49,10 @@ export const loader = async (): Promise<LoaderData> => {
|
|
49
49
|
```
|
50
50
|
|
51
51
|
:::note
|
52
|
-
Data Loader
|
52
|
+
Data Loader doesn't just work for SSR. In CSR projects, Data Loader can also avoid data acquisition dependency UI rendering, which solves the problem of requesting dynamic grid layout. In the future, Modern.js will also add more capabilities to this feature, such as pre-fetching, data caching, etc.
|
53
53
|
:::
|
54
54
|
|
55
|
-
Modern.js
|
55
|
+
Modern.js also provides a hooks API called `useLoaderData`, we modify the exported component of `src/routes/page.tsx`:
|
56
56
|
|
57
57
|
```tsx {1,4,13}
|
58
58
|
import { useLoaderData } from '@modern-js/runtime/router';
|
@@ -77,6 +77,6 @@ export default Index;
|
|
77
77
|
```
|
78
78
|
|
79
79
|
<!-- Todo 重新截图,SSR 内容 -->
|
80
|
-
|
80
|
+
Re-execute `pnpm run dev`, view `view-source: http://localhost:8080/`, or view the "Preview" of the HTML request in the Network panel of devtools, you can see that the HTML rendered by SSR already contains the complete UI:
|
81
81
|
|
82
82
|

|
@@ -1,22 +1,22 @@
|
|
1
1
|
---
|
2
|
-
title:
|
2
|
+
title: Add Model
|
3
3
|
---
|
4
4
|
|
5
|
-
|
5
|
+
In the previous chapter, we changed the hardcoding `mockData` to load from Data Loader.
|
6
6
|
|
7
|
-
|
7
|
+
In this chapter, we will further implement the functions of the project, such as the implementation of the function of the **Archive** button to put the point of contact archive.
|
8
8
|
|
9
|
-
|
9
|
+
Therefore, we will start to write some business logic that has nothing to do with the UI at all. If we continue to write in the component code, more and more noodle code will be generated. To this end, we introduced a code module called **Model** to decoupling these business logic and UI.
|
10
10
|
|
11
|
-
:::info
|
12
|
-
|
11
|
+
:::info note
|
12
|
+
To use the Model API, you need to set runtime.state(/docs/configure/app/runtime/state) to enable the state management plugin.
|
13
13
|
:::
|
14
14
|
|
15
|
-
##
|
15
|
+
## Model implementation
|
16
16
|
|
17
|
-
|
17
|
+
To create a complete Model, you first need to define **state**, including the name and initial value of data in the state.
|
18
18
|
|
19
|
-
|
19
|
+
We use Model to manage the data of the point of contact list, so define the following data state:
|
20
20
|
|
21
21
|
```js
|
22
22
|
const state = {
|
@@ -24,9 +24,9 @@ const state = {
|
|
24
24
|
};
|
25
25
|
```
|
26
26
|
|
27
|
-
|
27
|
+
Using TS syntax, you can define more complete type information, such as items in each object should have a `name`, `email` field. In order to implement archive function, also need to create the `archived` field to hold the point of contact has been archived state.
|
28
28
|
|
29
|
-
|
29
|
+
We also need a field to access all archived points of contact. We can define a field of type **computed** to convert the existing data:
|
30
30
|
|
31
31
|
```js
|
32
32
|
const computed = {
|
@@ -36,13 +36,13 @@ const computed = {
|
|
36
36
|
};
|
37
37
|
```
|
38
38
|
|
39
|
-
`computed`
|
39
|
+
Fields of type `computed` are defined as function, but can be accessed through state just like normal fields.
|
40
40
|
|
41
41
|
:::info
|
42
|
-
Modern.js
|
42
|
+
Modern.js integrates [Immer](https://immerjs.github.io/immer/) and can write such state transfer logic just like normal mutable data in JS.
|
43
43
|
:::
|
44
44
|
|
45
|
-
|
45
|
+
When implementing the Archive button, we need an `archive` function, which is responsible for modifying the `archived` field of the specified contact. We call this function **action**:
|
46
46
|
|
47
47
|
```js
|
48
48
|
const actions = {
|
@@ -55,11 +55,11 @@ const actions = {
|
|
55
55
|
};
|
56
56
|
```
|
57
57
|
|
58
|
-
action
|
58
|
+
An action function is a pure function, where a defined input gets a defined output (a shifted state) and should not have any side effects.
|
59
59
|
|
60
|
-
|
60
|
+
The first parameter of the function is the Draft State provided by Immer, and the second parameter is the parameter passed in when the action is called (more on how to call it later).
|
61
61
|
|
62
|
-
|
62
|
+
We try to implement them completely:
|
63
63
|
|
64
64
|
```js
|
65
65
|
const state = {
|
@@ -84,14 +84,14 @@ const actions = {
|
|
84
84
|
};
|
85
85
|
```
|
86
86
|
|
87
|
-
|
87
|
+
Next we connect the above code and put it in the same Model file. First execute the following command to create a new file directory:
|
88
88
|
|
89
89
|
```bash
|
90
90
|
mkdir -p src/models/
|
91
91
|
touch src/models/contacts.ts
|
92
92
|
```
|
93
93
|
|
94
|
-
|
94
|
+
Add `src/models/contacts.ts`:
|
95
95
|
|
96
96
|
```tsx
|
97
97
|
import { model } from '@modern-js/runtime/model';
|
@@ -127,13 +127,13 @@ export default model<State>('contacts').define({
|
|
127
127
|
});
|
128
128
|
```
|
129
129
|
|
130
|
-
|
130
|
+
We call a plain object containing elements such as state, action, etc. as **Model Spec**, Modern.js provides [Model API](/docs/apis/app/runtime/model/model_), which can generate **Model** from Model Spec.
|
131
131
|
|
132
|
-
##
|
132
|
+
## Use Model
|
133
133
|
|
134
|
-
|
134
|
+
Now let's use this Model directly to complement the logic of the project.
|
135
135
|
|
136
|
-
|
136
|
+
First modify `src/components/Item/index.tsx` and add the UI and interaction of the **Archive button**, the content is as follows:
|
137
137
|
|
138
138
|
```tsx
|
139
139
|
import Avatar from '../Avatar';
|
@@ -181,7 +181,7 @@ const Item = ({
|
|
181
181
|
export default Item;
|
182
182
|
```
|
183
183
|
|
184
|
-
|
184
|
+
Next, we modify `src/routes/page.tsx` to pass more parameters to the `<Item>` component:
|
185
185
|
|
186
186
|
```tsx
|
187
187
|
import { Helmet } from '@modern-js/runtime/head';
|
@@ -249,12 +249,12 @@ function Index() {
|
|
249
249
|
export default Index;
|
250
250
|
```
|
251
251
|
|
252
|
-
`useModel`
|
252
|
+
`useModel` is the hooks API provided by the Modern.js. You can provide the state defined in the Model in the component, or call the side effects and actions defined in the Model through actions to change the state of the Model.
|
253
253
|
|
254
|
-
Model
|
254
|
+
Model is business logic, a computational process that does not create or hold state itself. Only after being used by the component with the hooks API, the state is created in the specified place.
|
255
255
|
|
256
|
-
|
256
|
+
Execute `pnpm run dev` and click the **Archive button** to see that the page UI has changed.
|
257
257
|
|
258
258
|
:::note
|
259
|
-
|
259
|
+
In the above example, `useLoaderData` is actually executed every time the route is switched. Because we used fake data in the Data Loader, the data returned each time is different. But we use the data in the Model first, so the data does not change when switching routes.
|
260
260
|
:::
|
@@ -1,19 +1,19 @@
|
|
1
1
|
---
|
2
|
-
title:
|
2
|
+
title: Add Container
|
3
3
|
---
|
4
4
|
|
5
5
|
import Tabs from '@theme/Tabs';
|
6
6
|
import TabItem from '@theme/TabItem';
|
7
7
|
|
8
|
-
|
8
|
+
In the previous chapter, we initially introduced the **model** to split this part of the logic from the UI component. The `page.tsx` no longer contains UI-independent business logic implementation details, and only needs to use the Model to implement the same function.
|
9
9
|
|
10
|
-
|
10
|
+
In this chapter, we will further use the business logic of implementation in Model to let `page.tsx` and `archived/page.tsx` get the same data. And implementation Archive button, click the button to display the point of contact archive only in the Archives list, not in the All list.
|
11
11
|
|
12
|
-
##
|
12
|
+
## Use the full Model
|
13
13
|
|
14
|
-
|
14
|
+
Because the two pages need to share the same set of state (point of contact tabular data, point of contact is archived or not), both need to contain the logic to load the initial data, so we need to complete the data acquisition at a higher level.
|
15
15
|
|
16
|
-
Modern.js
|
16
|
+
Modern.js support obtaining data through Data Loader in `layout.tsx`, we first move the data acquisition part of the code to `src/routes/layout.tsx`:
|
17
17
|
|
18
18
|
```tsx
|
19
19
|
import { name, internet } from 'faker';
|
@@ -69,7 +69,7 @@ export default function Layout() {
|
|
69
69
|
}
|
70
70
|
```
|
71
71
|
|
72
|
-
|
72
|
+
In `src/routes/page.tsx`, use Model directly to get data:
|
73
73
|
|
74
74
|
```tsx
|
75
75
|
import { Helmet } from '@modern-js/runtime/head';
|
@@ -105,7 +105,7 @@ function Index() {
|
|
105
105
|
export default Index;
|
106
106
|
```
|
107
107
|
|
108
|
-
|
108
|
+
Also in `archived/page.tsx`, delete the original `mockData` logic and use the `archived` value computed in Model as the data source:
|
109
109
|
|
110
110
|
```tsx
|
111
111
|
import { Helmet } from '@modern-js/runtime/head';
|
@@ -141,21 +141,21 @@ function Index() {
|
|
141
141
|
export default Index;
|
142
142
|
```
|
143
143
|
|
144
|
-
|
144
|
+
Execute `pnpm run dev`, visit `http://localhost:8080/`, click the Archive button, you can see the button grey out:
|
145
145
|
|
146
146
|

|
147
147
|
|
148
|
-
|
148
|
+
Next, click the top navigation and switch to the Archives list. You can find that the point of contact of **Archive** just now has appeared in the list:
|
149
149
|
|
150
150
|

|
151
151
|
|
152
|
-
##
|
152
|
+
## Withdraw container components
|
153
153
|
|
154
|
-
|
154
|
+
In the previous chapters, we split the business logic in the project into two layers, one is the **view component**, and the other is the **module**. The former is responsible for UI display, interaction, etc., and the latter is responsible for the implementation of UI-independent business logic, which specializes in managing state.
|
155
155
|
|
156
|
-
|
156
|
+
Like `src/routes/page.tsx` and `src/routes/archives/page.tsx` use the component of the `useModel` API, which is responsible for linking the two layers of View and Model, similar to the role of the Controller in the traditional MVC architecture. In the Modern.js, we follow the habit and call them **Container**.
|
157
157
|
|
158
|
-
|
158
|
+
The container component is recommended to be placed in a special `containers/` directory. We execute the following command to create a new file:
|
159
159
|
|
160
160
|
<Tabs>
|
161
161
|
<TabItem value="macOS" label="macOS" default>
|
@@ -176,7 +176,7 @@ ni src/containers/Contacts.tsx
|
|
176
176
|
</TabItem>
|
177
177
|
</Tabs>
|
178
178
|
|
179
|
-
|
179
|
+
We extracted the common part of the original two `page.tsx`, and the code of `src/containers/Contacts.tsx` is as follows:
|
180
180
|
|
181
181
|
```tsx
|
182
182
|
import { Helmet } from "@modern-js/runtime/head";
|
@@ -222,7 +222,7 @@ function Contacts({
|
|
222
222
|
export default Contacts;
|
223
223
|
```
|
224
224
|
|
225
|
-
|
225
|
+
Modify the code for `src/routes/page.tsx` and `src/routes/archives/page.tsx`:
|
226
226
|
|
227
227
|
```tsx title="src/routes/page.tsx"
|
228
228
|
import Contacts from '../containers/Contacts';
|
@@ -244,7 +244,7 @@ function Index() {
|
|
244
244
|
export default Index;
|
245
245
|
```
|
246
246
|
|
247
|
-
|
247
|
+
The refactoring is complete, and the current project structure is:
|
248
248
|
|
249
249
|
```md
|
250
250
|
.
|
@@ -275,9 +275,8 @@ export default Index;
|
|
275
275
|
└── tsconfig.json
|
276
276
|
```
|
277
277
|
|
278
|
-
`components/`
|
278
|
+
The **view components** in `components/` dir are in the form of directories, such as `Avatar/index.tsx`. And the **container components** in `containers/` dir are in the form of single files, such as `contacts.tsx`. **This is a best practice we recommend**.
|
279
279
|
|
280
|
-
|
281
|
-
|
282
|
-
而容器组件只负责连接,是一个胶水层,复杂的业务逻辑和实现细节都交给 View 层和 Model 层去实现。容器组件自己应该保持简单清晰,不应该包含复杂实现细节,所以不应该有内部结构。采用单文件形式不但更简洁,也能起到约束作用,提醒开发者不要把容器组件写复杂。
|
280
|
+
As mentioned in the chapter [Add UI component](./c02-component.md), the view component is in the form of a directory, because the view component is responsible for the implementation of UI display and interaction details, and can evolve in complexity. In the form of a directory, it is convenient to add sub-files, including dedicated resources (pictures, etc.), dedicated sub-components, CSS files, etc. You can reconstruct at will within this directory, considering only the smallest parts.
|
283
281
|
|
282
|
+
The container component is only responsible for linkage and is a glue layer. The sophisticated business logic and implementation details are handed over to the View layer and the Model layer for implementation. The container component itself should be kept simple and clear, and should not contain complex implementation details, so there should be no internal structure. The single-file form is not only more concise, but also acts as a constraint, reminding developers not to write complicated container components.
|
@@ -1,24 +1,24 @@
|
|
1
1
|
---
|
2
|
-
title:
|
2
|
+
title: Add Application Entry
|
3
3
|
---
|
4
4
|
|
5
|
-
|
5
|
+
In the last chapter, we basically completed the development of the point of contact list application, introduced the usage of some functions in the Modern.js, and recommended best practices.
|
6
6
|
|
7
|
-
|
7
|
+
In this chapter, we will describe how to add a new entry to the application.
|
8
8
|
|
9
|
-
##
|
9
|
+
## New entry
|
10
10
|
|
11
|
-
|
11
|
+
A complete project may require multiple entries, Modern.js supports the automatic creation of new entries, as mentioned in the previous section, `pnpm run new` can enable optional features.
|
12
12
|
|
13
|
-
|
13
|
+
We can also use it to create new project elements and execute `pnpm run new` in the project root directory:
|
14
14
|
|
15
15
|
```bash
|
16
|
-
?
|
17
|
-
?
|
18
|
-
?
|
16
|
+
? Action Create project element
|
17
|
+
? Create project element New "entry"
|
18
|
+
? Entry name (entry) landing-page
|
19
19
|
```
|
20
20
|
|
21
|
-
|
21
|
+
When created, the project will look like this:
|
22
22
|
|
23
23
|
```md
|
24
24
|
.
|
@@ -55,44 +55,43 @@ title: 添加应用入口
|
|
55
55
|
|
56
56
|
```
|
57
57
|
|
58
|
-
|
58
|
+
You can see that the files of the contact list application are automatically refactored into `src/myapp/`.
|
59
59
|
|
60
|
-
|
60
|
+
At the same time, a new `src/landing-page/` is created, which also has `routes/*` (the `pnpm run new` command only does these things, so you can also easily create new entries or modify entries manually).
|
61
61
|
|
62
|
-
|
62
|
+
Execute `pnpm run dev` to display:
|
63
63
|
|
64
64
|

|
65
65
|
|
66
|
-
|
66
|
+
Access `http://localhost:8080/` to see the application as before.
|
67
67
|
|
68
|
-
|
68
|
+
Visit `http://localhost:8080/landing-page` to see the landing-page for the new entry you just created (Modern.js automatically generated default page).
|
69
69
|
|
70
|
-
Modern.js
|
70
|
+
One of the design principles of the Modern.js framework is [[Convention over Configuration](https://en.wikipedia.org/wiki/Convention_over_configuration) ]. In most cases, you can write code directly by convention without any configuration. The directory structure in `src/` is a convention:
|
71
71
|
|
72
|
-
`src/myapp/`
|
72
|
+
`src/myapp/` and `src/landing-page/` are automatically identified as two application portals: myapp and landing-page.
|
73
73
|
|
74
|
-
|
74
|
+
The directory name of `src/myapp/` is the same as the project name (`name` in `package.json`), which will be considered as the main entry of the project, and the root path of the project URL (the default in the development environment is `http://localhost:8080/`) will automatically point to the main entry.
|
75
75
|
|
76
|
-
|
76
|
+
The URL of other entries is to append the entry name after the root path, such as `http://localhost:8080/landing-page`.
|
77
77
|
|
78
|
-
|
78
|
+
Next, we rename `src/myapp/` to `src/contacts/`:
|
79
79
|
|
80
80
|
```bash
|
81
81
|
mv src/myapp src/contacts
|
82
82
|
```
|
83
83
|
|
84
|
-
|
84
|
+
Execute `pnpm run dev` again, the result becomes:
|
85
85
|
|
86
86
|

|
87
87
|
|
88
|
-
|
88
|
+
There is no longer a main entry, the point of contact list is now a normal entry that needs to be accessed with `http://localhost:8080/contacts`.
|
89
89
|
|
90
|
+
## Modify the configuration by entry
|
90
91
|
|
91
|
-
|
92
|
+
In the Modern.js configuration file, we can write our own code to control the configuration of the project.
|
92
93
|
|
93
|
-
|
94
|
-
|
95
|
-
现在,修改 `modern.config.ts` 里面添加内容:
|
94
|
+
Now, modify the `modern.config.ts` to add something:
|
96
95
|
|
97
96
|
```typescript
|
98
97
|
import AppToolsPlugin, { defineConfig } from '@modern-js/app-tools';
|
@@ -114,11 +113,11 @@ export default defineConfig({
|
|
114
113
|
});
|
115
114
|
```
|
116
115
|
|
117
|
-
|
116
|
+
Execute `pnpm run dev`, and then open `view-source: http://localhost:8080/landing-page` with the browser, you can see that the content of the `landing-page` web page is dynamically loaded through js, and the SSR function of this page is turned off.
|
118
117
|
|
119
|
-
|
118
|
+
If `ssrByEntries` and its value are annotated, the SSR function of landing-page is restored.
|
120
119
|
|
121
|
-
|
120
|
+
Other times, you need some more sophisticated logic to do the setup, such as JS variables, expressions, import modules, etc., for example, only in the development environment to enable SSR:
|
122
121
|
|
123
122
|
```js
|
124
123
|
export default defineConfig({
|
@@ -130,8 +129,8 @@ export default defineConfig({
|
|
130
129
|
};
|
131
130
|
```
|
132
131
|
|
133
|
-
|
132
|
+
So far, the prototype of our point of contact list application is almost complete 👏👏👏.
|
134
133
|
|
135
|
-
##
|
134
|
+
## Next step
|
136
135
|
|
137
|
-
|
136
|
+
Then you can further refine your application by following more tutorials like [Guides](/docs/guides/get-started/quick-start), [configuration](/docs/configure/app/usage), and more.
|
@@ -7,53 +7,9 @@
|
|
7
7
|
"message": "Basic",
|
8
8
|
"description": "The label for category 基础 in sidebar tutorialsSidebar"
|
9
9
|
},
|
10
|
-
"sidebar.tutorialsSidebar.category
|
11
|
-
"message": "
|
12
|
-
"description": "The label for category
|
13
|
-
},
|
14
|
-
"sidebar.tutorialsSidebar.category.1: 手动创建应用工程": {
|
15
|
-
"message": "1: 手动创建应用工程",
|
16
|
-
"description": "The label for category 1: 手动创建应用工程 in sidebar tutorialsSidebar"
|
17
|
-
},
|
18
|
-
"sidebar.tutorialsSidebar.category.2: 自动创建应用工程": {
|
19
|
-
"message": "2: 自动创建应用工程",
|
20
|
-
"description": "The label for category 2: 自动创建应用工程 in sidebar tutorialsSidebar"
|
21
|
-
},
|
22
|
-
"sidebar.tutorialsSidebar.category.3: 确认编程环境": {
|
23
|
-
"message": "3: 确认编程环境",
|
24
|
-
"description": "The label for category 3: 确认编程环境 in sidebar tutorialsSidebar"
|
25
|
-
},
|
26
|
-
"sidebar.tutorialsSidebar.category.4: 写 JS 代码": {
|
27
|
-
"message": "4: 写 JS 代码",
|
28
|
-
"description": "The label for category 4: 写 JS 代码 in sidebar tutorialsSidebar"
|
29
|
-
},
|
30
|
-
"sidebar.tutorialsSidebar.category.5: 使用 UI 组件": {
|
31
|
-
"message": "5: 使用 UI 组件",
|
32
|
-
"description": "The label for category 5: 使用 UI 组件 in sidebar tutorialsSidebar"
|
33
|
-
},
|
34
|
-
"sidebar.tutorialsSidebar.category.6: 添加 UI 组件": {
|
35
|
-
"message": "6: 添加 UI 组件",
|
36
|
-
"description": "The label for category 6: 添加 UI 组件 in sidebar tutorialsSidebar"
|
37
|
-
},
|
38
|
-
"sidebar.tutorialsSidebar.category.7: 添加应用入口": {
|
39
|
-
"message": "7: 添加应用入口",
|
40
|
-
"description": "The label for category 7: 添加应用入口 in sidebar tutorialsSidebar"
|
41
|
-
},
|
42
|
-
"sidebar.tutorialsSidebar.category.8: 添加客户端路由": {
|
43
|
-
"message": "8: 添加客户端路由",
|
44
|
-
"description": "The label for category 8: 添加客户端路由 in sidebar tutorialsSidebar"
|
45
|
-
},
|
46
|
-
"sidebar.tutorialsSidebar.category.9: 添加 BFF": {
|
47
|
-
"message": "9: 添加 BFF",
|
48
|
-
"description": "The label for category 9: 添加 BFF in sidebar tutorialsSidebar"
|
49
|
-
},
|
50
|
-
"sidebar.tutorialsSidebar.category.10: 添加业务模型": {
|
51
|
-
"message": "10: 添加业务模型",
|
52
|
-
"description": "The label for category 10: 添加业务模型 in sidebar tutorialsSidebar"
|
53
|
-
},
|
54
|
-
"sidebar.tutorialsSidebar.category.11: 添加容器组件": {
|
55
|
-
"message": "11: 添加容器组件",
|
56
|
-
"description": "The label for category 11: 添加容器组件 in sidebar tutorialsSidebar"
|
10
|
+
"sidebar.tutorialsSidebar.category.联系人列表应用": {
|
11
|
+
"message": "First App",
|
12
|
+
"description": "The label for category 联系人列表应用 in sidebar tutorialsSidebar"
|
57
13
|
},
|
58
14
|
"sidebar.guidesSidebar.category.开始": {
|
59
15
|
"message": "Start",
|
package/package.json
CHANGED
@@ -11,20 +11,20 @@
|
|
11
11
|
"modern",
|
12
12
|
"modern.js"
|
13
13
|
],
|
14
|
-
"version": "2.0.
|
14
|
+
"version": "2.0.3-alpha.0",
|
15
15
|
"publishConfig": {
|
16
16
|
"registry": "https://registry.npmjs.org/",
|
17
17
|
"access": "public"
|
18
18
|
},
|
19
19
|
"peerDependencies": {
|
20
|
-
"@modern-js/builder-doc": "^2.0.
|
20
|
+
"@modern-js/builder-doc": "^2.0.2"
|
21
21
|
},
|
22
22
|
"devDependencies": {
|
23
|
+
"@modern-js/builder-doc": "2.0.2",
|
23
24
|
"ts-node": "^10",
|
24
25
|
"fs-extra": "^10",
|
25
26
|
"@types/node": "^16",
|
26
|
-
"@types/fs-extra": "^9"
|
27
|
-
"@modern-js/builder-doc": "2.0.1"
|
27
|
+
"@types/fs-extra": "^9"
|
28
28
|
},
|
29
29
|
"scripts": {
|
30
30
|
"build": "npx ts-node ./scripts/sync.ts"
|
@@ -7,9 +7,9 @@ import TabItem from '@theme/TabItem';
|
|
7
7
|
<Tabs>
|
8
8
|
<TabItem value="express" label="Express.js" default>
|
9
9
|
|
10
|
-
```ts title="
|
11
|
-
import ExpressPlugin from '@
|
12
|
-
import BffPlugin from '@
|
10
|
+
```ts title="modern.config.ts"
|
11
|
+
import ExpressPlugin from '@modern-js/plugin-express';
|
12
|
+
import BffPlugin from '@modern-js/plugin-bff';
|
13
13
|
|
14
14
|
export default defineConfig({
|
15
15
|
plugins: [
|
@@ -21,9 +21,9 @@ export default defineConfig({
|
|
21
21
|
</TabItem>
|
22
22
|
<TabItem value="koa" label="Koa.js">
|
23
23
|
|
24
|
-
```ts title="
|
25
|
-
import KoaPlugin from '@
|
26
|
-
import BffPlugin from '@
|
24
|
+
```ts title="modern.config.ts"
|
25
|
+
import KoaPlugin from '@modern-js/plugin-koa';
|
26
|
+
import BffPlugin from '@modern-js/plugin-bff';
|
27
27
|
|
28
28
|
export default defineConfig({
|
29
29
|
plugins: [
|
@@ -38,6 +38,28 @@ export default defineConfig({
|
|
38
38
|
当 runtime 配置中存在函数时,只能使用该方式进行配置。
|
39
39
|
:::
|
40
40
|
|
41
|
+
import Tabs from '@theme/Tabs';
|
42
|
+
import TabItem from '@theme/TabItem';
|
43
|
+
|
44
|
+
<Tabs>
|
45
|
+
<TabItem value="layout" label="约定式路由" default>
|
46
|
+
|
47
|
+
```tsx title="src/routes/layout.tsx"
|
48
|
+
import type { AppConfig } from '@modern-js/runtime';
|
49
|
+
|
50
|
+
export const config = (): AppConfig => {
|
51
|
+
return {
|
52
|
+
router: {
|
53
|
+
supportHtml5History: false
|
54
|
+
}
|
55
|
+
}
|
56
|
+
};
|
57
|
+
```
|
58
|
+
|
59
|
+
</TabItem>
|
60
|
+
|
61
|
+
<TabItem value="app" label="自控路由">
|
62
|
+
|
41
63
|
```ts title="src/App.tsx"
|
42
64
|
import { defineConfig } from '@modern-js/runtime';
|
43
65
|
|
@@ -54,6 +76,11 @@ defineConfig(App, {
|
|
54
76
|
export default App;
|
55
77
|
```
|
56
78
|
|
79
|
+
</TabItem>
|
80
|
+
</Tabs>
|
81
|
+
|
82
|
+
|
83
|
+
|
57
84
|
:::info
|
58
85
|
使用运行时配置,可以解决 Runtime 插件配置需要在运行时才能获取到具体内容问题。
|
59
86
|
|