@modern-js/main-doc 2.66.0 → 2.66.1-alpha.1
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/docs/en/apis/app/hooks/src/app.mdx +20 -34
- package/docs/en/apis/app/hooks/src/modern.runtime.mdx +9 -0
- package/docs/en/apis/app/runtime/app/define-config.mdx +6 -0
- package/docs/en/apis/app/runtime/web-server/hook.mdx +5 -0
- package/docs/en/apis/app/runtime/web-server/middleware.mdx +2 -23
- package/docs/en/components/enable-micro-frontend.mdx +20 -3
- package/docs/en/components/micro-runtime-config.mdx +12 -13
- package/docs/en/components/reduck-notify.mdx +27 -0
- package/docs/en/components/runtime-cli-config.mdx +0 -0
- package/docs/en/configure/app/runtime/0-intro.mdx +66 -90
- package/docs/en/configure/app/usage.mdx +93 -69
- package/docs/en/guides/advanced-features/web-server.mdx +38 -102
- package/docs/en/guides/basic-features/render/_meta.json +1 -1
- package/docs/en/guides/basic-features/render/before-render.mdx +115 -0
- package/docs/en/guides/basic-features/routes.mdx +0 -95
- package/docs/en/guides/topic-detail/micro-frontend/c02-development.mdx +3 -5
- package/docs/en/guides/topic-detail/micro-frontend/c03-main-app.mdx +4 -2
- package/docs/en/guides/topic-detail/model/auto-actions.mdx +0 -4
- package/docs/en/guides/topic-detail/model/computed-state.mdx +0 -5
- package/docs/en/guides/topic-detail/model/define-model.mdx +0 -4
- package/docs/en/guides/topic-detail/model/faq.mdx +0 -5
- package/docs/en/guides/topic-detail/model/manage-effects.mdx +0 -5
- package/docs/en/guides/topic-detail/model/model-communicate.mdx +0 -5
- package/docs/en/guides/topic-detail/model/performance.mdx +0 -4
- package/docs/en/guides/topic-detail/model/quick-start.mdx +5 -7
- package/docs/en/guides/topic-detail/model/redux-integration.mdx +0 -4
- package/docs/en/guides/topic-detail/model/typescript-best-practice.mdx +0 -4
- package/docs/en/guides/topic-detail/model/use-model.mdx +0 -5
- package/docs/en/guides/topic-detail/model/use-out-of-modernjs.mdx +0 -4
- package/docs/zh/apis/app/hooks/src/app.mdx +18 -26
- package/docs/zh/apis/app/hooks/src/modern.runtime.mdx +9 -0
- package/docs/zh/apis/app/runtime/app/define-config.mdx +5 -0
- package/docs/zh/apis/app/runtime/web-server/hook.mdx +4 -0
- package/docs/zh/apis/app/runtime/web-server/middleware.mdx +2 -23
- package/docs/zh/components/enable-micro-frontend.mdx +19 -12
- package/docs/zh/components/micro-runtime-config.mdx +3 -3
- package/docs/zh/components/reduck-notify.mdx +27 -0
- package/docs/zh/components/runtime-cli-config.mdx +0 -0
- package/docs/zh/configure/app/runtime/0-intro.mdx +71 -86
- package/docs/zh/configure/app/usage.mdx +44 -21
- package/docs/zh/guides/advanced-features/web-server.mdx +35 -97
- package/docs/zh/guides/basic-features/render/_meta.json +1 -1
- package/docs/zh/guides/basic-features/render/before-render.mdx +115 -0
- package/docs/zh/guides/basic-features/routes.mdx +0 -95
- package/docs/zh/guides/topic-detail/micro-frontend/c02-development.mdx +3 -5
- package/docs/zh/guides/topic-detail/micro-frontend/c03-main-app.mdx +4 -2
- package/docs/zh/guides/topic-detail/model/auto-actions.mdx +0 -4
- package/docs/zh/guides/topic-detail/model/computed-state.mdx +0 -4
- package/docs/zh/guides/topic-detail/model/define-model.mdx +1 -4
- package/docs/zh/guides/topic-detail/model/faq.mdx +0 -5
- package/docs/zh/guides/topic-detail/model/manage-effects.mdx +0 -4
- package/docs/zh/guides/topic-detail/model/model-communicate.mdx +1 -4
- package/docs/zh/guides/topic-detail/model/performance.mdx +0 -4
- package/docs/zh/guides/topic-detail/model/quick-start.mdx +7 -8
- package/docs/zh/guides/topic-detail/model/redux-integration.mdx +0 -4
- package/docs/zh/guides/topic-detail/model/typescript-best-practice.mdx +0 -4
- package/docs/zh/guides/topic-detail/model/use-model.mdx +0 -5
- package/docs/zh/guides/topic-detail/model/use-out-of-modernjs.mdx +0 -4
- package/package.json +1 -1
- package/docs/en/configure/app/server/enable-framework-ext.mdx +0 -49
- package/docs/zh/configure/app/server/enable-framework-ext.mdx +0 -49
@@ -1,120 +1,105 @@
|
|
1
|
-
|
2
|
-
title: 总览
|
3
|
-
sidebar_position: 1
|
4
|
-
---
|
1
|
+
# 介绍
|
5
2
|
|
6
|
-
|
3
|
+
Modern.js 的运行时(Runtime)配置需集中在 `src/modern.runtime.ts` 文件中声明。
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
## 配置方式
|
11
|
-
|
12
|
-
### runtime
|
13
|
-
|
14
|
-
- **类型:** `Object`
|
5
|
+
:::info
|
6
|
+
如果项目中还没有此文件,请执行以下命令创建:
|
15
7
|
|
16
|
-
|
8
|
+
```bash
|
9
|
+
touch src/modern.runtime.ts
|
10
|
+
```
|
17
11
|
|
18
|
-
|
12
|
+
:::
|
19
13
|
|
20
|
-
|
14
|
+
## 基本配置
|
21
15
|
|
22
|
-
```
|
23
|
-
import {
|
16
|
+
```tsx
|
17
|
+
import { defineRuntimeConfig } from '@modern-js/runtime';
|
24
18
|
|
25
|
-
export default
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
export default defineRuntimeConfig({
|
20
|
+
router: {
|
21
|
+
// 路由配置
|
22
|
+
},
|
23
|
+
state: {
|
24
|
+
// 状态管理配置
|
29
25
|
},
|
26
|
+
// 其他运行时模块...
|
30
27
|
});
|
31
28
|
```
|
32
29
|
|
33
|
-
|
30
|
+
## 多入口配置
|
34
31
|
|
35
|
-
|
32
|
+
对于多入口应用,`defineRuntimeConfig` 函数可以根据入口名称返回特定的配置:
|
36
33
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
:::
|
34
|
+
```tsx
|
35
|
+
import { defineRuntimeConfig } from '@modern-js/runtime';
|
41
36
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
router: {
|
53
|
-
supportHtml5History: false
|
54
|
-
}
|
37
|
+
export default defineRuntimeConfig(entryName => {
|
38
|
+
if (entryName === 'main') {
|
39
|
+
return {
|
40
|
+
router: {
|
41
|
+
// "main" 入口的路由配置
|
42
|
+
},
|
43
|
+
state: {
|
44
|
+
// "main" 入口的状态管理配置
|
45
|
+
},
|
46
|
+
};
|
55
47
|
}
|
56
|
-
};
|
57
|
-
```
|
58
|
-
|
59
|
-
</TabItem>
|
60
|
-
|
61
|
-
<TabItem value="app" label="自控路由">
|
62
|
-
|
63
|
-
```ts title="src/App.tsx"
|
64
|
-
import { defineConfig } from '@modern-js/runtime';
|
65
|
-
|
66
|
-
const App = () => {
|
67
|
-
/** */
|
68
|
-
};
|
69
48
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
49
|
+
// 其他入口的配置
|
50
|
+
return {
|
51
|
+
masterApp: {
|
52
|
+
// 微前端配置示例
|
53
|
+
},
|
54
|
+
};
|
74
55
|
});
|
75
|
-
|
76
|
-
export default App;
|
77
56
|
```
|
78
57
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
:::info
|
83
|
-
使用运行时配置,可以解决 Runtime 插件配置需要在运行时才能获取到具体内容问题。
|
84
|
-
|
85
|
-
Runtime 插件运行时配置和直接在 `modern.config.ts` 中的配置默认会进行合并,且运行时配置优先级更高。
|
86
|
-
|
58
|
+
:::tip
|
59
|
+
使用 `src/modern.runtime.ts` 配置方式不支持导出异步函数,这与 Modern.js 的渲染方式有关。如果需要添加异步逻辑,请使用 **[Runtime 插件 (Runtime Plugin)](/plugin/introduction.html#runtime-插件)**。
|
87
60
|
:::
|
88
61
|
|
89
62
|
:::warning
|
90
|
-
|
91
|
-
|
63
|
+
使用 `src/modern.runtime.ts` 配置方式需要 Modern.js 版本 **MAJOR_VERSION.66.0** 或更高版本。
|
92
64
|
:::
|
93
65
|
|
94
|
-
|
66
|
+
import RuntimeCliConfig from '@site-docs/components/runtime-cli-config';
|
67
|
+
|
68
|
+
<RuntimeCliConfig />
|
95
69
|
|
96
|
-
|
97
|
-
- **默认值:**无
|
70
|
+
## 配置方式演进
|
98
71
|
|
99
|
-
|
72
|
+
在 MAJOR_VERSION.66.0 之前,运行时配置分散在多个位置:
|
100
73
|
|
101
|
-
|
74
|
+
1. `modern.config.ts` 中的 `runtime` 和 `runtimeByEntries` 字段
|
75
|
+
2. 各入口的 `App.config` 或 `layout` 文件导出的 `config` 函数
|
102
76
|
|
103
|
-
|
104
|
-
import { defineConfig } from '@modern-js/app-tools';
|
77
|
+
为提升可维护性,Modern.js 引入了统一的 `src/modern.runtime.ts` 配置入口。
|
105
78
|
|
106
|
-
|
79
|
+
### 旧配置方式(兼容但不推荐)
|
80
|
+
|
81
|
+
```ts
|
82
|
+
// modern.config.ts
|
83
|
+
export default {
|
107
84
|
runtime: {
|
108
|
-
|
85
|
+
/* ... */
|
109
86
|
},
|
110
87
|
runtimeByEntries: {
|
111
|
-
|
112
|
-
state: true, // { state: true }
|
113
|
-
},
|
114
|
-
entry2: {
|
115
|
-
// { state: false, router: true }
|
116
|
-
router: true,
|
117
|
-
},
|
88
|
+
/* ... */
|
118
89
|
},
|
119
|
-
}
|
90
|
+
};
|
91
|
+
|
92
|
+
// App.config
|
93
|
+
App.config = {
|
94
|
+
/* ... */
|
95
|
+
};
|
96
|
+
|
97
|
+
// layout 文件
|
98
|
+
export const config = () => {
|
99
|
+
/* 动态配置逻辑 */
|
100
|
+
};
|
120
101
|
```
|
102
|
+
|
103
|
+
### 迁移建议
|
104
|
+
|
105
|
+
强烈建议将所有运行时配置迁移至 `src/modern.runtime.ts`。虽然旧配置方式目前仍兼容,但计划在未来版本中逐步废弃。统一配置入口可避免配置分散,显著提高项目可维护性。
|
@@ -1,12 +1,8 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 0
|
3
|
-
---
|
4
|
-
|
5
1
|
# 配置使用
|
6
2
|
|
7
|
-
Modern.js
|
3
|
+
Modern.js 中有三种配置,分别是编译时配置、运行时配置和服务端运行时配置。
|
8
4
|
|
9
|
-
|
5
|
+
**编译时配置**可以在两个位置进行配置:
|
10
6
|
|
11
7
|
- 根路径下的 `modern.config.(ts|js|mjs)` 文件
|
12
8
|
- `package.json` 文件
|
@@ -15,9 +11,14 @@ Modern.js 中有两种配置,分别是编译时配置和服务端运行时配
|
|
15
11
|
Modern.js 不支持同时在 `package.json` 中和 `modern.config.ts` 中配置同一个配置项,推荐在 `modern.config.ts` 中进行配置。如果 Modern.js 检测到重复配置导致的冲突,将会抛出警告。
|
16
12
|
:::
|
17
13
|
|
18
|
-
|
14
|
+
**运行时配置**可以在 `src/modern.runtime.(ts|js|mjs)` 文件中配置。
|
15
|
+
|
16
|
+
{/* TODO server 配置文件更新 */}
|
17
|
+
**服务端运行时配置**可以在根路径下的 `modern.server-runtime.config.(ts|js|mjs)` 中进行配置。
|
19
18
|
|
20
|
-
##
|
19
|
+
## 编译时配置
|
20
|
+
|
21
|
+
### 在配置文件中配置
|
21
22
|
|
22
23
|
Modern.js 的配置文件定义在项目的根目录下,支持 `.ts`, `.js` 和 `.mjs` 格式:
|
23
24
|
|
@@ -25,7 +26,7 @@ Modern.js 的配置文件定义在项目的根目录下,支持 `.ts`, `.js`
|
|
25
26
|
- `modern.config.js`
|
26
27
|
- `modern.config.mjs`
|
27
28
|
|
28
|
-
|
29
|
+
#### modern.config.ts(推荐)
|
29
30
|
|
30
31
|
我们推荐使用 `.ts` 格式的配置文件,它提供了友好的 TypeScript 类型提示,从而帮助你避免配置中的错误。
|
31
32
|
|
@@ -52,7 +53,7 @@ export default defineConfig({
|
|
52
53
|
});
|
53
54
|
```
|
54
55
|
|
55
|
-
|
56
|
+
#### modern.config.js
|
56
57
|
|
57
58
|
如果你在开发一个非 TypeScript 项目,可以使用 `.js` 格式的配置文件:
|
58
59
|
|
@@ -76,7 +77,7 @@ export default {
|
|
76
77
|
};
|
77
78
|
```
|
78
79
|
|
79
|
-
|
80
|
+
#### 导出配置函数
|
80
81
|
|
81
82
|
Modern.js 支持在配置文件中导出一个函数,你可以在函数中动态计算配置,并返回给 Modern.js。
|
82
83
|
|
@@ -99,7 +100,7 @@ export default defineConfig(({ env, command }) => ({
|
|
99
100
|
- 当运行 `modern build` 或 `modern serve` 时,`env` 的值为 `production`。
|
100
101
|
- `command`:对应当前运行的命令,如 `dev`、`start`、`build`、`serve`。
|
101
102
|
|
102
|
-
|
103
|
+
#### 导出异步函数
|
103
104
|
|
104
105
|
Modern.js 也支持在配置文件中导出一个异步函数,你可以在函数中进行一些异步操作:
|
105
106
|
|
@@ -117,7 +118,7 @@ export default defineConfig(async ({ env, command }) => {
|
|
117
118
|
});
|
118
119
|
```
|
119
120
|
|
120
|
-
|
121
|
+
#### 指定配置文件
|
121
122
|
|
122
123
|
Modern.js 命令行支持通过 `--config` 选项来指定配置文件的名称。
|
123
124
|
|
@@ -138,7 +139,7 @@ Modern.js 命令行支持通过 `--config` 选项来指定配置文件的名称
|
|
138
139
|
$ modern build -c modern.prod.config.js
|
139
140
|
```
|
140
141
|
|
141
|
-
|
142
|
+
### 在 package.json 中配置(不推荐)
|
142
143
|
|
143
144
|
除了配置文件外,你也可以在 `package.json` 中的 `modernConfig` 字段下设置配置项,如:
|
144
145
|
|
@@ -156,16 +157,16 @@ $ modern build -c modern.prod.config.js
|
|
156
157
|
|
157
158
|
由于 JSON 文件格式的限制,`package.json` 中只能定义数字、字符串、布尔值、数组等简单类型的值,当我们需要设置函数类型的值时,建议在 Modern.js 配置文件中进行设置。
|
158
159
|
|
159
|
-
|
160
|
+
#### 注意事项
|
160
161
|
|
161
162
|
- 不建议同时使用 `package.json` 和 `modern.config.js` 进行配置。如果同时使用了两者并出现配置冲突,Modern.js 会在命令行进行提示错误。
|
162
163
|
- `@modern-js/runtime` 导出了同名的 [defineConfig](/apis/app/runtime/app/define-config) API,请注意区分。
|
163
164
|
|
164
|
-
|
165
|
+
### 本地调试配置
|
165
166
|
|
166
167
|
为了便于本地调试配置,Modern.js 支持在项目根目录下创建 `modern.config.local.(ts|js|mjs)` 文件,用于覆盖 `modern.config.(ts|js|mjs)` 中的配置选项。
|
167
168
|
|
168
|
-
|
169
|
+
#### 示例
|
169
170
|
|
170
171
|
比如,项目的 `modern.config.ts` 中配置了端口号为 `3000`:
|
171
172
|
|
@@ -193,7 +194,7 @@ export default defineConfig({
|
|
193
194
|
|
194
195
|
`modern.config.local.ts` 文件中的配置会与 `modern.config.ts` 中的配置进行深层合并,并覆盖 `modern.config.ts` 中的配置选项,因此 `server.port` 会被覆盖为 `3001`。
|
195
196
|
|
196
|
-
|
197
|
+
#### 注意事项
|
197
198
|
|
198
199
|
在使用 `modern.config.local.ts` 时,请注意以下事项:
|
199
200
|
|
@@ -205,13 +206,13 @@ export default defineConfig({
|
|
205
206
|
modern.config.local.*
|
206
207
|
```
|
207
208
|
|
208
|
-
|
209
|
+
### 合并多份配置
|
209
210
|
|
210
211
|
在某些情况下,你可能需要将多份配置合并为一份配置,此时你可以使用 `mergeConfig` 工具函数来合并多个配置。
|
211
212
|
|
212
213
|
`mergeConfig` 函数接受一个数组作为参数,数组中的每一项都是一个配置对象,`mergeConfig` 会将数组中的每一项配置对象进行深层合并,自动将多个函数项合并为数组,最终返回一个合并后的配置对象。
|
213
214
|
|
214
|
-
|
215
|
+
#### 示例
|
215
216
|
|
216
217
|
```ts title="modern.config.ts"
|
217
218
|
import { mergeConfig } from '@modern-js/app-tools';
|
@@ -249,7 +250,7 @@ const mergedConfig = {
|
|
249
250
|
};
|
250
251
|
```
|
251
252
|
|
252
|
-
|
253
|
+
### 配置类型定义
|
253
254
|
|
254
255
|
Modern.js 导出了 `AppUserConfig` 类型,对应 Modern.js 配置对象的类型:
|
255
256
|
|
@@ -274,3 +275,25 @@ const config: AppUserConfig<'rspack'> = {
|
|
274
275
|
},
|
275
276
|
};
|
276
277
|
```
|
278
|
+
|
279
|
+
## 运行时配置
|
280
|
+
|
281
|
+
运行时配置的详细信息可以参考 [Runtime 配置介绍](/configure/app/runtime/0-intro.html)。
|
282
|
+
|
283
|
+
:::tip
|
284
|
+
如果当前的 Runtime 配置需要在编译时和运行时同时使用,请将相关配置参数添加到插件注册的位置。
|
285
|
+
|
286
|
+
```ts title="modern.config.ts"
|
287
|
+
import { defineConfig } from '@modern-js/app-tools';
|
288
|
+
import { statePlugin } from '@modern-js/plugin-state';
|
289
|
+
|
290
|
+
export default defineConfig({
|
291
|
+
plugins: [
|
292
|
+
statePlugin({
|
293
|
+
/** 在此处添加参数 */
|
294
|
+
}),
|
295
|
+
],
|
296
|
+
});
|
297
|
+
```
|
298
|
+
|
299
|
+
:::
|
@@ -4,25 +4,17 @@ sidebar_position: 16
|
|
4
4
|
|
5
5
|
# 自定义 Web Server
|
6
6
|
|
7
|
-
Modern.js
|
7
|
+
Modern.js 将大部分项目需要的服务端能力都进行了封装,通常项目无需进行服务端开发。但在有些开发场景下,例如用户鉴权、请求预处理、添加页面渲染骨架等,项目仍需要对服务端进行定制。
|
8
8
|
|
9
|
-
|
9
|
+
Modern.js 提供了 **渲染中间件(Middleware)** 与**生命周期钩子(Hook)** 两类 API 来扩展 Web Server。
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
出于上述原因,Modern.js 提供了三种方式,让项目可以在根据需求,渐进式的定制服务端能力。
|
14
|
-
|
15
|
-
:::warning
|
16
|
-
三种扩展方式无法同时工作,开发者需要根据场景选择合适的方式。
|
11
|
+
:::note
|
12
|
+
Middleware 与 Hook 只会在用户请求页面路由时生效,BFF 路由不会经过这些 API。
|
17
13
|
:::
|
18
14
|
|
19
|
-
##
|
20
|
-
|
21
|
-
第一种方式是通过 Modern.js 提供的服务端运行时 API,在特定的生命周期对服务端进行定制。提供这种方式的目的是在部分情况下,开发者并不需要控制完整的 Web Server,只需要添加服务端逻辑即可。
|
15
|
+
## 开启自定义 Web Server
|
22
16
|
|
23
|
-
|
24
|
-
|
25
|
-
可以在项目根目录执行 `pnpm run new` 命令,开启「自定义 Web Serve」功能:
|
17
|
+
开发者可以在项目根目录执行 `pnpm run new` 命令,开启「自定义 Web Server」功能:
|
26
18
|
|
27
19
|
```bash
|
28
20
|
? 请选择你想要的操作 创建工程元素
|
@@ -39,78 +31,13 @@ export default defineConfig({
|
|
39
31
|
});
|
40
32
|
```
|
41
33
|
|
42
|
-
开启功能后,项目目录下会自动创建 `server/index.ts` 文件,可以在这个文件中编写自定义逻辑。
|
43
|
-
|
44
|
-
### Hook
|
45
|
-
|
46
|
-
Modern.js 提供的 Hook 用于控制 Web Server 中的内置逻辑,所有的页面请求都会经过 Hook。
|
47
|
-
|
48
|
-
目前提供了两种 Hook,分别是 `AfterMatch` 和 `AfterRender`,可以用于修改渲染结果。可以在 `server/index.ts` 中这样写:
|
34
|
+
开启功能后,项目目录下会自动创建 `server/index.ts` 文件,可以在这个文件中编写自定义逻辑。
|
49
35
|
|
50
|
-
|
51
|
-
import type {
|
52
|
-
AfterMatchHook,
|
53
|
-
AfterRenderHook,
|
54
|
-
} from '@modern-js/runtime/server';
|
55
|
-
|
56
|
-
export const afterMatch: AfterMatchHook = (ctx, next) => {
|
57
|
-
next();
|
58
|
-
};
|
59
|
-
|
60
|
-
export const afterRender: AfterRenderHook = (ctx, next) => {
|
61
|
-
next();
|
62
|
-
};
|
63
|
-
```
|
64
|
-
|
65
|
-
项目在使用 Hook 时,应该有以下最佳实践:
|
66
|
-
|
67
|
-
1. 在 afterMatch 中做权限校验。
|
68
|
-
2. 在 afterMatch 做 Rewrite 和 Redirect。
|
69
|
-
3. 在 afterRender 中做 HTML 内容注入。
|
70
|
-
|
71
|
-
:::note
|
72
|
-
详细 API 和更多用法可以查看 [Hook](/apis/app/runtime/web-server/hook)。
|
73
|
-
:::
|
74
|
-
|
75
|
-
### Middleware
|
76
|
-
|
77
|
-
对于某些项目,可能在服务端有更多的需求,Modern.js 提供了 Middleware 为 Web Server 添加前置中间件。它只能运行在 Node 环境下,因此如果项目被部署到其他环境中,如 Worker 环境,则不可以使用 Middleware。
|
78
|
-
|
79
|
-
:::note
|
80
|
-
下一个大版本,Modern.js 将会使用新 Middleware 来替代该写法。
|
81
|
-
|
82
|
-
推荐使用 [UnstableMiddleware](/guides/advanced-features/web-server.html#unstablemiddleware) 处理页面请求。
|
83
|
-
:::
|
84
|
-
|
85
|
-
Modern.js 默认提供了一套 API 供项目使用:
|
86
|
-
|
87
|
-
```ts
|
88
|
-
import { Middleware } from '@modern-js/runtime/server';
|
89
|
-
|
90
|
-
export const middleware: Middleware = (context, next) => {
|
91
|
-
const {
|
92
|
-
source: { req, res },
|
93
|
-
} = context;
|
94
|
-
console.log(req.url);
|
95
|
-
next();
|
96
|
-
};
|
97
|
-
```
|
98
|
-
|
99
|
-
:::note
|
100
|
-
详细 API 和更多用法可以查看 [Middleware](/apis/app/runtime/web-server/middleware)。
|
101
|
-
:::
|
102
|
-
|
103
|
-
项目在使用 Middleware 时,应该有以下最佳实践:
|
104
|
-
|
105
|
-
1. 在 Middleware 中可以直接操作原生的请求、响应对象,做数据打点、注入 SSR 渲染可能用到的 Node 服务(数据库、Redis 等)。
|
106
|
-
2. 在 Middleware 里可以做类似功能打标、爬虫优化等功能。
|
107
|
-
3. 在 Middleware 里可以无视后续默认渲染,自定义渲染流程。
|
108
|
-
|
109
|
-
**总的来说,CSR 项目中,使用 Hook 基本能满足简单场景的所有需求。SSR 项目中,可以使用 Middleware 做更复杂的 Node 扩展。**
|
36
|
+
## 自定义 Web Server 能力
|
110
37
|
|
111
38
|
### Unstable Middleware
|
112
39
|
|
113
|
-
Modern.js
|
40
|
+
Modern.js 支持为 Web Server 添加渲染中间件,支持在处理页面路由的前后执行自定义逻辑。
|
114
41
|
|
115
42
|
```ts title="server/index.ts"
|
116
43
|
import {
|
@@ -131,30 +58,41 @@ const time: UnstableMiddleware = async (c: UnstableMiddlewareContext, next) => {
|
|
131
58
|
export const unstableMiddleware: UnstableMiddleware[] = [time];
|
132
59
|
```
|
133
60
|
|
134
|
-
:::
|
135
|
-
详细 API 和更多用法查看 [UnstableMiddleware](/apis/app/runtime/web-server/unstable_middleware)
|
61
|
+
:::info
|
62
|
+
详细 API 和更多用法查看 [UnstableMiddleware](/apis/app/runtime/web-server/unstable_middleware)。
|
136
63
|
:::
|
137
64
|
|
138
|
-
|
65
|
+
### Hook
|
139
66
|
|
140
|
-
|
67
|
+
:::warning
|
68
|
+
我们推荐使用 UnstableMiddleware 代替 Hook。
|
69
|
+
:::
|
141
70
|
|
142
|
-
|
71
|
+
Modern.js 提供的 Hook 用于控制 Web Server 中的特定逻辑,所有的页面请求都会经过 Hook。
|
143
72
|
|
144
|
-
|
73
|
+
目前提供了两种 Hook,分别是 `AfterMatch` 和 `AfterRender`,开发者可以在 `server/index.ts` 中这样写:
|
145
74
|
|
146
75
|
```ts
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
76
|
+
import type {
|
77
|
+
AfterMatchHook,
|
78
|
+
AfterRenderHook,
|
79
|
+
} from '@modern-js/runtime/server';
|
80
|
+
|
81
|
+
export const afterMatch: AfterMatchHook = (ctx, next) => {
|
82
|
+
next();
|
83
|
+
};
|
84
|
+
|
85
|
+
export const afterRender: AfterRenderHook = (ctx, next) => {
|
86
|
+
next();
|
87
|
+
};
|
152
88
|
```
|
153
89
|
|
154
|
-
|
90
|
+
项目在使用 Hook 时,应该有以下最佳实践:
|
155
91
|
|
156
|
-
|
92
|
+
1. 在 afterMatch 中做权限校验。
|
93
|
+
2. 在 afterMatch 做 Rewrite 和 Redirect。
|
94
|
+
3. 在 afterRender 中做 HTML 内容注入。
|
157
95
|
|
158
|
-
:::
|
159
|
-
|
96
|
+
:::info
|
97
|
+
详细 API 和更多用法可以查看 [Hook](/apis/app/runtime/web-server/hook)。
|
160
98
|
:::
|
@@ -1 +1 @@
|
|
1
|
-
["ssr", "streaming-ssr", "ssr-cache", "ssg"]
|
1
|
+
["ssr", "streaming-ssr", "ssr-cache", "ssg", "before-render"]
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# 渲染预处理 (Render Preprocessing)
|
2
|
+
|
3
|
+
在某些场景下,应用需要在渲染前执行预处理操作。Modern.js 推荐使用 **[Runtime 插件 (Runtime Plugin)](/plugin/introduction.html#runtime-插件)** 来实现这类逻辑。
|
4
|
+
|
5
|
+
## 定义 Runtime 插件
|
6
|
+
|
7
|
+
```ts
|
8
|
+
import type { RuntimePluginFuture } from '@modern-js/runtime';
|
9
|
+
|
10
|
+
const myRuntimePlugin = (): RuntimePluginFuture => ({
|
11
|
+
name: 'my-runtime-plugin',
|
12
|
+
setup: (api) => {
|
13
|
+
api.onBeforeRender((context) => {
|
14
|
+
// 在渲染前执行的逻辑
|
15
|
+
console.log('Before rendering:', context);
|
16
|
+
});
|
17
|
+
},
|
18
|
+
});
|
19
|
+
|
20
|
+
export default myRuntimePlugin;
|
21
|
+
```
|
22
|
+
|
23
|
+
## 注册插件
|
24
|
+
|
25
|
+
在项目 `src/modern.runtime.ts` 文件中注册插件:
|
26
|
+
|
27
|
+
```ts
|
28
|
+
import { defineRuntimeConfig } from '@modern-js/runtime';
|
29
|
+
import myRuntimePlugin from './plugins/myRuntimePlugin';
|
30
|
+
|
31
|
+
export default defineRuntimeConfig({
|
32
|
+
plugins: [myRuntimePlugin()],
|
33
|
+
});
|
34
|
+
```
|
35
|
+
|
36
|
+
## 应用场景 -- 全局数据注入
|
37
|
+
|
38
|
+
通过 `onBeforeRender` 钩子的 `context` 参数,可以向应用注入全局数据。应用的组件可以通过 `useRuntimeContext` Hook 访问这些数据。
|
39
|
+
|
40
|
+
:::info
|
41
|
+
|
42
|
+
此功能在以下场景中特别有用:
|
43
|
+
* 需要页面级前置数据的应用
|
44
|
+
* 自定义数据注入流程
|
45
|
+
* 框架迁移场景(例如从 Next.js 迁移)
|
46
|
+
|
47
|
+
:::
|
48
|
+
|
49
|
+
**定义数据注入插件**
|
50
|
+
|
51
|
+
```ts
|
52
|
+
import type { RuntimePluginFuture } from '@modern-js/runtime';
|
53
|
+
|
54
|
+
const dataInjectionPlugin = (): RuntimePluginFuture => ({
|
55
|
+
name: 'data-injection-plugin',
|
56
|
+
setup: api => {
|
57
|
+
api.onBeforeRender(context => {
|
58
|
+
// 向 context 中注入数据
|
59
|
+
context.message = 'Hello World';
|
60
|
+
});
|
61
|
+
},
|
62
|
+
});
|
63
|
+
|
64
|
+
export default dataInjectionPlugin;
|
65
|
+
```
|
66
|
+
|
67
|
+
**在组件中使用注入的数据**
|
68
|
+
|
69
|
+
```tsx
|
70
|
+
import { useRuntimeContext } from '@modern-js/runtime';
|
71
|
+
|
72
|
+
export default function MyComponent() {
|
73
|
+
const context = useRuntimeContext();
|
74
|
+
const { message } = context;
|
75
|
+
|
76
|
+
return <div>{message}</div>;
|
77
|
+
}
|
78
|
+
```
|
79
|
+
|
80
|
+
**结合 SSR 使用**
|
81
|
+
|
82
|
+
在 SSR 场景下,浏览器端可以获取服务端渲染期间通过 `onBeforeRender` 注入的数据。开发者可以根据需求决定是否在浏览器端重新获取数据来覆盖服务端数据。
|
83
|
+
|
84
|
+
```ts
|
85
|
+
import type { RuntimePluginFuture } from '@modern-js/runtime';
|
86
|
+
|
87
|
+
const dataInjectionPlugin = (): RuntimePluginFuture => ({
|
88
|
+
name: 'data-injection-plugin',
|
89
|
+
setup: api => {
|
90
|
+
api.onBeforeRender(context => {
|
91
|
+
if (process.env.MODERN_TARGET === 'node') {
|
92
|
+
// 服务端渲染时设置数据
|
93
|
+
context.message = 'Hello World By Server';
|
94
|
+
} else {
|
95
|
+
// 客户端渲染时检查数据
|
96
|
+
if (!context.message) {
|
97
|
+
// 如果没有获取到服务端数据,则设置客户端数据
|
98
|
+
context.message = 'Hello World By Client';
|
99
|
+
}
|
100
|
+
}
|
101
|
+
});
|
102
|
+
},
|
103
|
+
});
|
104
|
+
|
105
|
+
export default dataInjectionPlugin;
|
106
|
+
```
|
107
|
+
|
108
|
+
## 兼容性说明
|
109
|
+
|
110
|
+
在 Modern.js 的早期版本中,支持通过 `routes/layout.tsx` 中的 `init` 钩子以及 `App.init` 方法来添加渲染预处理逻辑。这些方式目前仍然**被支持**,但我们**强烈推荐**使用 Runtime 插件实现。
|
111
|
+
|
112
|
+
:::warning
|
113
|
+
|
114
|
+
未来版本中,`routes/layout.tsx` 的 `init` 钩子和 `App.init` 方法将逐步**废弃**。建议尽早迁移到 Runtime 插件方案。
|
115
|
+
:::
|