@modern-js/main-doc 2.10.0 → 2.11.0
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 +14 -0
- package/docs/en/apis/app/hooks/src/server.mdx +1 -28
- package/docs/en/configure/app/source/config-dir.mdx +2 -2
- package/docs/en/configure/app/source/design-system.mdx +2 -2
- package/docs/en/configure/app/source/disable-default-entries.mdx +12 -12
- package/docs/en/configure/app/source/disable-entry-dirs.mdx +3 -4
- package/docs/en/configure/app/source/enable-async-entry.mdx +2 -2
- package/docs/en/configure/app/source/entries-dir.mdx +10 -10
- package/docs/en/configure/app/source/entries.mdx +83 -26
- package/docs/en/configure/app/source/plugin-import.mdx +13 -0
- package/docs/en/configure/app/source/transform-import.mdx +13 -0
- package/docs/en/configure/app/tools/esbuild.mdx +9 -4
- package/docs/en/configure/app/tools/jest.mdx +2 -3
- package/docs/en/configure/app/tools/swc.mdx +6 -2
- package/docs/en/guides/advanced-features/ssr.mdx +4 -3
- package/docs/en/guides/advanced-features/web-server.mdx +1 -1
- package/docs/en/guides/concept/entries.mdx +130 -39
- package/docs/en/guides/topic-detail/framework-plugin/hook-list.mdx +7 -3
- package/docs/en/guides/topic-detail/model/typescript-best-practice.mdx +4 -4
- 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/configure/app/source/config-dir.mdx +2 -2
- package/docs/zh/configure/app/source/design-system.mdx +3 -3
- package/docs/zh/configure/app/source/disable-default-entries.mdx +11 -10
- package/docs/zh/configure/app/source/disable-entry-dirs.mdx +2 -3
- package/docs/zh/configure/app/source/enable-async-entry.mdx +3 -3
- package/docs/zh/configure/app/source/entries-dir.mdx +10 -11
- package/docs/zh/configure/app/source/entries.mdx +84 -23
- package/docs/zh/configure/app/source/plugin-import.mdx +13 -0
- package/docs/zh/configure/app/source/transform-import.mdx +13 -0
- package/docs/zh/configure/app/tools/esbuild.mdx +9 -5
- package/docs/zh/configure/app/tools/jest.mdx +2 -3
- package/docs/zh/configure/app/tools/swc.mdx +6 -2
- package/docs/zh/guides/advanced-features/ssr.mdx +6 -3
- package/docs/zh/guides/advanced-features/web-server.mdx +10 -5
- package/docs/zh/guides/concept/entries.mdx +36 -35
- package/docs/zh/guides/topic-detail/framework-plugin/hook-list.mdx +6 -2
- package/docs/zh/tutorials/first-app/c06-model.mdx +14 -12
- package/docs/zh/tutorials/first-app/c07-container.mdx +22 -19
- package/modern.config.ts +1 -1
- package/package.json +5 -5
@@ -1,19 +1,36 @@
|
|
1
1
|
---
|
2
|
-
title: source.entries
|
3
2
|
sidebar_label: entries
|
4
3
|
---
|
5
|
-
# entries
|
6
4
|
|
7
|
-
|
8
|
-
- **默认值:** 根据当前项目目录结构动态结算出的默认入口对象。
|
5
|
+
# source.entries
|
9
6
|
|
10
|
-
|
7
|
+
- **类型:**
|
11
8
|
|
12
|
-
|
9
|
+
```ts
|
10
|
+
type Entries = Record<
|
11
|
+
string,
|
12
|
+
| string
|
13
|
+
| {
|
14
|
+
entry: string;
|
15
|
+
disableMount?: boolean;
|
16
|
+
}
|
17
|
+
>;
|
18
|
+
```
|
19
|
+
|
20
|
+
- **默认值:** 根据当前项目的目录结构计算出的入口对象。
|
21
|
+
|
22
|
+
用于配置自定义的页面入口。
|
23
|
+
|
24
|
+
:::tip 何时使用
|
25
|
+
对于大部分场景,Modern.js 根据目录结构自动生成的入口已经可以满足需求,具体可参考[入口](/guides/concept/entries)。
|
26
|
+
|
27
|
+
如果你需要自定义页面入口时,可以通过该选项进行设置。
|
28
|
+
|
29
|
+
:::
|
13
30
|
|
14
31
|
## String 类型
|
15
32
|
|
16
|
-
|
33
|
+
当 `entries` 对象的 value 为 `string` 类型时,表示入口模块的文件路径:
|
17
34
|
|
18
35
|
```ts title="modern.config.ts"
|
19
36
|
import { defineConfig } from '@modern-js/app-tools';
|
@@ -22,13 +39,15 @@ export default defineConfig({
|
|
22
39
|
source: {
|
23
40
|
entries: {
|
24
41
|
// 指定一个名称为 entry_customize 的新入口
|
25
|
-
entry_customize: './src/home/test/index.
|
42
|
+
entry_customize: './src/home/test/index.ts',
|
26
43
|
},
|
44
|
+
// 禁用默认入口扫描
|
45
|
+
disableDefaultEntries: true,
|
27
46
|
},
|
28
47
|
});
|
29
48
|
```
|
30
49
|
|
31
|
-
默认情况下,配置的入口等价于 `App.[jt]sx
|
50
|
+
默认情况下,配置的入口等价于 `App.[jt]sx`,即指定的入口文件**只需要导出应用的根组件**。
|
32
51
|
|
33
52
|
例如以下目录结构:
|
34
53
|
|
@@ -41,17 +60,19 @@ export default defineConfig({
|
|
41
60
|
└── package.json
|
42
61
|
```
|
43
62
|
|
44
|
-
|
63
|
+
上述目录不符合 Modern.js 的目录结构约定,因此,Modern.js 在分析目录结构时,不会得到任何默认入口。
|
45
64
|
|
46
65
|
在不想改变目录结构的情况下(如项目迁移),可以通过 `source.entries` 自定义入口:
|
47
66
|
|
48
|
-
```ts title="modern.config.
|
67
|
+
```ts title="modern.config.ts"
|
49
68
|
export default defineConfig({
|
50
69
|
source: {
|
51
70
|
entries: {
|
52
71
|
home: './src/entry/home.tsx',
|
53
72
|
chat: './src/entry/chat.tsx',
|
54
73
|
},
|
74
|
+
// 禁用默认入口扫描
|
75
|
+
disableDefaultEntries: true,
|
55
76
|
},
|
56
77
|
});
|
57
78
|
```
|
@@ -61,7 +82,7 @@ export default defineConfig({
|
|
61
82
|
当值为 `Object` 时,可配置如下属性:
|
62
83
|
|
63
84
|
- `entry`:`string`,入口文件路径。
|
64
|
-
- `disableMount`:`boolean = false`,关闭 Modern.js
|
85
|
+
- `disableMount`:`boolean = false`,关闭 Modern.js 自动生成入口代码的行为。
|
65
86
|
|
66
87
|
```ts title="modern.config.ts"
|
67
88
|
import { defineConfig } from '@modern-js/app-tools';
|
@@ -71,25 +92,65 @@ export default defineConfig({
|
|
71
92
|
entries: {
|
72
93
|
entry_customize: {
|
73
94
|
// 入口文件路径
|
74
|
-
entry: './src/home/test/
|
95
|
+
entry: './src/home/test/index.tsx',
|
96
|
+
},
|
97
|
+
},
|
98
|
+
// 禁用默认入口扫描
|
99
|
+
disableDefaultEntries: true,
|
100
|
+
},
|
101
|
+
});
|
102
|
+
```
|
103
|
+
|
104
|
+
### 禁用入口文件生成
|
105
|
+
|
106
|
+
默认情况下,配置的入口等价于 `App.[jt]sx`,Modern.js 会自动生成一个入口文件来引用你配置的入口。
|
107
|
+
|
108
|
+
如果你希望禁用 Modern.js 自动生成入口文件的逻辑,可以将 `disableMount` 属性设置为 `true`。
|
109
|
+
|
110
|
+
```ts title="modern.config.ts"
|
111
|
+
export default defineConfig({
|
112
|
+
source: {
|
113
|
+
entries: {
|
114
|
+
entry_customize: {
|
115
|
+
entry: './src/home/test/index.tsx',
|
116
|
+
disableMount: true,
|
75
117
|
},
|
118
|
+
},
|
119
|
+
// 禁用默认入口扫描
|
120
|
+
disableDefaultEntries: true,
|
121
|
+
},
|
122
|
+
});
|
123
|
+
```
|
124
|
+
|
125
|
+
### 约定式路由
|
126
|
+
|
127
|
+
如果你需要为某个自定义入口启用约定式路由,可以将 `entry` 设置为目录路径:
|
128
|
+
|
129
|
+
```ts title="modern.config.ts"
|
130
|
+
import { defineConfig } from '@modern-js/app-tools';
|
131
|
+
|
132
|
+
export default defineConfig({
|
133
|
+
source: {
|
134
|
+
entries: {
|
76
135
|
// 启用约定式路由
|
77
136
|
entry_spa: {
|
78
137
|
// 约定式路由的入口路径必须设置为目录
|
79
138
|
entry: './src/about',
|
80
139
|
},
|
81
140
|
},
|
141
|
+
// 禁用默认入口扫描
|
142
|
+
disableDefaultEntries: true,
|
82
143
|
},
|
83
144
|
});
|
84
145
|
```
|
85
146
|
|
86
|
-
|
147
|
+
## 入口合并规则
|
87
148
|
|
88
|
-
|
149
|
+
在设置 `source.entries` 后,如果没有设置 `disableDefaultEntries: true`,Modern.js 会将自定义入口与分析目录结构得到的入口合并。
|
89
150
|
|
90
|
-
|
151
|
+
合并规则为:
|
91
152
|
|
92
|
-
比较自定义入口设置的入口路径和默认入口路径,当入口路径一致时,自定义入口会覆盖默认入口。
|
153
|
+
- 比较自定义入口设置的入口路径和默认入口路径,当入口路径一致时,自定义入口会覆盖默认入口。
|
93
154
|
|
94
155
|
例如以下目录结构:
|
95
156
|
|
@@ -97,13 +158,13 @@ export default defineConfig({
|
|
97
158
|
.
|
98
159
|
├── src
|
99
160
|
│ ├── chat
|
100
|
-
│ │ └── App.
|
161
|
+
│ │ └── App.tsx
|
101
162
|
│ └── home
|
102
|
-
│ └── index.
|
163
|
+
│ └── index.ts
|
103
164
|
└── package.json
|
104
165
|
```
|
105
166
|
|
106
|
-
Modern.js
|
167
|
+
Modern.js 会分析 `src/` 目录,得到默认入口 `chat` 和 `home`。当用户在 `modern.config.ts` 文件中配置如下时:
|
107
168
|
|
108
169
|
```ts title="modern.config.ts"
|
109
170
|
import { defineConfig } from '@modern-js/app-tools';
|
@@ -111,7 +172,7 @@ import { defineConfig } from '@modern-js/app-tools';
|
|
111
172
|
export default defineConfig({
|
112
173
|
source: {
|
113
174
|
entries: {
|
114
|
-
index: './src/home/index.
|
175
|
+
index: './src/home/index.ts',
|
115
176
|
},
|
116
177
|
},
|
117
178
|
};
|
@@ -119,5 +180,5 @@ export default defineConfig({
|
|
119
180
|
|
120
181
|
可以看到自定义入口 `index` 的路径和默认入口 `home` 的路径一致,在合并的过程中,`index` 会覆盖掉 `home`,最终入口如下:
|
121
182
|
|
122
|
-
- `chat -> ./src/chat/App.
|
123
|
-
- `index -> ./src/home/index.
|
183
|
+
- `chat -> ./src/chat/App.tsx`
|
184
|
+
- `index -> ./src/home/index.ts`
|
@@ -0,0 +1,13 @@
|
|
1
|
+
---
|
2
|
+
sidebar_label: pluginImport
|
3
|
+
---
|
4
|
+
|
5
|
+
# source.transformImport
|
6
|
+
|
7
|
+
:::tip
|
8
|
+
该配置由 Modern.js Builder 提供,更多信息可参考 [source.transformImport](https://modernjs.dev/builder/api/config-source.html#sourcepluginimport)。
|
9
|
+
:::
|
10
|
+
|
11
|
+
import Main from '@modern-js/builder-doc/docs/zh/config/source/transformImport.md';
|
12
|
+
|
13
|
+
<Main />
|
@@ -0,0 +1,13 @@
|
|
1
|
+
---
|
2
|
+
sidebar_label: transformImport
|
3
|
+
---
|
4
|
+
|
5
|
+
# source.transformImport
|
6
|
+
|
7
|
+
:::tip
|
8
|
+
该配置由 Modern.js Builder 提供,更多信息可参考 [source.transformImport](https://modernjs.dev/builder/api/config-source.html#sourcetransformimport)。
|
9
|
+
:::
|
10
|
+
|
11
|
+
import Main from '@modern-js/builder-doc/docs/zh/config/source/transformImport.md';
|
12
|
+
|
13
|
+
<Main />
|
@@ -1,21 +1,25 @@
|
|
1
1
|
---
|
2
|
-
title: tools.esbuild
|
3
2
|
sidebar_label: esbuild
|
4
3
|
---
|
5
|
-
|
4
|
+
|
5
|
+
# tools.esbuild
|
6
6
|
|
7
7
|
- **类型:** `Object`
|
8
8
|
- **默认值:** `undefined`
|
9
9
|
|
10
10
|
## 介绍
|
11
11
|
|
12
|
-
:::tip esbuild 介绍
|
13
12
|
[esbuild](https://esbuild.github.io/) 是一款基于 Golang 开发的前端构建工具,具有打包、编译和压缩 JavaScript 代码的功能,相比传统的打包编译工具,esbuild 在性能上有显著提升。在代码压缩方面,相比 webpack 内置的 terser 压缩器,esbuild 在性能上有数十倍的提升。
|
14
13
|
|
15
|
-
:::
|
16
|
-
|
17
14
|
Modern.js 提供了 esbuild 插件,让你能使用 esbuild 代替 babel-loader、ts-loader 和 terser 等库进行代码编译和压缩。在大型工程中开启后,**可以大幅度减少代码编译和压缩所需的时间,同时有效避免 OOM (heap out of memory) 问题**。
|
18
15
|
|
16
|
+
:::tip 推荐使用 SWC
|
17
|
+
相较于 esbuild,我们更推荐使用 SWC 来编译和压缩代码,因为 SWC 支持更多的语法特性、拥有更好的代码压缩率,并且产物具备更好的兼容性。
|
18
|
+
|
19
|
+
因此,我们建议你使用 SWC 而不是 esbuild,用法请参考 [tools.swc](/configure/app/tools/swc)。
|
20
|
+
|
21
|
+
:::
|
22
|
+
|
19
23
|
## 配置项
|
20
24
|
|
21
25
|
你可以通过 `tools.esbuild` 配置项来设置 esbuild 编译行为。
|
@@ -1,8 +1,8 @@
|
|
1
1
|
---
|
2
|
-
title: tools.swc
|
3
2
|
sidebar_label: swc
|
4
3
|
---
|
5
|
-
|
4
|
+
|
5
|
+
# tools.swc
|
6
6
|
|
7
7
|
- **类型:** `Object`
|
8
8
|
- **默认值:** `undefined`
|
@@ -13,6 +13,10 @@ sidebar_label: swc
|
|
13
13
|
|
14
14
|
Modern.js 提供了开箱即用的 SWC 插件,可以为你的 Web 应用提供语法降级、Polyfill 以及压缩,并且移植了一些额外常见的 Babel 插件。
|
15
15
|
|
16
|
+
:::tip
|
17
|
+
在使用 Rspack 作为打包工具时,默认会使用 SWC 进行转译和压缩,因此你不需要再安装和配置 SWC 插件。
|
18
|
+
:::
|
19
|
+
|
16
20
|
## 安装
|
17
21
|
|
18
22
|
使用前需要安装 `@modern-js/plugin-swc` 插件。
|
@@ -48,6 +48,7 @@ Modern.js 打破传统的 SSR 开发模式,提供了用户无感的 SSR 开发
|
|
48
48
|
1. 当以客户端路由的方式请求页面时,Modern.js 会发送一个 HTTP 请求,服务端接收到请求后执行页面对应的 Data Loader 函数,然后将执行结果作为请求的响应返回浏览器。
|
49
49
|
|
50
50
|
2. 使用 Data Loader 时,数据获取发生在渲染前,Modern.js 也仍然支持在组件渲染时获取数据。更多相关内容可以查看[数据获取](/guides/basic-features/data-fetch)。
|
51
|
+
|
51
52
|
:::
|
52
53
|
|
53
54
|
|
@@ -147,10 +148,10 @@ SPR 利用预渲染与缓存技术,为 SSR 页面提供静态 Web 的响应性
|
|
147
148
|
|
148
149
|
这里模拟一个使用 `useLoaderData` API 的组件,Data Loader 中的请求需要消耗 2s 时间。
|
149
150
|
|
150
|
-
```
|
151
|
+
```tsx title="page.loader.ts"
|
151
152
|
import { useLoaderData } from '@modern-js/runtime/router';
|
152
153
|
|
153
|
-
export
|
154
|
+
export default async () => {
|
154
155
|
await new Promise((resolve, reject) => {
|
155
156
|
setTimeout(() => {
|
156
157
|
resolve(null);
|
@@ -161,7 +162,9 @@ export const loader = async () => {
|
|
161
162
|
message: 'Hello Modern.js',
|
162
163
|
};
|
163
164
|
};
|
165
|
+
```
|
164
166
|
|
167
|
+
```tsx title="page.tsx"
|
165
168
|
export default () => {
|
166
169
|
const data = useLoaderData();
|
167
170
|
return <div>{data?.message}</div>;
|
@@ -413,11 +416,11 @@ export default Page;
|
|
413
416
|
从 Data Loader 文件导入类型时,需要使用 import type 语法,保证只导入类型信息,这样可以避免 Data Loader 的代码打包到前端产物的 bundle 文件中。
|
414
417
|
|
415
418
|
所以,这里的导入方式为:`import type { Data } from './page.loader'`;
|
419
|
+
|
416
420
|
:::
|
417
421
|
|
418
422
|
也可以通过 `useAsyncValue` 获取 Data Loader 返回的异步数据。例如:
|
419
423
|
|
420
|
-
|
421
424
|
```tsx title='page.tsx'
|
422
425
|
import { useAsyncValue } from '@modern-js/runtime/router';
|
423
426
|
|
@@ -48,15 +48,18 @@ Modern.js 提供的 Hook 用于控制 Web Server 中的内置逻辑,所有的
|
|
48
48
|
目前提供了两种 Hook,分别是 `AfterMatch` 和 `AfterRender`,可以用于修改渲染结果。可以在 `server/index.ts` 中这样写:
|
49
49
|
|
50
50
|
```ts
|
51
|
-
import type {
|
51
|
+
import type {
|
52
|
+
AfterMatchHook,
|
53
|
+
AfterRenderHook,
|
54
|
+
} from '@modern-js/runtime/server';
|
52
55
|
|
53
56
|
export const afterMatch: AfterMatchHook = (ctx, next) => {
|
54
57
|
next();
|
55
|
-
}
|
58
|
+
};
|
56
59
|
|
57
60
|
export const afterRender: AfterRenderHook = (ctx, next) => {
|
58
61
|
next();
|
59
|
-
}
|
62
|
+
};
|
60
63
|
```
|
61
64
|
|
62
65
|
项目在使用 Hook 时,应该有以下最佳实践:
|
@@ -78,8 +81,10 @@ Modern.js 默认提供了一套 API 供项目使用:
|
|
78
81
|
```ts
|
79
82
|
import { Middlewre } from '@modern-js/runtime/server';
|
80
83
|
|
81
|
-
export const middleware = (context, next) => {
|
82
|
-
const {
|
84
|
+
export const middleware: Middlewre = (context, next) => {
|
85
|
+
const {
|
86
|
+
source: { req, res },
|
87
|
+
} = context;
|
83
88
|
console.log(req.url);
|
84
89
|
next();
|
85
90
|
};
|
@@ -2,50 +2,52 @@
|
|
2
2
|
sidebar_position: 1
|
3
3
|
---
|
4
4
|
|
5
|
-
#
|
5
|
+
# 入口(Entry)
|
6
6
|
|
7
|
-
|
7
|
+
通过本章节,你可以了解到 Modern.js 中的入口约定,以及如何自定义入口。
|
8
8
|
|
9
|
-
|
9
|
+
## 什么是入口(Entry)
|
10
|
+
|
11
|
+
**入口指的是一个页面的起始模块。**
|
12
|
+
|
13
|
+
在 Modern.js 项目中,每一个入口对应一个独立的页面,也对应一条服务端路由。默认情况下,Modern.js 会基于目录约定来自动确定页面的入口,同时也支持通过配置项来自定义入口。
|
14
|
+
|
15
|
+
Modern.js 提供的很多配置项都是以入口为维度进行划分的,比如页面标题、HTML 模板、页面 Meta 信息、是否开启 SSR/SSG、服务端路由规则等。
|
10
16
|
|
11
17
|
## 单入口与多入口
|
12
18
|
|
13
|
-
Modern.js
|
19
|
+
Modern.js 初始化的项目是单入口的(SPA),项目结构如下:
|
14
20
|
|
15
21
|
```
|
16
22
|
.
|
17
23
|
├── src
|
18
|
-
│ ├── modern-app-env.d.ts
|
19
24
|
│ └── routes
|
20
25
|
│ ├── index.css
|
21
26
|
│ ├── layout.tsx
|
22
27
|
│ └── page.tsx
|
23
28
|
├── package.json
|
24
29
|
├── modern.config.ts
|
25
|
-
├── pnpm-lock.yaml
|
26
|
-
├── README.md
|
27
30
|
└── tsconfig.json
|
28
31
|
```
|
29
32
|
|
30
|
-
Modern.js
|
33
|
+
在 Modern.js 项目中,你可以很方便的将单入口切换成多入口,直接在项目下执行 `pnpm run new`,通过生成器创建入口即可:
|
31
34
|
|
32
35
|
```bash
|
33
|
-
?
|
34
|
-
?
|
35
|
-
?
|
36
|
+
? 请选择你想要的操作:创建工程元素
|
37
|
+
? 创建工程元素:新建「应用入口」
|
38
|
+
? 请填写入口名称:new-entry
|
36
39
|
```
|
37
40
|
|
38
|
-
|
41
|
+
执行后,Modern.js 会自动生成一个新的入口目录,此时可以看到 `src/` 目录变成如下结构:
|
39
42
|
|
40
|
-
```
|
43
|
+
```bash
|
41
44
|
.
|
42
|
-
├──
|
43
|
-
├── myapp
|
45
|
+
├── myapp # 原入口
|
44
46
|
│ └── routes
|
45
47
|
│ ├── index.css
|
46
48
|
│ ├── layout.tsx
|
47
49
|
│ └── page.tsx
|
48
|
-
└── new-entry
|
50
|
+
└── new-entry # 新入口
|
49
51
|
└── routes
|
50
52
|
├── index.css
|
51
53
|
├── layout.tsx
|
@@ -54,10 +56,12 @@ Modern.js 可以很方便的将单入口切换成多入口。可以在项目下
|
|
54
56
|
|
55
57
|
原本的代码被移动到了和 `package.json` 中 `name` 同名的目录下,并创建了新的目录。
|
56
58
|
|
57
|
-
执行 `pnpm run dev`
|
59
|
+
执行 `pnpm run dev` 后,可以看到新增了一条名为 `/new-entry` 的路由,并且被迁移的代码路由并未发生变化。
|
60
|
+
|
61
|
+
:::tip
|
62
|
+
Modern.js 会将与 package.json 文件中 `name` 字段同名的入口作为主入口,主入口的路由为 `/`,其他入口的路由为 `/{entryName}`。
|
58
63
|
|
59
|
-
|
60
|
-
Modern.js 会将和 `package.json` 中 `name` 字段同名的入口作为主入口,默认路由为 `/`,其他入口默认路由为 `/{entryName}`。
|
64
|
+
比如,package.json 中的 `name` 为 `myapp` 时,`src/myapp` 会作为项目的主入口。
|
61
65
|
|
62
66
|
:::
|
63
67
|
|
@@ -82,7 +86,7 @@ Modern.js 会将和 `package.json` 中 `name` 字段同名的入口作为主入
|
|
82
86
|
当 `src/` 目录满足入口特征时,Modern.js 会认为当前项目为单入口应用。
|
83
87
|
|
84
88
|
:::tip
|
85
|
-
|
89
|
+
在单入口应用中,默认的入口名为 `main`。
|
86
90
|
|
87
91
|
:::
|
88
92
|
|
@@ -168,35 +172,32 @@ ReactDOM.render(<App />, document.getElementById('root'));
|
|
168
172
|
|
169
173
|
Modern.js **不推荐**使用这种方式,这种方式丧失了框架的一些能力,如 **`modern.config.js` 文件中的 `runtime` 配置将不会再生效**。但是在项目从其他框架迁移到 Modern.js,例如 CRA,或是自己手动搭建的 webpack 时,这种方式会非常有用。
|
170
174
|
|
171
|
-
##
|
175
|
+
## 自定义入口
|
172
176
|
|
173
|
-
|
177
|
+
大部分存量项目并不是按照 Modern.js 的目录结构来搭建的。如果要改成 Modern.js 约定的目录结构,会存在一定的迁移成本。
|
174
178
|
|
175
|
-
|
179
|
+
在这种情况下,除了使用文件约定生成入口外,你可以在 `modern.config.[jt]s` 中手动配置入口。
|
176
180
|
|
177
|
-
```ts
|
181
|
+
```ts title="modern.config.ts"
|
178
182
|
export default defineConfig({
|
179
183
|
source: {
|
180
184
|
entries: {
|
181
185
|
// 指定一个名称为 entry_customize 的新入口
|
182
|
-
entry_customize: './src/home/test/index.
|
186
|
+
entry_customize: './src/home/test/index.ts',
|
183
187
|
},
|
188
|
+
// 禁用默认入口扫描
|
189
|
+
disableDefaultEntries: true,
|
184
190
|
},
|
185
191
|
});
|
186
192
|
```
|
187
193
|
|
188
|
-
|
189
|
-
详情可以查看 [source.entries](/configure/app/source/entries)。
|
190
|
-
|
191
|
-
:::
|
192
|
-
|
193
|
-
## 禁用默认入口扫描
|
194
|
+
### 禁用默认入口扫描
|
194
195
|
|
195
|
-
|
196
|
+
当使用自定义入口时,项目的部分结构可能恰巧命中了 Modern.js 的目录约定,但实际上这部分目录并不是真实的入口。
|
196
197
|
|
197
|
-
Modern.js
|
198
|
+
Modern.js 提供了 `disableDefaultEntries` 配置,来禁用默认的入口扫描规则。当你需要自定义入口时,一般需要将 `disableDefaultEntries` 与 `entries` 结合使用。这样,一些存量项目可以在不修改目录结构的情况下,快速地进行迁移。
|
198
199
|
|
199
|
-
```ts
|
200
|
+
```ts title="modern.config.ts"
|
200
201
|
export default defineConfig({
|
201
202
|
source: {
|
202
203
|
disableDefaultEntries: true,
|
@@ -205,6 +206,6 @@ export default defineConfig({
|
|
205
206
|
```
|
206
207
|
|
207
208
|
:::tip
|
208
|
-
|
209
|
+
详细用法请查看 [source.entries](/configure/app/source/entries) 和 [source.disableDefaultEntries](/configure/app/source/disable-default-entries)。
|
209
210
|
|
210
211
|
:::
|
@@ -191,8 +191,8 @@ foo
|
|
191
191
|
|
192
192
|
- 功能:在退出进程前,重置一些文件状态
|
193
193
|
- 执行阶段:进程退出之前
|
194
|
-
- Hook 模型:
|
195
|
-
- 类型:`
|
194
|
+
- Hook 模型:Workflow
|
195
|
+
- 类型:`Workflow<void, void>`
|
196
196
|
- 使用示例:
|
197
197
|
|
198
198
|
```ts
|
@@ -209,6 +209,10 @@ export default (): CliPlugin => ({
|
|
209
209
|
});
|
210
210
|
```
|
211
211
|
|
212
|
+
:::tip
|
213
|
+
由于 Node.js 中退出进程时的回调函数是同步的,所以 `beforeExit` Hook 的类型是 `Workflow`,不能执行异步操作。
|
214
|
+
:::
|
215
|
+
|
212
216
|
### `beforeDev`
|
213
217
|
|
214
218
|
- 功能:运行 dev 主流程的之前的任务
|
@@ -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/modern.config.ts
CHANGED