@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,35 +1,37 @@
|
|
1
|
-
|
2
|
-
sidebar_position: 0
|
3
|
-
---
|
1
|
+
# Configuration
|
4
2
|
|
5
|
-
|
3
|
+
There are three types of configurations in Modern.js: Compile configuration, Runtime configuration, and Server Runtime configuration.
|
6
4
|
|
7
|
-
|
5
|
+
**Compile configuration** can be configured in two locations:
|
8
6
|
|
9
|
-
The
|
10
|
-
|
11
|
-
- `modern.config.(ts|js|mjs)` file in the root path
|
12
|
-
- `package.json` file
|
7
|
+
- The `modern.config.(ts|js|mjs)` file at the root path
|
8
|
+
- The `package.json` file
|
13
9
|
|
14
10
|
:::info
|
15
|
-
|
11
|
+
Modern.js does not support configuring the same configuration item in both `package.json` and `modern.config.ts` simultaneously. It is recommended to configure it in `modern.config.ts`. If Modern.js detects conflicts due to duplicate configurations, it will throw a warning.
|
16
12
|
:::
|
17
13
|
|
18
|
-
|
14
|
+
**Runtime configuration** can be configured in the `src/modern.runtime.(ts|js|mjs)` file.
|
15
|
+
|
16
|
+
{/* TODO server 配置文件更新 */}
|
17
|
+
**Server Runtime configuration** can be configured in the `modern.server-runtime.config.(ts|js|mjs)` file in the root path.
|
18
|
+
|
19
|
+
|
20
|
+
## Compile Configuration
|
19
21
|
|
20
|
-
|
22
|
+
### Configuring in Configuration Files
|
21
23
|
|
22
|
-
|
24
|
+
The configuration files for Modern.js are defined in the root directory of the project and support `.ts`, `.js`, and `.mjs` formats:
|
23
25
|
|
24
26
|
- `modern.config.ts`
|
25
27
|
- `modern.config.js`
|
26
28
|
- `modern.config.mjs`
|
27
29
|
|
28
|
-
|
30
|
+
#### modern.config.ts (Recommended)
|
29
31
|
|
30
|
-
We recommend using
|
32
|
+
We recommend using the `.ts` format for configuration files as it provides friendly TypeScript type hints, helping you avoid errors in the configuration.
|
31
33
|
|
32
|
-
Import the `defineConfig`
|
34
|
+
Import the `defineConfig` utility function from `@modern-js/app-tools`, which will assist you with type inference and type completion for the configuration:
|
33
35
|
|
34
36
|
```ts title="modern.config.ts"
|
35
37
|
import { defineConfig } from '@modern-js/app-tools';
|
@@ -43,18 +45,18 @@ export default defineConfig({
|
|
43
45
|
});
|
44
46
|
```
|
45
47
|
|
46
|
-
When using Rspack as the bundler, due to some differences in configuration types between webpack and Rspack, you need to specify `<'rspack'>` generic
|
48
|
+
When using Rspack as the bundler, due to some differences in configuration types between webpack and Rspack, you need to specify the `<'rspack'>` generic for `defineConfig`:
|
47
49
|
|
48
50
|
```diff title=modern.config.ts
|
49
51
|
- export default defineConfig({
|
50
52
|
+ export default defineConfig<'rspack'>({
|
51
|
-
|
53
|
+
// ...
|
52
54
|
});
|
53
55
|
```
|
54
56
|
|
55
|
-
|
57
|
+
#### modern.config.js
|
56
58
|
|
57
|
-
If you are developing a non-TypeScript project, you can use the
|
59
|
+
If you are developing a non-TypeScript project, you can use the `.js` format for the configuration file:
|
58
60
|
|
59
61
|
```js title="modern.config.js"
|
60
62
|
export default {
|
@@ -66,7 +68,7 @@ export default {
|
|
66
68
|
};
|
67
69
|
```
|
68
70
|
|
69
|
-
You can also configure
|
71
|
+
You can also configure different settings based on the environment using `process.env.NODE_ENV`:
|
70
72
|
|
71
73
|
```js title="modern.config.js"
|
72
74
|
export default {
|
@@ -76,9 +78,9 @@ export default {
|
|
76
78
|
};
|
77
79
|
```
|
78
80
|
|
79
|
-
|
81
|
+
#### Exporting Configuration Functions
|
80
82
|
|
81
|
-
Modern.js supports exporting a function in the configuration file,
|
83
|
+
Modern.js supports exporting a function in the configuration file, where you can dynamically compute the configuration and return it to Modern.js.
|
82
84
|
|
83
85
|
```js title="modern.config.js"
|
84
86
|
import { defineConfig } from '@modern-js/app-tools';
|
@@ -92,16 +94,16 @@ export default defineConfig(({ env, command }) => ({
|
|
92
94
|
}));
|
93
95
|
```
|
94
96
|
|
95
|
-
This function
|
97
|
+
This function accepts the following parameters:
|
96
98
|
|
97
|
-
- `env`:
|
99
|
+
- `env`: Corresponds to the value of `process.env.NODE_ENV`.
|
98
100
|
- When running `modern dev` or `modern start`, the value of `env` is `development`.
|
99
101
|
- When running `modern build` or `modern serve`, the value of `env` is `production`.
|
100
|
-
- `command`:
|
102
|
+
- `command`: Corresponds to the current command being run, such as `dev`, `start`, `build`, or `serve`.
|
101
103
|
|
102
|
-
|
104
|
+
#### Exporting Asynchronous Functions
|
103
105
|
|
104
|
-
Modern.js also supports exporting an asynchronous function in the configuration file, you
|
106
|
+
Modern.js also supports exporting an asynchronous function in the configuration file, allowing you to perform some asynchronous operations:
|
105
107
|
|
106
108
|
```js title="modern.config.js"
|
107
109
|
import { defineConfig } from '@modern-js/app-tools';
|
@@ -117,11 +119,11 @@ export default defineConfig(async ({ env, command }) => {
|
|
117
119
|
});
|
118
120
|
```
|
119
121
|
|
120
|
-
|
122
|
+
#### Specifying Configuration Files
|
121
123
|
|
122
|
-
|
124
|
+
The Modern.js command line supports specifying the name of the configuration file using the `--config` option.
|
123
125
|
|
124
|
-
For example, if you need to use the `modern.prod.config.js` file when
|
126
|
+
For example, if you need to use the `modern.prod.config.js` file when executing the `build` command, you can add the following configuration in `package.json`:
|
125
127
|
|
126
128
|
```json title="package.json"
|
127
129
|
{
|
@@ -132,15 +134,15 @@ For example, if you need to use the `modern.prod.config.js` file when running `b
|
|
132
134
|
}
|
133
135
|
```
|
134
136
|
|
135
|
-
You can also abbreviate the `--config` option
|
137
|
+
You can also abbreviate the `--config` option as `-c`:
|
136
138
|
|
137
139
|
```bash
|
138
140
|
$ modern build -c modern.prod.config.js
|
139
141
|
```
|
140
142
|
|
141
|
-
|
143
|
+
### Configuring in package.json (Not Recommended)
|
142
144
|
|
143
|
-
In addition to configuration files,
|
145
|
+
In addition to configuration files, you can also set configuration items under the `modernConfig` field in `package.json`, such as:
|
144
146
|
|
145
147
|
```json title="package.json"
|
146
148
|
{
|
@@ -154,20 +156,20 @@ In addition to configuration files, configuration options can also be set the `m
|
|
154
156
|
}
|
155
157
|
```
|
156
158
|
|
157
|
-
Due to the
|
159
|
+
Due to the limitations of the JSON file format, only simple types such as numbers, strings, booleans, and arrays can be defined in `package.json`. When we need to set function-type values, it is recommended to do so in the Modern.js configuration file.
|
158
160
|
|
159
|
-
|
161
|
+
#### Notes
|
160
162
|
|
161
|
-
- It is not recommended to use both `package.json` and `modern.config.
|
162
|
-
- `@modern-js/runtime` exports
|
163
|
+
- It is not recommended to use both `package.json` and `modern.config.js` for configuration simultaneously. If both are used and conflicts arise, Modern.js will prompt an error in the command line.
|
164
|
+
- The `@modern-js/runtime` exports a similarly named [defineConfig](/apis/app/runtime/app/define-config) API, so please be careful to distinguish between them.
|
163
165
|
|
164
|
-
|
166
|
+
### Local Debugging Configuration
|
165
167
|
|
166
|
-
To facilitate local debugging
|
168
|
+
To facilitate local debugging of configurations, Modern.js supports creating a `modern.config.local.(ts|js|mjs)` file in the root directory to override the configuration options in `modern.config.(ts|js|mjs)`.
|
167
169
|
|
168
|
-
|
170
|
+
#### Example
|
169
171
|
|
170
|
-
For example, the
|
172
|
+
For example, if the `modern.config.ts` file in your project is configured with a port number of `3000`:
|
171
173
|
|
172
174
|
```ts title="modern.config.ts"
|
173
175
|
import { defineConfig } from '@modern-js/app-tools';
|
@@ -179,7 +181,7 @@ export default defineConfig({
|
|
179
181
|
});
|
180
182
|
```
|
181
183
|
|
182
|
-
If you need to change the port number to `3001`
|
184
|
+
If you need to change the port number to `3001` for local debugging but do not want to modify the current project's `modern.config.ts` file, you can create a `modern.config.local.ts` file and add the following configuration:
|
183
185
|
|
184
186
|
```ts title="modern.config.local.ts"
|
185
187
|
import { defineConfig } from '@modern-js/app-tools';
|
@@ -191,52 +193,52 @@ export default defineConfig({
|
|
191
193
|
});
|
192
194
|
```
|
193
195
|
|
194
|
-
The configuration in the `modern.config.local.ts` file will be
|
196
|
+
The configuration in the `modern.config.local.ts` file will be deeply merged with the configuration in `modern.config.ts`, overriding the options in `modern.config.ts`, so `server.port` will be changed to `3001`.
|
195
197
|
|
196
|
-
|
198
|
+
#### Notes
|
197
199
|
|
198
200
|
When using `modern.config.local.ts`, please note the following:
|
199
201
|
|
200
|
-
- The `modern.config.local.ts` file
|
201
|
-
- The `modern.config.local.ts` file
|
202
|
-
-
|
202
|
+
- The `modern.config.local.ts` file will only be loaded when executing the `modern dev` or `modern start` commands and will not be loaded during `modern build`.
|
203
|
+
- The priority of the `modern.config.local.ts` file is higher than both `modern.config.ts` and the `modernConfig` field in `package.json`.
|
204
|
+
- Since `modern.config.local.ts` is only used for local debugging, it is not recommended to commit it to the code repository. Ensure that the project's `.gitignore` file includes `modern.config.local.ts` and similar files.
|
203
205
|
|
204
|
-
```bash title=".
|
206
|
+
```bash title=".gitignore"
|
205
207
|
modern.config.local.*
|
206
208
|
```
|
207
209
|
|
208
|
-
|
210
|
+
### Merging Multiple Configurations
|
209
211
|
|
210
|
-
In some cases, you may need to merge multiple configurations into one
|
212
|
+
In some cases, you may need to merge multiple configurations into one. You can use the `mergeConfig` utility function to merge multiple configurations.
|
211
213
|
|
212
|
-
The `mergeConfig` function accepts an array as a parameter,
|
214
|
+
The `mergeConfig` function accepts an array as a parameter, where each item in the array is a configuration object. `mergeConfig` will deeply merge each configuration object in the array, automatically merging multiple function items into an array, and finally returning a merged configuration object.
|
213
215
|
|
214
|
-
|
216
|
+
#### Example
|
215
217
|
|
216
218
|
```ts title="modern.config.ts"
|
217
219
|
import { mergeConfig } from '@modern-js/app-tools';
|
218
220
|
|
219
221
|
const config1 = {
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
222
|
+
dev: {
|
223
|
+
port: 3000,
|
224
|
+
},
|
225
|
+
tools: {
|
226
|
+
postcss: () => console.log('config1');
|
227
|
+
},
|
226
228
|
};
|
227
229
|
const config2 = {
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
230
|
+
dev: {
|
231
|
+
port: 3001,
|
232
|
+
},
|
233
|
+
tools: {
|
234
|
+
postcss: () => console.log('config2');
|
235
|
+
},
|
234
236
|
};
|
235
237
|
|
236
238
|
const mergedConfig = mergeConfig([config1, config2]);
|
237
239
|
```
|
238
240
|
|
239
|
-
In the above example, the merged configuration object
|
241
|
+
In the above example, the merged configuration object will be:
|
240
242
|
|
241
243
|
```ts
|
242
244
|
const mergedConfig = {
|
@@ -249,9 +251,9 @@ const mergedConfig = {
|
|
249
251
|
};
|
250
252
|
```
|
251
253
|
|
252
|
-
|
254
|
+
### Configuration Type Definitions
|
253
255
|
|
254
|
-
Modern.js exports `AppUserConfig` type, which corresponds to the type of Modern.js configuration object:
|
256
|
+
Modern.js exports the `AppUserConfig` type, which corresponds to the type of the Modern.js configuration object:
|
255
257
|
|
256
258
|
```ts title="modern.config.ts"
|
257
259
|
import type { AppUserConfig } from '@modern-js/app-tools';
|
@@ -263,7 +265,7 @@ const config: AppUserConfig = {
|
|
263
265
|
};
|
264
266
|
```
|
265
267
|
|
266
|
-
When using Rspack as the bundler, due to some differences in configuration types between webpack and Rspack, you need to specify `<'rspack'>` generic
|
268
|
+
When using Rspack as the bundler, due to some differences in configuration types between webpack and Rspack, you need to specify the `<'rspack'>` generic for `AppUserConfig`:
|
267
269
|
|
268
270
|
```ts title="modern.config.ts"
|
269
271
|
import type { AppUserConfig } from '@modern-js/app-tools';
|
@@ -274,3 +276,25 @@ const config: AppUserConfig<'rspack'> = {
|
|
274
276
|
},
|
275
277
|
};
|
276
278
|
```
|
279
|
+
|
280
|
+
## Runtime Configuration
|
281
|
+
|
282
|
+
For detailed information on runtime configuration, please refer to the [Introduction to Runtime Configuration](/configure/app/runtime/0-intro.html).
|
283
|
+
|
284
|
+
:::tip
|
285
|
+
If the current Runtime configuration needs to be used both at compile time and runtime, please add the relevant configuration parameters at the plugin registration location.
|
286
|
+
|
287
|
+
```ts title="modern.config.ts"
|
288
|
+
import { defineConfig } from '@modern-js/app-tools';
|
289
|
+
import { statePlugin } from '@modern-js/plugin-state';
|
290
|
+
|
291
|
+
export default defineConfig({
|
292
|
+
plugins: [
|
293
|
+
statePlugin({
|
294
|
+
/** Add parameters here */
|
295
|
+
}),
|
296
|
+
],
|
297
|
+
});
|
298
|
+
```
|
299
|
+
|
300
|
+
:::
|
@@ -4,31 +4,21 @@ sidebar_position: 16
|
|
4
4
|
|
5
5
|
# Custom Web Server
|
6
6
|
|
7
|
-
|
7
|
+
Modern.js encapsulates most server-side capabilities required by projects, typically eliminating the need for server-side development. However, in certain scenarios such as user authentication, request preprocessing, or adding page skeletons, custom server-side logic may still be necessary.
|
8
8
|
|
9
|
-
|
9
|
+
Modern.js provides two types of APIs to extend the Web Server: **Middleware** and **Lifecycle Hooks**.
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
For example, hosting pages separately from BFF, deploying page services to non-Node environments, customizing for deployment platforms, etc.
|
14
|
-
|
15
|
-
For the above reasons, Modern.js provides three ways that projects can customize server-level capabilities progressively according to their needs.
|
16
|
-
|
17
|
-
:::warning
|
18
|
-
The three extension methods cannot work at the same time, and developers need to choose the appropriate method according to the scenario.
|
11
|
+
:::note
|
12
|
+
Middleware and Hooks only take effect when users request page routes, and BFF routes won't pass through these APIs.
|
19
13
|
:::
|
20
14
|
|
21
|
-
##
|
15
|
+
## Enabling Custom Web Server
|
22
16
|
|
23
|
-
|
24
|
-
|
25
|
-
Because the full web server cannot be controlled this way, and the extension logic **only takes effect when the page is requested**. Therefore, it is relatively simple to apply server-level logic, and you do not want to create additional BFFs or BFFs and pages without common server-level logic scenarios.
|
26
|
-
|
27
|
-
You can run the'pnpm run new 'command in the project root directory to enable the "Custom Web Serve" function:
|
17
|
+
Developers can execute the `pnpm run new` command in the project root directory to enable the "Custom Web Server" feature:
|
28
18
|
|
29
19
|
```bash
|
30
|
-
?
|
31
|
-
?
|
20
|
+
? Select operation: Create project element
|
21
|
+
? Select element type: Create "Custom Web Server" source directory
|
32
22
|
```
|
33
23
|
|
34
24
|
After executing the command, register the `@modern-js/plugin-server` plugin in `modern.config.ts`:
|
@@ -41,84 +31,19 @@ export default defineConfig({
|
|
41
31
|
});
|
42
32
|
```
|
43
33
|
|
44
|
-
|
45
|
-
|
46
|
-
### Hook
|
47
|
-
|
48
|
-
The Hook provided by Modern.js is used to control the built-in logic in the Web Server, and all page requests go through the Hook.
|
34
|
+
Once enabled, a `server/index.ts` file will be automatically created in the project directory where custom logic can be implemented.
|
49
35
|
|
50
|
-
|
51
|
-
|
52
|
-
```ts
|
53
|
-
import type {
|
54
|
-
AfterMatchHook,
|
55
|
-
AfterRenderHook,
|
56
|
-
} from '@modern-js/runtime/server';
|
57
|
-
|
58
|
-
export const afterMatch: AfterMatchHook = (ctx, next) => {
|
59
|
-
next();
|
60
|
-
};
|
61
|
-
|
62
|
-
export const afterRender: AfterRenderHook = (ctx, next) => {
|
63
|
-
next();
|
64
|
-
};
|
65
|
-
```
|
66
|
-
|
67
|
-
Projects should follow these best practices when using Hook:
|
68
|
-
|
69
|
-
1. Authentication in afterMatch.
|
70
|
-
2. Do Rewrite and Redirect in afterMatch.
|
71
|
-
3. Inject HTML content in afterRender.
|
72
|
-
|
73
|
-
:::note
|
74
|
-
For more detail, see [Hook](/apis/app/runtime/web-server/hook).
|
75
|
-
:::
|
76
|
-
|
77
|
-
### Middleware
|
78
|
-
|
79
|
-
For some projects, there may be more requirements at the server level, Modern.js provides Middleware to add pre-middleware for Web Server. It can only run in a Node environment, so if the project is deployed to another environment, such as a Worker environment, Middleware cannot be used.
|
80
|
-
|
81
|
-
:::note
|
82
|
-
In the next major release, Modern.js will use new middleware to replace this approach.
|
83
|
-
|
84
|
-
It is recommended to use [UnstableMiddleware](/guides/advanced-features/web-server.html#unstablemiddleware) to handle page requests.
|
85
|
-
:::
|
86
|
-
|
87
|
-
Modern.js provides a set of APIs by default for projects to use:
|
88
|
-
|
89
|
-
```ts
|
90
|
-
import { Middleware } from '@modern-js/runtime/server';
|
91
|
-
|
92
|
-
export const middleware: Middleware = (context, next) => {
|
93
|
-
const {
|
94
|
-
source: { req, res },
|
95
|
-
} = context;
|
96
|
-
console.log(req.url);
|
97
|
-
next();
|
98
|
-
};
|
99
|
-
```
|
100
|
-
|
101
|
-
:::note
|
102
|
-
For more detail, see [Middleware] (/apis/app/runtime/web-server/middleware).
|
103
|
-
:::
|
104
|
-
|
105
|
-
Projects should follow these best practices when using Middleware:
|
106
|
-
|
107
|
-
1. In Middleware, you can directly operate origin request and response objects, do event tracking, and inject Node services (databases, Redis, etc.) that may be used for SSR rendering.
|
108
|
-
2. Operations such as marking and crawler optimization can be done in Middleware.
|
109
|
-
3. In Middleware, you can ignore the default rendering and customize the rendering process.
|
110
|
-
|
111
|
-
**In general, in CSR projects, using Hook can basically meet all the needs of simple scenarios. In SSR projects, Middleware can be used for more complex Node extensions.**
|
36
|
+
## Custom Web Server Capabilities
|
112
37
|
|
113
38
|
### Unstable Middleware
|
114
39
|
|
115
|
-
Modern.js
|
40
|
+
Modern.js supports adding rendering middleware to the Web Server, allowing custom logic execution before and after processing page routes.
|
116
41
|
|
117
42
|
```ts title="server/index.ts"
|
118
43
|
import {
|
119
44
|
UnstableMiddleware,
|
120
45
|
UnstableMiddlewareContext,
|
121
|
-
} from '@
|
46
|
+
} from '@Modern.js/runtime/server';
|
122
47
|
|
123
48
|
const time: UnstableMiddleware = async (c: UnstableMiddlewareContext, next) => {
|
124
49
|
const start = Date.now();
|
@@ -133,30 +58,41 @@ const time: UnstableMiddleware = async (c: UnstableMiddlewareContext, next) => {
|
|
133
58
|
export const unstableMiddleware: UnstableMiddleware[] = [time];
|
134
59
|
```
|
135
60
|
|
136
|
-
:::
|
137
|
-
For detailed API and more usage,
|
61
|
+
:::info
|
62
|
+
For detailed API and more usage, see [UnstableMiddleware](/apis/app/runtime/web-server/unstable_middleware).
|
138
63
|
:::
|
139
64
|
|
140
|
-
|
65
|
+
### Hooks
|
141
66
|
|
142
|
-
|
67
|
+
:::warning
|
68
|
+
We recommend using UnstableMiddleware instead of Hooks.
|
69
|
+
:::
|
143
70
|
|
144
|
-
|
71
|
+
Modern.js provides Hooks to control specific logic in the Web Server. All page requests will pass through Hooks.
|
145
72
|
|
146
|
-
|
73
|
+
Currently, two types of Hooks are available: `AfterMatch` and `AfterRender`. Developers can implement them in `server/index.ts` as follows:
|
147
74
|
|
148
75
|
```ts
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
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
|
+
};
|
154
88
|
```
|
155
89
|
|
156
|
-
|
90
|
+
Best practices when using Hooks:
|
157
91
|
|
158
|
-
|
92
|
+
1. Perform authorization checks in afterMatch.
|
93
|
+
2. Handle Rewrite and Redirect in afterMatch.
|
94
|
+
3. Inject HTML content in afterRender.
|
159
95
|
|
160
|
-
:::
|
161
|
-
|
96
|
+
:::info
|
97
|
+
For detailed API and more usage, see [Hook](/apis/app/runtime/web-server/hook).
|
162
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
|
+
In certain scenarios, applications need to perform preprocessing operations before rendering. Modern.js recommends using **[Runtime Plugins](/plugin/introduction.html#runtime-plugins)** to implement this type of logic.
|
4
|
+
|
5
|
+
## Defining a Runtime Plugin
|
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
|
+
// Logic to execute before rendering
|
15
|
+
console.log('Before rendering:', context);
|
16
|
+
});
|
17
|
+
},
|
18
|
+
});
|
19
|
+
|
20
|
+
export default myRuntimePlugin;
|
21
|
+
```
|
22
|
+
|
23
|
+
## Registering the Plugin
|
24
|
+
|
25
|
+
Register the plugin in your project's `src/modern.runtime.ts` file:
|
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
|
+
## Use Case -- Global Data Injection
|
37
|
+
|
38
|
+
Through the `context` parameter of the `onBeforeRender` hook, you can inject global data into your application. Application components can access this data using the `useRuntimeContext` Hook.
|
39
|
+
|
40
|
+
:::info
|
41
|
+
|
42
|
+
This feature is particularly useful in the following scenarios:
|
43
|
+
* Applications requiring page-level preliminary data
|
44
|
+
* Custom data injection workflows
|
45
|
+
* Framework migration scenarios (e.g., migrating from Next.js)
|
46
|
+
|
47
|
+
:::
|
48
|
+
|
49
|
+
**Defining a Data Injection Plugin**
|
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
|
+
// Inject data into the context
|
59
|
+
context.message = 'Hello World';
|
60
|
+
});
|
61
|
+
},
|
62
|
+
});
|
63
|
+
|
64
|
+
export default dataInjectionPlugin;
|
65
|
+
```
|
66
|
+
|
67
|
+
**Using Injected Data in Components**
|
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
|
+
**Using with SSR**
|
81
|
+
|
82
|
+
In SSR scenarios, the browser can access data injected via `onBeforeRender` during server-side rendering. Developers can decide whether to re-fetch data on the browser side to override server data based on their requirements.
|
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
|
+
// Set data during server-side rendering
|
93
|
+
context.message = 'Hello World By Server';
|
94
|
+
} else {
|
95
|
+
// Check data during client-side rendering
|
96
|
+
if (!context.message) {
|
97
|
+
// If server data is not available, set client data
|
98
|
+
context.message = 'Hello World By Client';
|
99
|
+
}
|
100
|
+
}
|
101
|
+
});
|
102
|
+
},
|
103
|
+
});
|
104
|
+
|
105
|
+
export default dataInjectionPlugin;
|
106
|
+
```
|
107
|
+
|
108
|
+
## Compatibility Notes
|
109
|
+
|
110
|
+
In earlier versions of Modern.js, it was possible to add render preprocessing logic through the `init` hook in `routes/layout.tsx` and the `App.init` method. These approaches are still **supported**, but we **strongly recommend** implementing with Runtime plugins instead.
|
111
|
+
|
112
|
+
:::warning
|
113
|
+
|
114
|
+
In future versions, the `init` hook in `routes/layout.tsx` and the `App.init` method will be gradually **deprecated**. We recommend migrating to the Runtime plugin approach as soon as possible.
|
115
|
+
:::
|