@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.
Files changed (61) hide show
  1. package/docs/en/apis/app/hooks/src/app.mdx +20 -34
  2. package/docs/en/apis/app/hooks/src/modern.runtime.mdx +9 -0
  3. package/docs/en/apis/app/runtime/app/define-config.mdx +6 -0
  4. package/docs/en/apis/app/runtime/web-server/hook.mdx +5 -0
  5. package/docs/en/apis/app/runtime/web-server/middleware.mdx +2 -23
  6. package/docs/en/components/enable-micro-frontend.mdx +20 -3
  7. package/docs/en/components/micro-runtime-config.mdx +12 -13
  8. package/docs/en/components/reduck-notify.mdx +27 -0
  9. package/docs/en/components/runtime-cli-config.mdx +0 -0
  10. package/docs/en/configure/app/runtime/0-intro.mdx +66 -90
  11. package/docs/en/configure/app/usage.mdx +93 -69
  12. package/docs/en/guides/advanced-features/web-server.mdx +38 -102
  13. package/docs/en/guides/basic-features/render/_meta.json +1 -1
  14. package/docs/en/guides/basic-features/render/before-render.mdx +115 -0
  15. package/docs/en/guides/basic-features/routes.mdx +0 -95
  16. package/docs/en/guides/topic-detail/micro-frontend/c02-development.mdx +3 -5
  17. package/docs/en/guides/topic-detail/micro-frontend/c03-main-app.mdx +4 -2
  18. package/docs/en/guides/topic-detail/model/auto-actions.mdx +0 -4
  19. package/docs/en/guides/topic-detail/model/computed-state.mdx +0 -5
  20. package/docs/en/guides/topic-detail/model/define-model.mdx +0 -4
  21. package/docs/en/guides/topic-detail/model/faq.mdx +0 -5
  22. package/docs/en/guides/topic-detail/model/manage-effects.mdx +0 -5
  23. package/docs/en/guides/topic-detail/model/model-communicate.mdx +0 -5
  24. package/docs/en/guides/topic-detail/model/performance.mdx +0 -4
  25. package/docs/en/guides/topic-detail/model/quick-start.mdx +5 -7
  26. package/docs/en/guides/topic-detail/model/redux-integration.mdx +0 -4
  27. package/docs/en/guides/topic-detail/model/typescript-best-practice.mdx +0 -4
  28. package/docs/en/guides/topic-detail/model/use-model.mdx +0 -5
  29. package/docs/en/guides/topic-detail/model/use-out-of-modernjs.mdx +0 -4
  30. package/docs/zh/apis/app/hooks/src/app.mdx +18 -26
  31. package/docs/zh/apis/app/hooks/src/modern.runtime.mdx +9 -0
  32. package/docs/zh/apis/app/runtime/app/define-config.mdx +5 -0
  33. package/docs/zh/apis/app/runtime/web-server/hook.mdx +4 -0
  34. package/docs/zh/apis/app/runtime/web-server/middleware.mdx +2 -23
  35. package/docs/zh/components/enable-micro-frontend.mdx +19 -12
  36. package/docs/zh/components/micro-runtime-config.mdx +3 -3
  37. package/docs/zh/components/reduck-notify.mdx +27 -0
  38. package/docs/zh/components/runtime-cli-config.mdx +0 -0
  39. package/docs/zh/configure/app/runtime/0-intro.mdx +71 -86
  40. package/docs/zh/configure/app/usage.mdx +44 -21
  41. package/docs/zh/guides/advanced-features/web-server.mdx +35 -97
  42. package/docs/zh/guides/basic-features/render/_meta.json +1 -1
  43. package/docs/zh/guides/basic-features/render/before-render.mdx +115 -0
  44. package/docs/zh/guides/basic-features/routes.mdx +0 -95
  45. package/docs/zh/guides/topic-detail/micro-frontend/c02-development.mdx +3 -5
  46. package/docs/zh/guides/topic-detail/micro-frontend/c03-main-app.mdx +4 -2
  47. package/docs/zh/guides/topic-detail/model/auto-actions.mdx +0 -4
  48. package/docs/zh/guides/topic-detail/model/computed-state.mdx +0 -4
  49. package/docs/zh/guides/topic-detail/model/define-model.mdx +1 -4
  50. package/docs/zh/guides/topic-detail/model/faq.mdx +0 -5
  51. package/docs/zh/guides/topic-detail/model/manage-effects.mdx +0 -4
  52. package/docs/zh/guides/topic-detail/model/model-communicate.mdx +1 -4
  53. package/docs/zh/guides/topic-detail/model/performance.mdx +0 -4
  54. package/docs/zh/guides/topic-detail/model/quick-start.mdx +7 -8
  55. package/docs/zh/guides/topic-detail/model/redux-integration.mdx +0 -4
  56. package/docs/zh/guides/topic-detail/model/typescript-best-practice.mdx +0 -4
  57. package/docs/zh/guides/topic-detail/model/use-model.mdx +0 -5
  58. package/docs/zh/guides/topic-detail/model/use-out-of-modernjs.mdx +0 -4
  59. package/package.json +1 -1
  60. package/docs/en/configure/app/server/enable-framework-ext.mdx +0 -49
  61. 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
- 此节将介绍 Runtime 插件的配置。
9
-
10
- ## 配置方式
11
-
12
- ### runtime
13
-
14
- - **类型:** `Object`
5
+ :::info
6
+ 如果项目中还没有此文件,请执行以下命令创建:
15
7
 
16
- runtime 配置方式如下:
8
+ ```bash
9
+ touch src/modern.runtime.ts
10
+ ```
17
11
 
18
- #### 基本用法
12
+ :::
19
13
 
20
- `modern.config.ts` 中配置
14
+ ## 基本配置
21
15
 
22
- ```ts title="modern.config.ts"
23
- import { defineConfig } from '@modern-js/app-tools';
16
+ ```tsx
17
+ import { defineRuntimeConfig } from '@modern-js/runtime';
24
18
 
25
- export default defineConfig({
26
- runtime: {
27
- state: true,
28
- router: true,
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
- 通过 [`defineConfig`](/apis/app/runtime/app/define-config) API 配置:
32
+ 对于多入口应用,`defineRuntimeConfig` 函数可以根据入口名称返回特定的配置:
36
33
 
37
- :::info
38
- runtime 配置中存在函数时,只能使用该方式进行配置。
39
-
40
- :::
34
+ ```tsx
35
+ import { defineRuntimeConfig } from '@modern-js/runtime';
41
36
 
42
- import { Tabs, Tab as TabItem } from "@theme";
43
-
44
- <Tabs>
45
- <TabItem value="layout" label="约定式路由" default>
46
-
47
- ```tsx title="src/routes/layout.tsx"
48
- import type { AppConfig } from '@modern-js/runtime';
49
-
50
- export const config = (): AppConfig => {
51
- return {
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
- defineConfig(App, {
71
- router: {
72
- supportHtml5History: false,
73
- },
49
+ // 其他入口的配置
50
+ return {
51
+ masterApp: {
52
+ // 微前端配置示例
53
+ },
54
+ };
74
55
  });
75
-
76
- export default App;
77
56
  ```
78
57
 
79
- </TabItem>
80
- </Tabs>
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
- defineConfig 中只能定义 Runtime 插件的具体配置内容,确认是否开启插件还需要通过 `modern.config.ts` 中的配置决定。
91
-
63
+ 使用 `src/modern.runtime.ts` 配置方式需要 Modern.js 版本 **MAJOR_VERSION.66.0** 或更高版本。
92
64
  :::
93
65
 
94
- ### runtimeByEntries
66
+ import RuntimeCliConfig from '@site-docs/components/runtime-cli-config';
67
+
68
+ <RuntimeCliConfig />
95
69
 
96
- - **类型:** `Object`
97
- - **默认值:**无
70
+ ## 配置方式演进
98
71
 
99
- #### 说明
72
+ MAJOR_VERSION.66.0 之前,运行时配置分散在多个位置:
100
73
 
101
- 按入口添加 runtime 配置,选项属性同 runtime 一致,指定值会和 runtime 属性内容做替换合并操作。
74
+ 1. `modern.config.ts` 中的 `runtime` `runtimeByEntries` 字段
75
+ 2. 各入口的 `App.config` 或 `layout` 文件导出的 `config` 函数
102
76
 
103
- ```ts title="modern.config.ts"
104
- import { defineConfig } from '@modern-js/app-tools';
77
+ 为提升可维护性,Modern.js 引入了统一的 `src/modern.runtime.ts` 配置入口。
105
78
 
106
- export default defineConfig({
79
+ ### 旧配置方式(兼容但不推荐)
80
+
81
+ ```ts
82
+ // modern.config.ts
83
+ export default {
107
84
  runtime: {
108
- state: false,
85
+ /* ... */
109
86
  },
110
87
  runtimeByEntries: {
111
- entry1: {
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
- 服务端运行时配置可以在根路径下的 `modern.server-runtime.config.(ts|js|mjs)` 中进行配置。
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
- ### modern.config.ts(推荐)
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
- ### modern.config.js
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
- ## 在 package.json 中配置(不推荐)
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
- 一些开发者可能会有疑惑,Modern.js 已经提供了 [BFF 能力](/guides/advanced-features/bff/function.html),为什么还需要**自定义 Web Server**。
9
+ Modern.js 提供了 **渲染中间件(Middleware)** 与**生命周期钩子(Hook)** 两类 API 来扩展 Web Server
10
10
 
11
- 因为在默认情况下,页面路由并不会经过 BFF,它没有办法为页面访问提供服务端的定制逻辑。之所以这样设计,是因为我们不希望控制页面的服务与 BFF 服务绑定在一起,避免 BFF 的框架限制页面的部署方式。例如将页面与 BFF 分开托管、将页面服务部署到非 Node 的环境上,或是针对部署平台做定制等。
12
-
13
- 出于上述原因,Modern.js 提供了三种方式,让项目可以在根据需求,渐进式的定制服务端能力。
14
-
15
- :::warning
16
- 三种扩展方式无法同时工作,开发者需要根据场景选择合适的方式。
11
+ :::note
12
+ Middleware 与 Hook 只会在用户请求页面路由时生效,BFF 路由不会经过这些 API。
17
13
  :::
18
14
 
19
- ## 使用 API 扩展 Web Server
20
-
21
- 第一种方式是通过 Modern.js 提供的服务端运行时 API,在特定的生命周期对服务端进行定制。提供这种方式的目的是在部分情况下,开发者并不需要控制完整的 Web Server,只需要添加服务端逻辑即可。
15
+ ## 开启自定义 Web Server
22
16
 
23
- 这种方式无法控制完整的 Web Server,并且扩展逻辑**只在请求页面时生效**。因此,它适用于服务端逻辑相对简单,不希望额外创建 BFF 或者 BFF 和页面无需公用服务端逻辑场景。
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` 文件,可以在这个文件中编写自定义逻辑。Modern.js 提供了 **Hook** 与 **Middleware** 两类 API 来扩展 Web Server。
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
- ```ts
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 将提供新 Middleware 为 Web Server 添加前置中间件,支持在处理页面的前后执行自定义逻辑。
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
- :::note
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
- ## 通过 BFF 托管页面请求
65
+ ### Hook
139
66
 
140
- 第二种方式,是利用 BFF 来托管页面渲染,这种方式下,所有的请求都会先打到 BFF 的服务。
67
+ :::warning
68
+ 我们推荐使用 UnstableMiddleware 代替 Hook。
69
+ :::
141
70
 
142
- 因为这种方式可以通过 BFF 统一控制所有请求的服务端逻辑。因此,它适用于服务端逻辑复杂,BFF 和页面需要公用服务端逻辑的场景。但它整体还是依托于 Modern.js Web Server 运行,无法将逻辑运行在已有的服务上。
71
+ Modern.js 提供的 Hook 用于控制 Web Server 中的特定逻辑,所有的页面请求都会经过 Hook。
143
72
 
144
- 使用这种方式,我们需要先通过 `pnpm new` 开启「BFF」功能。然后在配置文件中添加 [`bff.enableHandleWeb`](/configure/app/bff/enable-handle-web.html) 配置:
73
+ 目前提供了两种 Hook,分别是 `AfterMatch` `AfterRender`,开发者可以在 `server/index.ts` 中这样写:
145
74
 
146
75
  ```ts
147
- export default defineConfig({
148
- bff: {
149
- enableHandleWeb: true,
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
- 当该值设置为 `true` 时,页面请求流量也会经过 BFF,并且 Modern.js 内置的页面渲染的逻辑默认会作为 BFF 服务的最后一个中间件运行。
90
+ 项目在使用 Hook 时,应该有以下最佳实践:
155
91
 
156
- ## 完全自定义的 Web Server
92
+ 1. afterMatch 中做权限校验。
93
+ 2. 在 afterMatch 做 Rewrite 和 Redirect。
94
+ 3. 在 afterRender 中做 HTML 内容注入。
157
95
 
158
- :::note
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
+ :::