@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.
Files changed (42) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/docs/en/apis/app/hooks/src/server.mdx +1 -28
  3. package/docs/en/configure/app/source/config-dir.mdx +2 -2
  4. package/docs/en/configure/app/source/design-system.mdx +2 -2
  5. package/docs/en/configure/app/source/disable-default-entries.mdx +12 -12
  6. package/docs/en/configure/app/source/disable-entry-dirs.mdx +3 -4
  7. package/docs/en/configure/app/source/enable-async-entry.mdx +2 -2
  8. package/docs/en/configure/app/source/entries-dir.mdx +10 -10
  9. package/docs/en/configure/app/source/entries.mdx +83 -26
  10. package/docs/en/configure/app/source/plugin-import.mdx +13 -0
  11. package/docs/en/configure/app/source/transform-import.mdx +13 -0
  12. package/docs/en/configure/app/tools/esbuild.mdx +9 -4
  13. package/docs/en/configure/app/tools/jest.mdx +2 -3
  14. package/docs/en/configure/app/tools/swc.mdx +6 -2
  15. package/docs/en/guides/advanced-features/ssr.mdx +4 -3
  16. package/docs/en/guides/advanced-features/web-server.mdx +1 -1
  17. package/docs/en/guides/concept/entries.mdx +130 -39
  18. package/docs/en/guides/topic-detail/framework-plugin/hook-list.mdx +7 -3
  19. package/docs/en/guides/topic-detail/model/typescript-best-practice.mdx +4 -4
  20. package/docs/en/tutorials/first-app/c06-model.mdx +15 -12
  21. package/docs/en/tutorials/first-app/c07-container.mdx +22 -19
  22. package/docs/zh/apis/app/hooks/src/server.mdx +1 -28
  23. package/docs/zh/configure/app/source/config-dir.mdx +2 -2
  24. package/docs/zh/configure/app/source/design-system.mdx +3 -3
  25. package/docs/zh/configure/app/source/disable-default-entries.mdx +11 -10
  26. package/docs/zh/configure/app/source/disable-entry-dirs.mdx +2 -3
  27. package/docs/zh/configure/app/source/enable-async-entry.mdx +3 -3
  28. package/docs/zh/configure/app/source/entries-dir.mdx +10 -11
  29. package/docs/zh/configure/app/source/entries.mdx +84 -23
  30. package/docs/zh/configure/app/source/plugin-import.mdx +13 -0
  31. package/docs/zh/configure/app/source/transform-import.mdx +13 -0
  32. package/docs/zh/configure/app/tools/esbuild.mdx +9 -5
  33. package/docs/zh/configure/app/tools/jest.mdx +2 -3
  34. package/docs/zh/configure/app/tools/swc.mdx +6 -2
  35. package/docs/zh/guides/advanced-features/ssr.mdx +6 -3
  36. package/docs/zh/guides/advanced-features/web-server.mdx +10 -5
  37. package/docs/zh/guides/concept/entries.mdx +36 -35
  38. package/docs/zh/guides/topic-detail/framework-plugin/hook-list.mdx +6 -2
  39. package/docs/zh/tutorials/first-app/c06-model.mdx +14 -12
  40. package/docs/zh/tutorials/first-app/c07-container.mdx +22 -19
  41. package/modern.config.ts +1 -1
  42. 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
- - **类型:** `Object = { [ entryName: string ]: string | Object }`
8
- - **默认值:** 根据当前项目目录结构动态结算出的默认入口对象。
5
+ # source.entries
9
6
 
10
- 对于大部分场景,Modern.js 根据目录结构自动生成的入口能满足大部分业务需求。具体可参考[入口](/guides/concept/entries)。
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
- 当值为 `string` 类型时,为入口的文件路径:
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.js',
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
- 结合上面默认入口机制的内容,Modern.js 在分析上述目录结构时,不会得到任何默认入口。
63
+ 上述目录不符合 Modern.js 的目录结构约定,因此,Modern.js 在分析目录结构时,不会得到任何默认入口。
45
64
 
46
65
  在不想改变目录结构的情况下(如项目迁移),可以通过 `source.entries` 自定义入口:
47
66
 
48
- ```ts title="modern.config.js"
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/App.jsx',
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
- 默认情况下,配置的入口等价于 `App.[jt]sx`,如果希望该入口等价于构建模式下的入口,可以将属性 `disableMount` 设置为 `true`。
147
+ ## 入口合并规则
87
148
 
88
- ## 自定义入口和默认入口合并
149
+ 在设置 `source.entries` 后,如果没有设置 `disableDefaultEntries: true`,Modern.js 会将自定义入口与分析目录结构得到的入口合并。
89
150
 
90
- 在指定 `source.entries` 后,Modern.js 会将用户自定义的入口与分析目录结构得到的默认入口合并。合并规则为:
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.jsx
161
+ │ │ └── App.tsx
101
162
  │ └── home
102
- │ └── index.js
163
+ │ └── index.ts
103
164
  └── package.json
104
165
  ```
105
166
 
106
- Modern.js 分析 `src/` 目录,得到默认入口 `chat` 和 `home`。当用户在 `modern.config.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.js',
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.jsx`
123
- - `index -> ./src/home/index.js`
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
- # esbuild
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,9 +1,8 @@
1
1
  ---
2
- title: tools.jest
3
-
4
2
  sidebar_label: jest
5
3
  ---
6
- # jest
4
+
5
+ # tools.jest
7
6
 
8
7
  - **类型:** `Object | Function`
9
8
  - **默认值:** `{}`
@@ -1,8 +1,8 @@
1
1
  ---
2
- title: tools.swc
3
2
  sidebar_label: swc
4
3
  ---
5
- # swc
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
- ```jsx
151
+ ```tsx title="page.loader.ts"
151
152
  import { useLoaderData } from '@modern-js/runtime/router';
152
153
 
153
- export const loader = async () => {
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 { AfterMatchHook, AfterRenderHook } from '@modern-js/runtime/server';
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 { source: { req, res } } = context;
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
- 入口是 Modern.js 默认的文件约定,项目的每一个入口是一张独立的页面,对应一条**服务端路由**。
7
+ 通过本章节,你可以了解到 Modern.js 中的入口约定,以及如何自定义入口。
8
8
 
9
- 很多配置,如 HTML 模板、Meta 信息、是否开启 SSR、SSG、服务端路由规则都是以入口为维度划分的。
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 可以很方便的将单入口切换成多入口。可以在项目下执行 `pnpm run new`,通过生成器创建入口:
33
+ Modern.js 项目中,你可以很方便的将单入口切换成多入口,直接在项目下执行 `pnpm run new`,通过生成器创建入口即可:
31
34
 
32
35
  ```bash
33
- ? 请选择你想要的操作 创建工程元素
34
- ? 创建工程元素 新建「应用入口」
35
- ? 请填写入口名称 new-entry
36
+ ? 请选择你想要的操作:创建工程元素
37
+ ? 创建工程元素:新建「应用入口」
38
+ ? 请填写入口名称:new-entry
36
39
  ```
37
40
 
38
- 执行后,`src/` 目录将会变成如下结构:
41
+ 执行后,Modern.js 会自动生成一个新的入口目录,此时可以看到 `src/` 目录变成如下结构:
39
42
 
40
- ```
43
+ ```bash
41
44
  .
42
- ├── modern-app-env.d.ts
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` 后,可以看到新增一条 `/new-entry` 的路由,并且被迁移的代码路由并未发生变化。
59
+ 执行 `pnpm run dev` 后,可以看到新增了一条名为 `/new-entry` 的路由,并且被迁移的代码路由并未发生变化。
60
+
61
+ :::tip
62
+ Modern.js 会将与 package.json 文件中 `name` 字段同名的入口作为主入口,主入口的路由为 `/`,其他入口的路由为 `/{entryName}`。
58
63
 
59
- :::note
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
- 单入口默认的入口名为 `main`。
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
- 有些时候,已有的项目并不是按照 Modern.js 的目录结构来搭建的。如果强行要按照这种结构来工作,会有比较大的迁移成本。
177
+ 大部分存量项目并不是按照 Modern.js 的目录结构来搭建的。如果要改成 Modern.js 约定的目录结构,会存在一定的迁移成本。
174
178
 
175
- Modern.js 中,除了使用文件约定生成入口外,还可以在 `modern.config.[jt]s` 中手动配置入口。
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.js',
186
+ entry_customize: './src/home/test/index.ts',
183
187
  },
188
+ // 禁用默认入口扫描
189
+ disableDefaultEntries: true,
184
190
  },
185
191
  });
186
192
  ```
187
193
 
188
- :::tip
189
- 详情可以查看 [source.entries](/configure/app/source/entries)。
190
-
191
- :::
192
-
193
- ## 禁用默认入口扫描
194
+ ### 禁用默认入口扫描
194
195
 
195
- 另外,项目的部分结构可能恰巧命中了 Modern.js 的约定,但实际上这部分并不是真实的入口。
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
- 详情可以查看 [source.disableDefaultEntries](/configure/app/source/disable-default-entries)。
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 模型:AsyncWorkflow
195
- - 类型:`AsyncWorkflow<void, void>`
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
- ```tsx
201
- import { Helmet } from '@modern-js/runtime/head';
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 const loader = async (): Promise<LoaderData> => {
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
- ```tsx
19
- import { name, internet } from 'faker';
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 const loader = async (): Promise<LoaderData> => {
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
@@ -152,5 +152,5 @@ export default defineConfig({
152
152
  }),
153
153
  ],
154
154
  },
155
- plugins: [docTools()],
155
+ plugins: [docTools({})],
156
156
  });