@modern-js/main-doc 2.10.0 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- 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