@modern-js/main-doc 0.0.0-next-1680114730914 → 0.0.0-next-1680153170734
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -2
- package/docs/en/apis/app/hooks/src/server.mdx +1 -28
- package/docs/en/guides/advanced-features/ssr.mdx +3 -3
- package/docs/en/tutorials/first-app/c06-model.mdx +15 -12
- package/docs/en/tutorials/first-app/c07-container.mdx +22 -19
- package/docs/zh/apis/app/hooks/src/server.mdx +1 -28
- package/docs/zh/guides/advanced-features/ssr.mdx +4 -2
- package/docs/zh/tutorials/first-app/c06-model.mdx +14 -12
- package/docs/zh/tutorials/first-app/c07-container.mdx +22 -19
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @modern-js/main-doc
|
|
2
2
|
|
|
3
|
-
## 0.0.0-next-
|
|
3
|
+
## 0.0.0-next-1680153170734
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
fix: 将部分英文文档中的中文翻译为英文
|
|
13
13
|
- Updated dependencies [a8c08c3a2]
|
|
14
14
|
- Updated dependencies [b71cef1d9]
|
|
15
|
-
- @modern-js/builder-doc@0.0.0-next-
|
|
15
|
+
- @modern-js/builder-doc@0.0.0-next-1680153170734
|
|
16
16
|
|
|
17
17
|
## 2.10.0
|
|
18
18
|
|
|
@@ -4,31 +4,4 @@ sidebar_position: 8
|
|
|
4
4
|
---
|
|
5
5
|
# *.[server|node].[tj]sx
|
|
6
6
|
|
|
7
|
-
Used in application projects to place server side code,
|
|
8
|
-
|
|
9
|
-
1. When `*.tsx` and `*. [server|node].tsx` coexist, rendering on the server side will give preference to the `*. [server|node].tsx` file instead of the `*.tsx` file.
|
|
10
|
-
|
|
11
|
-
2. When using [data loader](/guides/basic-features/data-fetch), the server-side dependencies need to be re-exported from this file
|
|
12
|
-
|
|
13
|
-
```tsx
|
|
14
|
-
// routes/user/avatar.tsx
|
|
15
|
-
import { useLoaderData } from '@modern-js/runtime/router';
|
|
16
|
-
import { readFile } from './utils.server';
|
|
17
|
-
|
|
18
|
-
type ProfileData = {
|
|
19
|
-
/* some type declarations */
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const loader = async (): ProfileData => {
|
|
23
|
-
const profile = await readFile('profile.json');
|
|
24
|
-
return profile;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export default function UserPage() {
|
|
28
|
-
const profileData = useLoaderData() as ProfileData;
|
|
29
|
-
return <div>{profileData}</div>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// routes/user/utils.server.ts
|
|
33
|
-
export * from 'fs-extra';
|
|
34
|
-
```
|
|
7
|
+
Used in application projects to place server side code, When `*.tsx` and `*. [server|node].tsx` coexist, rendering on the server side will give preference to the `*. [server|node].tsx` file instead of the `*.tsx` file.
|
|
@@ -22,8 +22,8 @@ export default defineConfig({
|
|
|
22
22
|
|
|
23
23
|
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:
|
|
24
24
|
|
|
25
|
-
```ts title="src/routes/page.
|
|
26
|
-
export
|
|
25
|
+
```ts title="src/routes/page.loader.ts"
|
|
26
|
+
export default () => {
|
|
27
27
|
return {
|
|
28
28
|
message: 'Hello World',
|
|
29
29
|
};
|
|
@@ -226,7 +226,7 @@ The Node API is introduced in the component file, usually because of the use of
|
|
|
226
226
|
|
|
227
227
|
```ts
|
|
228
228
|
import fse from 'fs-extra';
|
|
229
|
-
export
|
|
229
|
+
export default () => {
|
|
230
230
|
const file = fse.readFileSync('./myfile');
|
|
231
231
|
return {
|
|
232
232
|
...
|
|
@@ -195,18 +195,10 @@ const Item = ({
|
|
|
195
195
|
export default Item;
|
|
196
196
|
```
|
|
197
197
|
|
|
198
|
-
Next, we modify `src/routes/page.tsx` to pass more parameters to the `<Item>` component:
|
|
198
|
+
Next, we add `src/routes.page.loader` and modify `src/routes/page.tsx` to pass more parameters to the `<Item>` component:
|
|
199
199
|
|
|
200
|
-
```tsx
|
|
201
|
-
|
|
202
|
-
import { useModel } from '@modern-js/runtime/model';
|
|
203
|
-
import { useLoaderData } from '@modern-js/runtime/router';
|
|
204
|
-
import { List } from 'antd';
|
|
205
|
-
import { name, internet } from 'faker';
|
|
206
|
-
import Item from '../components/Item';
|
|
207
|
-
import contacts from '../models/contacts';
|
|
208
|
-
|
|
209
|
-
type LoaderData = {
|
|
200
|
+
```tsx title="src/routes/page.loader.ts"
|
|
201
|
+
export type LoaderData = {
|
|
210
202
|
code: number;
|
|
211
203
|
data: {
|
|
212
204
|
name: string;
|
|
@@ -215,7 +207,7 @@ type LoaderData = {
|
|
|
215
207
|
}[];
|
|
216
208
|
};
|
|
217
209
|
|
|
218
|
-
export
|
|
210
|
+
export default async (): Promise<LoaderData> => {
|
|
219
211
|
const data = new Array(20).fill(0).map(() => {
|
|
220
212
|
const firstName = name.firstName();
|
|
221
213
|
return {
|
|
@@ -231,6 +223,17 @@ export const loader = async (): Promise<LoaderData> => {
|
|
|
231
223
|
data,
|
|
232
224
|
};
|
|
233
225
|
};
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
```tsx title="src/routes/page.tsx"
|
|
229
|
+
import { Helmet } from '@modern-js/runtime/head';
|
|
230
|
+
import { useModel } from '@modern-js/runtime/model';
|
|
231
|
+
import { useLoaderData } from '@modern-js/runtime/router';
|
|
232
|
+
import { List } from 'antd';
|
|
233
|
+
import { name, internet } from 'faker';
|
|
234
|
+
import Item from '../components/Item';
|
|
235
|
+
import contacts from '../models/contacts';
|
|
236
|
+
import type { LoaderData } from './page.loader';
|
|
234
237
|
|
|
235
238
|
function Index() {
|
|
236
239
|
const { data } = useLoaderData() as LoaderData;
|
|
@@ -15,24 +15,8 @@ Because the two pages need to share the same set of state (point of contact tabu
|
|
|
15
15
|
|
|
16
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
|
-
```
|
|
19
|
-
|
|
20
|
-
import {
|
|
21
|
-
Outlet,
|
|
22
|
-
useLoaderData,
|
|
23
|
-
useLocation,
|
|
24
|
-
useNavigate,
|
|
25
|
-
} from '@modern-js/runtime/router';
|
|
26
|
-
import { useState } from 'react';
|
|
27
|
-
import { Radio, RadioChangeEvent } from 'antd';
|
|
28
|
-
import { useModel } from '@modern-js/runtime/model';
|
|
29
|
-
import contacts from '../models/contacts';
|
|
30
|
-
import 'tailwindcss/base.css';
|
|
31
|
-
import 'tailwindcss/components.css';
|
|
32
|
-
import 'tailwindcss/utilities.css';
|
|
33
|
-
import '../styles/utils.css';
|
|
34
|
-
|
|
35
|
-
type LoaderData = {
|
|
18
|
+
```ts title="src/routes/layout.loader.ts"
|
|
19
|
+
export type LoaderData = {
|
|
36
20
|
code: number;
|
|
37
21
|
data: {
|
|
38
22
|
name: string;
|
|
@@ -41,7 +25,7 @@ type LoaderData = {
|
|
|
41
25
|
}[];
|
|
42
26
|
};
|
|
43
27
|
|
|
44
|
-
export
|
|
28
|
+
export default async (): Promise<LoaderData> => {
|
|
45
29
|
const data = new Array(20).fill(0).map(() => {
|
|
46
30
|
const firstName = name.firstName();
|
|
47
31
|
return {
|
|
@@ -56,6 +40,25 @@ export const loader = async (): Promise<LoaderData> => {
|
|
|
56
40
|
data,
|
|
57
41
|
};
|
|
58
42
|
};
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```tsx title="src/routes/layout.tsx"
|
|
46
|
+
import { name, internet } from 'faker';
|
|
47
|
+
import {
|
|
48
|
+
Outlet,
|
|
49
|
+
useLoaderData,
|
|
50
|
+
useLocation,
|
|
51
|
+
useNavigate,
|
|
52
|
+
} from '@modern-js/runtime/router';
|
|
53
|
+
import { useState } from 'react';
|
|
54
|
+
import { Radio, RadioChangeEvent } from 'antd';
|
|
55
|
+
import { useModel } from '@modern-js/runtime/model';
|
|
56
|
+
import contacts from '../models/contacts';
|
|
57
|
+
import 'tailwindcss/base.css';
|
|
58
|
+
import 'tailwindcss/components.css';
|
|
59
|
+
import 'tailwindcss/utilities.css';
|
|
60
|
+
import '../styles/utils.css';
|
|
61
|
+
import type { LoaderData } from './layout.loader';
|
|
59
62
|
|
|
60
63
|
export default function Layout() {
|
|
61
64
|
const { data } = useLoaderData() as LoaderData;
|
|
@@ -4,31 +4,4 @@ sidebar_position: 8
|
|
|
4
4
|
---
|
|
5
5
|
# *.[server|node].[tj]sx
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
1. 当 `*.tsx` 和 `*.[server|node].tsx` 共存时,SSR 在服务端执行渲染时,会优先使用 `*.[server|node].tsx` 文件,而不是 `*.tsx` 文件。
|
|
10
|
-
|
|
11
|
-
2. 在使用 [data loader](/guides/basic-features/data-fetch) 时,需要将服务端的依赖从该文件中做重导出
|
|
12
|
-
|
|
13
|
-
```tsx
|
|
14
|
-
// routes/user/avatar.tsx
|
|
15
|
-
import { useLoaderData } from '@modern-js/runtime/router';
|
|
16
|
-
import { readFile } from './utils.server';
|
|
17
|
-
|
|
18
|
-
type ProfileData = {
|
|
19
|
-
/* some type declarations */
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const loader = async (): ProfileData => {
|
|
23
|
-
const profile = await readFile('profile.json');
|
|
24
|
-
return profile;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export default function UserPage() {
|
|
28
|
-
const profileData = useLoaderData() as ProfileData;
|
|
29
|
-
return <div>{profileData}</div>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// routes/user/utils.server.ts
|
|
33
|
-
export * from 'fs-extra';
|
|
34
|
-
```
|
|
7
|
+
应用项目中使用,用于放置服务端代码,当 `*.tsx` 和 `*.[server|node].tsx` 共存时,SSR 在服务端执行渲染时,会优先使用 `*.[server|node].tsx` 文件,而不是 `*.tsx` 文件。
|
|
@@ -148,10 +148,10 @@ SPR 利用预渲染与缓存技术,为 SSR 页面提供静态 Web 的响应性
|
|
|
148
148
|
|
|
149
149
|
这里模拟一个使用 `useLoaderData` API 的组件,Data Loader 中的请求需要消耗 2s 时间。
|
|
150
150
|
|
|
151
|
-
```
|
|
151
|
+
```tsx title="page.loader.ts"
|
|
152
152
|
import { useLoaderData } from '@modern-js/runtime/router';
|
|
153
153
|
|
|
154
|
-
export
|
|
154
|
+
export default async () => {
|
|
155
155
|
await new Promise((resolve, reject) => {
|
|
156
156
|
setTimeout(() => {
|
|
157
157
|
resolve(null);
|
|
@@ -162,7 +162,9 @@ export const loader = async () => {
|
|
|
162
162
|
message: 'Hello Modern.js',
|
|
163
163
|
};
|
|
164
164
|
};
|
|
165
|
+
```
|
|
165
166
|
|
|
167
|
+
```tsx title="page.tsx"
|
|
166
168
|
export default () => {
|
|
167
169
|
const data = useLoaderData();
|
|
168
170
|
return <div>{data?.message}</div>;
|
|
@@ -195,18 +195,10 @@ const Item = ({
|
|
|
195
195
|
export default Item;
|
|
196
196
|
```
|
|
197
197
|
|
|
198
|
-
接下来,我们修改 `src/routes/page.tsx`,为 `<Item>` 组件传递更多参数:
|
|
198
|
+
接下来,我们修改 `src/routes/page.tsx` 和 `src/routes/page.loader.ts`,为 `<Item>` 组件传递更多参数:
|
|
199
199
|
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
import { useModel } from '@modern-js/runtime/model';
|
|
203
|
-
import { useLoaderData } from '@modern-js/runtime/router';
|
|
204
|
-
import { List } from 'antd';
|
|
205
|
-
import { name, internet } from 'faker';
|
|
206
|
-
import Item from '../components/Item';
|
|
207
|
-
import contacts from '../models/contacts';
|
|
208
|
-
|
|
209
|
-
type LoaderData = {
|
|
200
|
+
```ts title="src/routes/page.loader.ts"
|
|
201
|
+
export type LoaderData = {
|
|
210
202
|
code: number;
|
|
211
203
|
data: {
|
|
212
204
|
name: string;
|
|
@@ -215,7 +207,7 @@ type LoaderData = {
|
|
|
215
207
|
}[];
|
|
216
208
|
};
|
|
217
209
|
|
|
218
|
-
export
|
|
210
|
+
export default async (): Promise<LoaderData> => {
|
|
219
211
|
const data = new Array(20).fill(0).map(() => {
|
|
220
212
|
const firstName = name.firstName();
|
|
221
213
|
return {
|
|
@@ -231,6 +223,16 @@ export const loader = async (): Promise<LoaderData> => {
|
|
|
231
223
|
data,
|
|
232
224
|
};
|
|
233
225
|
};
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
```tsx title="src/routes/page.tsx"
|
|
229
|
+
import { Helmet } from '@modern-js/runtime/head';
|
|
230
|
+
import { useModel } from '@modern-js/runtime/model';
|
|
231
|
+
import { useLoaderData } from '@modern-js/runtime/router';
|
|
232
|
+
import { List } from 'antd';
|
|
233
|
+
import { name, internet } from 'faker';
|
|
234
|
+
import Item from '../components/Item';
|
|
235
|
+
import contacts from '../models/contacts';
|
|
234
236
|
|
|
235
237
|
function Index() {
|
|
236
238
|
const { data } = useLoaderData() as LoaderData;
|
|
@@ -15,24 +15,8 @@ import { Tabs, Tab as TabItem } from "@theme";
|
|
|
15
15
|
|
|
16
16
|
Modern.js 支持在 `layout.tsx` 通过 Data Loader 获取数据,我们先数据获取这部分代码移动到 `src/routes/layout.tsx` 中:
|
|
17
17
|
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
import {
|
|
21
|
-
Outlet,
|
|
22
|
-
useLoaderData,
|
|
23
|
-
useLocation,
|
|
24
|
-
useNavigate,
|
|
25
|
-
} from '@modern-js/runtime/router';
|
|
26
|
-
import { useState } from 'react';
|
|
27
|
-
import { Radio, RadioChangeEvent } from 'antd';
|
|
28
|
-
import { useModel } from '@modern-js/runtime/model';
|
|
29
|
-
import contacts from '../models/contacts';
|
|
30
|
-
import 'tailwindcss/base.css';
|
|
31
|
-
import 'tailwindcss/components.css';
|
|
32
|
-
import 'tailwindcss/utilities.css';
|
|
33
|
-
import '../styles/utils.css';
|
|
34
|
-
|
|
35
|
-
type LoaderData = {
|
|
18
|
+
```ts title="src/routes/layout.loader.ts"
|
|
19
|
+
export type LoaderData = {
|
|
36
20
|
code: number;
|
|
37
21
|
data: {
|
|
38
22
|
name: string;
|
|
@@ -41,7 +25,7 @@ type LoaderData = {
|
|
|
41
25
|
}[];
|
|
42
26
|
};
|
|
43
27
|
|
|
44
|
-
export
|
|
28
|
+
export default async (): Promise<LoaderData> => {
|
|
45
29
|
const data = new Array(20).fill(0).map(() => {
|
|
46
30
|
const firstName = name.firstName();
|
|
47
31
|
return {
|
|
@@ -56,6 +40,25 @@ export const loader = async (): Promise<LoaderData> => {
|
|
|
56
40
|
data,
|
|
57
41
|
};
|
|
58
42
|
};
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```tsx title="src/routes/layout.tsx"
|
|
46
|
+
import { name, internet } from 'faker';
|
|
47
|
+
import {
|
|
48
|
+
Outlet,
|
|
49
|
+
useLoaderData,
|
|
50
|
+
useLocation,
|
|
51
|
+
useNavigate,
|
|
52
|
+
} from '@modern-js/runtime/router';
|
|
53
|
+
import { useState } from 'react';
|
|
54
|
+
import { Radio, RadioChangeEvent } from 'antd';
|
|
55
|
+
import { useModel } from '@modern-js/runtime/model';
|
|
56
|
+
import contacts from '../models/contacts';
|
|
57
|
+
import 'tailwindcss/base.css';
|
|
58
|
+
import 'tailwindcss/components.css';
|
|
59
|
+
import 'tailwindcss/utilities.css';
|
|
60
|
+
import '../styles/utils.css';
|
|
61
|
+
import type { LoaderData } from './layout.loader';
|
|
59
62
|
|
|
60
63
|
export default function Layout() {
|
|
61
64
|
const { data } = useLoaderData() as LoaderData;
|
package/package.json
CHANGED
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
"modern",
|
|
12
12
|
"modern.js"
|
|
13
13
|
],
|
|
14
|
-
"version": "0.0.0-next-
|
|
14
|
+
"version": "0.0.0-next-1680153170734",
|
|
15
15
|
"publishConfig": {
|
|
16
16
|
"registry": "https://registry.npmjs.org/",
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"@modern-js/builder-doc": "0.0.0-next-
|
|
20
|
+
"@modern-js/builder-doc": "0.0.0-next-1680153170734"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"classnames": "^2",
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
"fs-extra": "^10",
|
|
30
30
|
"@types/node": "^16",
|
|
31
31
|
"@types/fs-extra": "^9",
|
|
32
|
-
"@modern-js/builder-doc": "0.0.0-next-
|
|
33
|
-
"@modern-js/doc-tools": "0.0.0-next-
|
|
34
|
-
"@modern-js/doc-plugin-auto-sidebar": "0.0.0-next-
|
|
32
|
+
"@modern-js/builder-doc": "0.0.0-next-1680153170734",
|
|
33
|
+
"@modern-js/doc-tools": "0.0.0-next-1680153170734",
|
|
34
|
+
"@modern-js/doc-plugin-auto-sidebar": "0.0.0-next-1680153170734"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"dev": "modern dev",
|