@modern-js/main-doc 0.0.0-next-20230302080514 → 0.0.0-next-20230302100214
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +4 -2
- package/en/apis/app/runtime/web-server/hook.mdx +2 -2
- package/en/apis/app/runtime/web-server/middleware.mdx +33 -9
- package/en/configure/app/bff/enable-handle-web.mdx +24 -0
- package/en/configure/app/server/enable-framework-ext.mdx +1 -1
- package/en/guides/advanced-features/rspack-start.mdx +8 -8
- package/en/guides/advanced-features/web-server.mdx +86 -19
- package/package.json +3 -3
- package/zh/apis/app/runtime/web-server/hook.mdx +2 -4
- package/zh/apis/app/runtime/web-server/middleware.mdx +30 -10
- package/zh/configure/app/bff/enable-handle-web.mdx +24 -0
- package/zh/configure/app/server/enable-framework-ext.mdx +1 -1
- package/zh/guides/advanced-features/rspack-start.mdx +8 -8
- package/zh/guides/advanced-features/web-server.mdx +80 -15
- package/zh/guides/concept/builder.mdx +1 -1
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# @modern-js/main-doc
|
|
2
2
|
|
|
3
|
-
## 0.0.0-next-
|
|
3
|
+
## 0.0.0-next-20230302100214
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- ea7bb41e30: feat: add custom web server docs
|
|
8
|
+
feat: 添加自定义 Web Server 文档
|
|
9
|
+
- @modern-js/builder-doc@0.0.0-next-20230302100214
|
|
@@ -3,7 +3,7 @@ title: Hook
|
|
|
3
3
|
---
|
|
4
4
|
# Hook
|
|
5
5
|
|
|
6
|
-
Used to extend Modern.js built-in Web Server,
|
|
6
|
+
Used to extend Modern.js built-in Web Server, all page requests are handled by these hooks.
|
|
7
7
|
|
|
8
8
|
:::note
|
|
9
9
|
For more detail, see [Extend Web Server](/guides/advanced-features/web-server).
|
|
@@ -63,7 +63,7 @@ type HookContext = {
|
|
|
63
63
|
function Hook(context: HookContext, next: NextFunction): Promsie<void> | void;
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
different Hooks additionally provide different contexts. Currently Modern.js support `
|
|
66
|
+
different Hooks additionally provide different contexts. Currently Modern.js support `AfterMatch` and `AfterRender`.
|
|
67
67
|
|
|
68
68
|
```ts
|
|
69
69
|
type AfterMatchContext = HookContext & {
|
|
@@ -3,9 +3,7 @@ title: Middleware
|
|
|
3
3
|
---
|
|
4
4
|
# Middleware
|
|
5
5
|
|
|
6
|
-
Used to extend
|
|
7
|
-
|
|
8
|
-
Unlike [Hook](/apis/app/runtime/web-server/hook), middleware can be extended using the framework plugin.
|
|
6
|
+
Used to extend the built-in Web Server of Modern.js, unlike [Hook](/apis/app/runtime/web-server/hook), Middleware can directly operate Node's origin request and response, and can be extended using the framework plugin.
|
|
9
7
|
|
|
10
8
|
:::note
|
|
11
9
|
For more detail, see [Extend Web Server](/guides/advanced-features/web-server).
|
|
@@ -38,6 +36,11 @@ pnpm run new
|
|
|
38
36
|
## Function Signature
|
|
39
37
|
|
|
40
38
|
```ts
|
|
39
|
+
type Middleware = (
|
|
40
|
+
context: MiddlewareContext,
|
|
41
|
+
next: NextFunction,
|
|
42
|
+
) => Promise<void> | void;
|
|
43
|
+
|
|
41
44
|
type MiddlewareContext = {
|
|
42
45
|
response: {
|
|
43
46
|
set: (key: string, value: string) => void;
|
|
@@ -70,11 +73,6 @@ type MiddlewareContext = {
|
|
|
70
73
|
res: ServerResponse;
|
|
71
74
|
};
|
|
72
75
|
};
|
|
73
|
-
|
|
74
|
-
type RequestHandler = (
|
|
75
|
-
context: Context,
|
|
76
|
-
next: NextFunction,
|
|
77
|
-
) => Promise<void> | void;
|
|
78
76
|
```
|
|
79
77
|
|
|
80
78
|
### Input
|
|
@@ -85,6 +83,10 @@ type RequestHandler = (
|
|
|
85
83
|
- `source`: provides Node.js native `req` and `res` object.
|
|
86
84
|
- `next`: call next listener(not affect the server process, only current hook).
|
|
87
85
|
|
|
86
|
+
:::warning
|
|
87
|
+
The execution of the `next` function does not affect built-in processes, only controls whether the next middleware executes. Rendering processes are interrupted only when the response is written.
|
|
88
|
+
:::
|
|
89
|
+
|
|
88
90
|
## Example
|
|
89
91
|
|
|
90
92
|
### Tracking
|
|
@@ -106,5 +108,27 @@ Modern.js provides `res.locals` to store local variables for the current request
|
|
|
106
108
|
export const Middleware = () => async (ctx, next) => {
|
|
107
109
|
ctx.res.locals.id = 'Modern.js';
|
|
108
110
|
ctx.res.locals.rpc = createRpcInstance();
|
|
109
|
-
}
|
|
111
|
+
};
|
|
110
112
|
```
|
|
113
|
+
|
|
114
|
+
### Framework Extension
|
|
115
|
+
|
|
116
|
+
Middleware can also use runtime framework extensions like BFF.
|
|
117
|
+
|
|
118
|
+
When using framework runtime extensions, type information is exported from `@modern-js/runtime/{namespace}`. Middleware can use framework syntax, such as framework middleware writing, the following is pseudo-code:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { SomeType } from '@modern-js/runtime/{namespace}';
|
|
122
|
+
|
|
123
|
+
export const middleware: SomeType = (ctx, next) => {
|
|
124
|
+
console.log(ctx.url);
|
|
125
|
+
next();
|
|
126
|
+
};
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
By default, the framework extension capability of Web Server is turned off after installing the framework extension plug-in. If you want to use the framework extension, you can turn it on through ['server.enableFrameworkExt'](/configure/app/server/enable-framework-ext.html).
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
:::info
|
|
133
|
+
The type name exported by the framework extension may not 'Middleware', but is named by the framework extension plugin.
|
|
134
|
+
:::
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: enableHandleWeb
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# bff.enableHandleWeb
|
|
6
|
+
|
|
7
|
+
- **Type:** `boolean`
|
|
8
|
+
- **Default:** `false`
|
|
9
|
+
|
|
10
|
+
:::caution
|
|
11
|
+
First you need to enable the "BFF" function using [new](/apis/app/commands#modern-new) command.
|
|
12
|
+
:::
|
|
13
|
+
|
|
14
|
+
By default, the BFF service can only handle requests from the BFF API.
|
|
15
|
+
|
|
16
|
+
When this value is set to `true`, page request traffic also goes through the BFF, and the logic built into Modern.js for page rendering defaults to running as the last middleware for the BFF service.
|
|
17
|
+
|
|
18
|
+
```ts title="modern.config.ts"
|
|
19
|
+
export default defineConfig({
|
|
20
|
+
bff: {
|
|
21
|
+
enableHandleWeb: true,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
```
|
|
@@ -35,7 +35,7 @@ export const middleware: Middleware = (ctx, next) => {
|
|
|
35
35
|
When enabled, Middleware types will be exported from other namespaces and can the syntax of framework extensions:
|
|
36
36
|
|
|
37
37
|
```ts title="server/index.ts"
|
|
38
|
-
import { SomeType } from '@modern-js/runtime/{
|
|
38
|
+
import { SomeType } from '@modern-js/runtime/{namespace}';
|
|
39
39
|
|
|
40
40
|
export const middleware: SomeType = (...args) => {
|
|
41
41
|
console.log(args[0].url);
|
|
@@ -13,9 +13,9 @@ Rspack optimizes compilation performance by:
|
|
|
13
13
|
- Take full advantage of multi-core, and the entire compilation process is fully optimized for multi-threading.
|
|
14
14
|
- On-demand compilation based on request (Lazy Compilation), reducing the number of modules per compilation to improve the speed of cold start.
|
|
15
15
|
|
|
16
|
-
## Initializing an
|
|
16
|
+
## Initializing an Rspack project
|
|
17
17
|
|
|
18
|
-
The Modern.js generator provides an interactive question-and-answer interface to initialize a project. To create an
|
|
18
|
+
The Modern.js generator provides an interactive question-and-answer interface to initialize a project. To create an Rspack project, simply select the **rspack** build tool by running:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
$ npx @modern-js/create myapp
|
|
@@ -28,7 +28,7 @@ $ npx @modern-js/create myapp
|
|
|
28
28
|
After the project is created, you can experience the project by running `pnpm run dev`. For more project information, please refer to [Quick Start](/guides/get-started/quick-start.html).
|
|
29
29
|
|
|
30
30
|
:::tip
|
|
31
|
-
When using
|
|
31
|
+
When using Rspack as the bundler, the following features are currently not supported:
|
|
32
32
|
|
|
33
33
|
- Server-side rendering (SSR)
|
|
34
34
|
- Static Site Generation (SSG)
|
|
@@ -37,17 +37,17 @@ When using rspack as the bundler, the following features are currently not suppo
|
|
|
37
37
|
|
|
38
38
|
:::
|
|
39
39
|
|
|
40
|
-
## Migrating from webpack to
|
|
40
|
+
## Migrating from webpack to Rspack
|
|
41
41
|
|
|
42
|
-
You can enable
|
|
42
|
+
You can enable Rspack build by running `pnpm run new`:
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
$ pnpm run new
|
|
46
46
|
? Action: Enable features
|
|
47
|
-
? Enable features: Enable
|
|
47
|
+
? Enable features: Enable Rspack Build
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
After executing the command, enable the
|
|
50
|
+
After executing the command, enable the Rspack build in `modern.config.ts`:
|
|
51
51
|
|
|
52
52
|
```ts title=modern.config.ts
|
|
53
53
|
import appTools, { defineConfig } from '@modern-js/app-tools';
|
|
@@ -65,5 +65,5 @@ export default defineConfig<'rspack'>({
|
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
:::tip
|
|
68
|
-
Migrating from webpack to
|
|
68
|
+
Migrating from webpack to Rspack may have some differences in build and configuration capabilities. For more details, please refer to [Configuration Differences](https://modernjs.dev/builder/en/guide/advanced/rspack-start.html#migrating-from-webpack-to-rspack)
|
|
69
69
|
:::
|
|
@@ -4,20 +4,34 @@ sidebar_position: 2
|
|
|
4
4
|
---
|
|
5
5
|
# Custom Web Server
|
|
6
6
|
|
|
7
|
-
Modern.js
|
|
7
|
+
As a client side-centric development framework, Modern.js has weak customization capabilities on the server side. In some development scenarios, special server level logic needs to be customized, such as user authentication, request preprocessing, and adding page rendering skeletons.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Some developers may be wondering, Modern.js already provides [BFF](/guides/advanced-features/bff/function.html), why do you need **Custom Web Server**.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Because by default, page routing does not go through BFF, it has no way to provide server-side custom logic for page access. The reason for this design is that we do not want the service that controls the page to be bound to the BFF service, so as to avoid the BFF framework restricting how the page is deployed.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
For example, hosting pages separately from BFF, deploying page services to non-Node environments, or 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.
|
|
19
|
+
:::
|
|
20
|
+
|
|
21
|
+
## Extending Web Server with API
|
|
22
|
+
|
|
23
|
+
The first way is to customize the server level at a specific life cycle through the server level runtime API provided by Modern.js. The purpose of providing this way is that in some cases, developers do not need to control the full Web Server, but only need to add server level logic.
|
|
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 to 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 execute the'pnpm run new 'command in the project root directory to enable the "Custom Web Serve" function:
|
|
14
28
|
|
|
15
29
|
```bash
|
|
16
|
-
?
|
|
17
|
-
?
|
|
30
|
+
? Action Create project element
|
|
31
|
+
? New "Custom Web Server" source code directory
|
|
18
32
|
```
|
|
19
33
|
|
|
20
|
-
|
|
34
|
+
After executing the command, register the `@modern-js/plugin-server` plugin in `modern.config.ts`:
|
|
21
35
|
|
|
22
36
|
```ts title="modern.config.ts"
|
|
23
37
|
import serverPlugin from '@modern-js/plugin-server';
|
|
@@ -27,31 +41,84 @@ export default defineConfig({
|
|
|
27
41
|
});
|
|
28
42
|
```
|
|
29
43
|
|
|
30
|
-
|
|
44
|
+
After the function is turned on, the `server/index.ts` file will be automatically created in the project directory, and custom logic can be written in this file. Modern.js provides two types of APIs, **Hook** and **Middleware**, to extend Web Server.
|
|
45
|
+
|
|
46
|
+
### Hook
|
|
31
47
|
|
|
32
|
-
|
|
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.
|
|
33
49
|
|
|
34
|
-
|
|
50
|
+
There are currently two Hooks provided, namely `AfterMatch` and `AfterRender`, which can be used to modify the rendering results. It can be written in `server/index.ts` like this:
|
|
35
51
|
|
|
36
|
-
|
|
52
|
+
```ts
|
|
53
|
+
import type { AfterMatchHook, AfterRenderHook } from '@modern-js/runtime/server';
|
|
54
|
+
|
|
55
|
+
export const afterMatch: AfterMatchHook = (ctx, next) => {
|
|
56
|
+
next();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const afterRender: AfterRenderHook = (ctx, next) => {
|
|
60
|
+
next();
|
|
61
|
+
}
|
|
62
|
+
```
|
|
37
63
|
|
|
38
|
-
|
|
64
|
+
Projects should have the following best practices when using Hook:
|
|
39
65
|
|
|
40
|
-
|
|
66
|
+
1. Permission verification in afterMatch.
|
|
67
|
+
2. Do Rewrite and Redirect in afterMatch.
|
|
68
|
+
3. Do HTML content injection in afterRender.
|
|
41
69
|
|
|
42
|
-
|
|
70
|
+
:::note
|
|
71
|
+
For more detail, see [Hook](/apis/app/runtime/web-server/hook)。
|
|
72
|
+
:::
|
|
43
73
|
|
|
44
74
|
### Middleware
|
|
45
75
|
|
|
46
|
-
Middleware
|
|
76
|
+
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.
|
|
47
77
|
|
|
48
|
-
|
|
78
|
+
Modern.js provides a set of APIs by default for projects to use:
|
|
49
79
|
|
|
50
|
-
|
|
80
|
+
```ts
|
|
81
|
+
import { Middlewre } from '@modern-js/runtime/server';
|
|
51
82
|
|
|
52
|
-
|
|
83
|
+
export const middleware = (context, next) => {
|
|
84
|
+
const { source: { req, res } } = context;
|
|
85
|
+
console.log(req.url);
|
|
86
|
+
next();
|
|
87
|
+
};
|
|
88
|
+
```
|
|
53
89
|
|
|
54
90
|
:::note
|
|
55
|
-
|
|
91
|
+
For more detail, see [Middleware] (/apis/app/runtime/web-server/middleware).
|
|
92
|
+
:::
|
|
93
|
+
|
|
94
|
+
Projects should have the following best practices when using Middleware:
|
|
95
|
+
|
|
96
|
+
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.
|
|
97
|
+
2. Marking and crawler optimization can be done in Middleware.
|
|
98
|
+
3. In Middleware, you can ignore the default rendering and customize the rendering process.
|
|
99
|
+
|
|
100
|
+
**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.**
|
|
101
|
+
|
|
102
|
+
## Managed Page Requests with BFF
|
|
103
|
+
|
|
104
|
+
The second way is to use BFF to Managed page rendering. In this way, all requests will first hit the BFF service.
|
|
105
|
+
|
|
106
|
+
This method can uniformly control the server level logic of all requests through BFF. Therefore, it is suitable for scenarios where the server level logic is complex, and BFF and pages need common server level logic. But it still relies on the Web Server of Modern.js as a whole, and cannot run the logic on existing services.
|
|
107
|
+
|
|
108
|
+
To use this method, we need to first enable the "BFF" function through `pnpm new`. Then add [`bff.enableHandleWeb`](/configure/app/bff/enable-handle-web.html) configuration in the configuration file:
|
|
56
109
|
|
|
110
|
+
```ts
|
|
111
|
+
export default defineConfig({
|
|
112
|
+
bff: {
|
|
113
|
+
enableHandleWeb: true,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
When this value is set to `true`, page request traffic also goes through the BFF, and the logic built into Modern.js for page rendering defaults to running as the last middleware for the BFF service.
|
|
119
|
+
|
|
120
|
+
## Fully Customized Web Server
|
|
121
|
+
|
|
122
|
+
:::note
|
|
123
|
+
Comming soon..
|
|
57
124
|
:::
|
package/package.json
CHANGED
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
"modern",
|
|
12
12
|
"modern.js"
|
|
13
13
|
],
|
|
14
|
-
"version": "0.0.0-next-
|
|
14
|
+
"version": "0.0.0-next-20230302100214",
|
|
15
15
|
"publishConfig": {
|
|
16
16
|
"registry": "https://registry.npmjs.org/",
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"@modern-js/builder-doc": "0.0.0-next-
|
|
20
|
+
"@modern-js/builder-doc": "^0.0.0-next-20230302100214"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"ts-node": "^10",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"fs-extra": "^10",
|
|
26
26
|
"@types/node": "^16",
|
|
27
27
|
"@types/fs-extra": "^9",
|
|
28
|
-
"@modern-js/builder-doc": "0.0.0-next-
|
|
28
|
+
"@modern-js/builder-doc": "0.0.0-next-20230302100214"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
31
|
"build": "npx ts-node ./scripts/sync.ts"
|
|
@@ -3,11 +3,10 @@ title: Hook
|
|
|
3
3
|
---
|
|
4
4
|
# Hook
|
|
5
5
|
|
|
6
|
-
用于拓展 Modern.js 内置的 Web Server
|
|
6
|
+
用于拓展 Modern.js 内置的 Web Server,所有的页面请求都会经过 Hook。
|
|
7
7
|
|
|
8
8
|
:::note
|
|
9
9
|
更多内容可以查看[自定义 Web Server](/guides/advanced-features/web-server)。
|
|
10
|
-
|
|
11
10
|
:::
|
|
12
11
|
|
|
13
12
|
## 使用姿势
|
|
@@ -27,7 +26,6 @@ pnpm run new
|
|
|
27
26
|
? 请选择你想要的操作 创建工程元素
|
|
28
27
|
? 新建「自定义 Web Server」源码目录
|
|
29
28
|
```
|
|
30
|
-
|
|
31
29
|
:::
|
|
32
30
|
|
|
33
31
|
## 函数签名
|
|
@@ -64,7 +62,7 @@ type HookContext = {
|
|
|
64
62
|
function Hook(context: HookContext, next: NextFunction): Promsie<void> | void;
|
|
65
63
|
```
|
|
66
64
|
|
|
67
|
-
另外,不同 Hook 额外提供了不同的上下文。目前 Modern.js 支持 `
|
|
65
|
+
另外,不同 Hook 额外提供了不同的上下文。目前 Modern.js 支持 `AfterMatch` 和 `AfterRender` 两个 Hook。
|
|
68
66
|
|
|
69
67
|
```ts
|
|
70
68
|
type AfterMatchContext = HookContext & {
|
|
@@ -3,13 +3,10 @@ title: Middleware
|
|
|
3
3
|
---
|
|
4
4
|
# Middleware
|
|
5
5
|
|
|
6
|
-
用于拓展 Modern.js 内置的 Web Server
|
|
7
|
-
|
|
8
|
-
与 [Hook](/apis/app/runtime/web-server/hook) 不同的是,Middleware 可以使用 Server 运行时框架拓展。
|
|
6
|
+
用于拓展 Modern.js 内置的 Web Server,与 [Hook](/apis/app/runtime/web-server/hook) 不同的是,Middleware 可以直接操作 Node 原生的请求、响应对象,并且可以使用框架拓展。
|
|
9
7
|
|
|
10
8
|
:::note
|
|
11
9
|
更多内容可以查看[自定义 Web Server](/guides/advanced-features/web-server)。
|
|
12
|
-
|
|
13
10
|
:::
|
|
14
11
|
|
|
15
12
|
## 使用姿势
|
|
@@ -38,6 +35,11 @@ pnpm run new
|
|
|
38
35
|
## 函数签名
|
|
39
36
|
|
|
40
37
|
```ts
|
|
38
|
+
type Middleware = (
|
|
39
|
+
context: MiddlewareContext,
|
|
40
|
+
next: NextFunction,
|
|
41
|
+
) => Promise<void> | void;
|
|
42
|
+
|
|
41
43
|
type MiddlewareContext = {
|
|
42
44
|
response: {
|
|
43
45
|
set: (key: string, value: string) => void;
|
|
@@ -71,11 +73,6 @@ type MiddlewareContext = {
|
|
|
71
73
|
res: ServerResponse;
|
|
72
74
|
};
|
|
73
75
|
};
|
|
74
|
-
|
|
75
|
-
type RequestHandler = (
|
|
76
|
-
context: Context,
|
|
77
|
-
next: NextFunction,
|
|
78
|
-
) => Promise<void> | void;
|
|
79
76
|
```
|
|
80
77
|
|
|
81
78
|
### 参数
|
|
@@ -86,6 +83,10 @@ type RequestHandler = (
|
|
|
86
83
|
- `source`:提供 Node.js 原生的 `req` 与 `res` 对象。
|
|
87
84
|
- `next`:执行当前 Hook 的下一个监听函数(不影响整体服务端流程)。
|
|
88
85
|
|
|
86
|
+
:::warning
|
|
87
|
+
`next` 函数的执行不影响后续内置流程,只控制下一个中间件是否执行。只有当响应被写入时,后续渲染流程才会中断。
|
|
88
|
+
:::
|
|
89
|
+
|
|
89
90
|
## 示例
|
|
90
91
|
|
|
91
92
|
### 服务端耗时打点
|
|
@@ -107,5 +108,24 @@ Modern.js 提供了 `res.locals` 属性用来存放当前请求的局部变量
|
|
|
107
108
|
export const Middleware = () => async (ctx, next) => {
|
|
108
109
|
ctx.res.locals.id = 'Modern.js';
|
|
109
110
|
ctx.res.locals.rpc = createRpcInstance();
|
|
110
|
-
}
|
|
111
|
+
};
|
|
111
112
|
```
|
|
113
|
+
|
|
114
|
+
### 框架拓展
|
|
115
|
+
|
|
116
|
+
Middleware 还可以和 BFF 一样,使用运行时框架拓展。Modern.js 约定,当使用框架运行时拓展时,类型信息从 `@modern-js/runtime/{namespace}` 下导出,Middleware 可以使用框架语法,例如框架中间件写法,以下是伪代码:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
import { SomeType } from '@modern-js/runtime/{namespace}';
|
|
120
|
+
|
|
121
|
+
export const middleware: SomeType = (ctx, next) => {
|
|
122
|
+
console.log(ctx.url);
|
|
123
|
+
next();
|
|
124
|
+
};
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
默认情况下,在安装框架拓展插件后,Web Server 的框架拓展能力是关闭的。如果希望使用框架拓展,可以通过 [`server.enableFrameworkExt`](/configure/app/server/enable-framework-ext.html) 开启。
|
|
128
|
+
|
|
129
|
+
:::info
|
|
130
|
+
框架拓展导出的类型名不一定为 Middleware,命名由框架拓展插件。
|
|
131
|
+
:::
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: enableHandleWeb
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# bff.enableHandleWeb
|
|
6
|
+
|
|
7
|
+
- **类型:** `boolean`
|
|
8
|
+
- **默认值:** `false`
|
|
9
|
+
|
|
10
|
+
:::caution 注意
|
|
11
|
+
请先在当前应用项目根目录使用【[new](/apis/app/commands#modern-new)】 启用 BFF 功能。
|
|
12
|
+
:::
|
|
13
|
+
|
|
14
|
+
默认情况下,BFF 服务只能处理 BFF API 的请求。
|
|
15
|
+
|
|
16
|
+
当该值设置为 `true` 时,页面请求流量也会经过 BFF,并且 Modern.js 内置的页面渲染的逻辑默认会作为 BFF 服务的最后一个中间件运行。
|
|
17
|
+
|
|
18
|
+
```ts title="modern.config.ts"
|
|
19
|
+
export default defineConfig({
|
|
20
|
+
bff: {
|
|
21
|
+
enableHandleWeb: true,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
```
|
|
@@ -35,7 +35,7 @@ export const middleware: Middleware = (ctx, next) => {
|
|
|
35
35
|
开启后,Middleware 类型将从其他命名空间下导出,并且可以使用框架拓展的语法:
|
|
36
36
|
|
|
37
37
|
```ts title="server/index.ts"
|
|
38
|
-
import { SomeType } from '@modern-js/runtime/{
|
|
38
|
+
import { SomeType } from '@modern-js/runtime/{namespace}';
|
|
39
39
|
|
|
40
40
|
export const middleware: SomeType = (...args) => {
|
|
41
41
|
console.log(args[0].url);
|
|
@@ -13,9 +13,9 @@ Rspack 通过以下方式来提升编译性能:
|
|
|
13
13
|
- 充分利用多核优势,整个编译过程充分进行多线程优化。
|
|
14
14
|
- 基于请求的按需编译(Lazy Compilation),减小每次编译的模块数目,以提升冷启动的速度。
|
|
15
15
|
|
|
16
|
-
## 初始化
|
|
16
|
+
## 初始化 Rspack 项目
|
|
17
17
|
|
|
18
|
-
Modern.js 生成器会提供一个可交互的问答界面,只需将构建工具选择为**rspack**,即可创建一个
|
|
18
|
+
Modern.js 生成器会提供一个可交互的问答界面,只需将构建工具选择为**rspack**,即可创建一个 Rspack 项目:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
$ npx @modern-js/create myapp
|
|
@@ -28,7 +28,7 @@ $ npx @modern-js/create myapp
|
|
|
28
28
|
项目创建完成后,在项目中执行 `pnpm run dev` 即可体验项目。更多项目信息可参考[快速上手](/guides/get-started/quick-start.html)。
|
|
29
29
|
|
|
30
30
|
:::tip
|
|
31
|
-
使用
|
|
31
|
+
使用 Rspack 作为打包工具时,以下功能暂不支持使用:
|
|
32
32
|
|
|
33
33
|
- 服务端渲染(SSR)
|
|
34
34
|
- 静态站点生成(SSG)
|
|
@@ -37,17 +37,17 @@ $ npx @modern-js/create myapp
|
|
|
37
37
|
|
|
38
38
|
:::
|
|
39
39
|
|
|
40
|
-
## 从 webpack 迁移至
|
|
40
|
+
## 从 webpack 迁移至 Rspack
|
|
41
41
|
|
|
42
|
-
通过执行 `pnpm run new` 可启用
|
|
42
|
+
通过执行 `pnpm run new` 可启用 Rspack 构建:
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
$ pnpm run new
|
|
46
46
|
? 请选择你想要的操作 启用可选功能
|
|
47
|
-
? 启用可选功能 启用「
|
|
47
|
+
? 启用可选功能 启用「Rspack 构建」
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
执行命令后,在 modern.config.ts 中开启
|
|
50
|
+
执行命令后,在 modern.config.ts 中开启 Rspack 构建:
|
|
51
51
|
|
|
52
52
|
```ts title=modern.config.ts
|
|
53
53
|
import appTools, { defineConfig } from '@modern-js/app-tools';
|
|
@@ -65,5 +65,5 @@ export default defineConfig<'rspack'>({
|
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
:::tip
|
|
68
|
-
从 webpack 迁移至
|
|
68
|
+
从 webpack 迁移至 Rspack,会有一些构建和配置能力上的差异,详情可参考:[配置差异](https://modernjs.dev/builder/guide/advanced/rspack-start.html#从-webpack-迁移到-rspack)
|
|
69
69
|
:::
|
|
@@ -6,18 +6,30 @@ sidebar_position: 2
|
|
|
6
6
|
|
|
7
7
|
Modern.js 作为以客户端为中心的开发框架,对服务端的定制能力较弱。而在有些开发场景下,需要定制特殊的服务端逻辑,例如用户鉴权、请求预处理、添加页面渲染骨架等。
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
一些开发者可能会有疑惑,Modern.js 已经提供了 [BFF 能力](/guides/advanced-features/bff/function.html),为什么还需要**自定义 Web Server**。
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
因为在默认情况下,页面路由并不会经过 BFF,它没有办法为页面访问提供服务端的定制逻辑。之所以这样设计,是因为我们不希望控制页面的服务与 BFF 服务绑定在一起,避免 BFF 的框架限制页面的部署方式。例如将页面与 BFF 分开托管、将页面服务部署到非 Node 的环境上,或是针对部署平台做定制等。
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
出于上述原因,Modern.js 提供了三种方式,让项目可以在根据需求,渐进式的定制服务端能力。
|
|
14
|
+
|
|
15
|
+
:::warning
|
|
16
|
+
三种扩展方式无法同时工作,开发者需要根据场景选择合适的方式。
|
|
17
|
+
:::
|
|
18
|
+
|
|
19
|
+
## 使用 API 扩展 Web Server
|
|
20
|
+
|
|
21
|
+
第一种方式是通过 Modern.js 提供的服务端运行时 API,在特定的生命周期对服务端进行定制。提供这种方式的目的是在部分情况下,开发者并不需要控制完整的 Web Server,只需要添加服务端逻辑即可。
|
|
22
|
+
|
|
23
|
+
这种方式无法控制完整的 Web Server,并且扩展逻辑**只在请求页面时生效**。因此,它适用于服务端逻辑相对简单,不希望额外创建 BFF 或者 BFF 和页面无需公用服务端逻辑场景。
|
|
24
|
+
|
|
25
|
+
可以在项目根目录执行 `pnpm run new` 命令,开启「自定义 Web Serve」功能:
|
|
14
26
|
|
|
15
27
|
```bash
|
|
16
28
|
? 请选择你想要的操作 创建工程元素
|
|
17
29
|
? 创建工程元素 新建「自定义 Web Server」源码目录
|
|
18
30
|
```
|
|
19
31
|
|
|
20
|
-
执行命令后,在 `modern.config.ts` 中注册
|
|
32
|
+
执行命令后,在 `modern.config.ts` 中注册 `@modern-js/plugin-server` 插件:
|
|
21
33
|
|
|
22
34
|
```ts title="modern.config.ts"
|
|
23
35
|
import serverPlugin from '@modern-js/plugin-server';
|
|
@@ -27,31 +39,84 @@ export default defineConfig({
|
|
|
27
39
|
});
|
|
28
40
|
```
|
|
29
41
|
|
|
30
|
-
|
|
42
|
+
开启功能后,项目目录下会自动创建 `server/index.ts` 文件,可以在这个文件中编写自定义逻辑。Modern.js 提供了 **Hook** 与 **Middleware** 两类 API 来扩展 Web Server。
|
|
31
43
|
|
|
32
|
-
|
|
44
|
+
### Hook
|
|
33
45
|
|
|
34
|
-
Modern.js
|
|
46
|
+
Modern.js 提供的 Hook 用于控制 Web Server 中的内置逻辑,所有的页面请求都会经过 Hook。
|
|
35
47
|
|
|
36
|
-
|
|
48
|
+
目前提供了两种 Hook,分别是 `AfterMatch` 和 `AfterRender`,可以用于修改渲染结果。可以在 `server/index.ts` 中这样写:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import type { AfterMatchHook, AfterRenderHook } from '@modern-js/runtime/server';
|
|
52
|
+
|
|
53
|
+
export const afterMatch: AfterMatchHook = (ctx, next) => {
|
|
54
|
+
next();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const afterRender: AfterRenderHook = (ctx, next) => {
|
|
58
|
+
next();
|
|
59
|
+
}
|
|
60
|
+
```
|
|
37
61
|
|
|
38
|
-
|
|
62
|
+
项目在使用 Hook 时,应该有以下最佳实践:
|
|
39
63
|
|
|
40
|
-
|
|
64
|
+
1. 在 afterMatch 中做权限校验。
|
|
65
|
+
2. 在 afterMatch 做 Rewrite 和 Redirect。
|
|
66
|
+
3. 在 afterRender 中做 HTML 内容注入。
|
|
41
67
|
|
|
42
|
-
|
|
68
|
+
:::note
|
|
69
|
+
详细 API 和更多用法可以查看 [Hook](/apis/app/runtime/web-server/hook)。
|
|
70
|
+
:::
|
|
43
71
|
|
|
44
72
|
### Middleware
|
|
45
73
|
|
|
46
|
-
Middleware
|
|
74
|
+
对于某些项目,可能在服务端有更多的需求,Modern.js 提供了 Middleware 为 Web Server 添加前置中间件。它只能运行在 Node 环境下,因此如果项目被部署到其他环境中,如 Worker 环境,则不可以使用 Middleware。
|
|
75
|
+
|
|
76
|
+
Modern.js 默认提供了一套 API 供项目使用:
|
|
47
77
|
|
|
48
|
-
|
|
78
|
+
```ts
|
|
79
|
+
import { Middlewre } from '@modern-js/runtime/server';
|
|
49
80
|
|
|
50
|
-
|
|
81
|
+
export const middleware = (context, next) => {
|
|
82
|
+
const { source: { req, res } } = context;
|
|
83
|
+
console.log(req.url);
|
|
84
|
+
next();
|
|
85
|
+
};
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
:::note
|
|
89
|
+
详细 API 和更多用法可以查看 [Middleware](/apis/app/runtime/web-server/middleware)。
|
|
90
|
+
:::
|
|
91
|
+
|
|
92
|
+
项目在使用 Middleware 时,应该有以下最佳实践:
|
|
93
|
+
|
|
94
|
+
1. 在 Middleware 中可以直接操作原生的请求、响应对象,做数据打点、注入 SSR 渲染可能用到的 Node 服务(数据库、Redis 等)。
|
|
95
|
+
2. 在 Middleware 里可以做类似功能打标、爬虫优化等功能。
|
|
96
|
+
3. 在 Middleware 里可以无视后续默认渲染,自定义渲染流程。
|
|
97
|
+
|
|
98
|
+
**总的来说,CSR 项目中,使用 Hook 基本能满足简单场景的所有需求。SSR 项目中,可以使用 Middleware 做更复杂的 Node 扩展。**
|
|
99
|
+
|
|
100
|
+
## 通过 BFF 托管页面请求
|
|
101
|
+
|
|
102
|
+
第二种方式,是利用 BFF 来托管页面渲染,这种方式下,所有的请求都会先打到 BFF 的服务。
|
|
103
|
+
|
|
104
|
+
因为这种方式可以通过 BFF 统一控制所有请求的服务端逻辑。因此,它适用于服务端逻辑复杂,BFF 和页面需要公用服务端逻辑的场景。但它整体还是依托于 Modern.js 的 Web Server 运行,无法将逻辑运行在已有的服务上。
|
|
105
|
+
|
|
106
|
+
使用这种方式,我们需要先通过 `pnpm new` 开启「BFF」功能。然后在配置文件中添加 [`bff.enableHandleWeb`](/configure/app/bff/enable-handle-web.html) 配置:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
export default defineConfig({
|
|
110
|
+
bff: {
|
|
111
|
+
enableHandleWeb: true,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
当该值设置为 `true` 时,页面请求流量也会经过 BFF,并且 Modern.js 内置的页面渲染的逻辑默认会作为 BFF 服务的最后一个中间件运行。
|
|
51
117
|
|
|
52
118
|
## 完全自定义的 Web Server
|
|
53
119
|
|
|
54
120
|
:::note
|
|
55
121
|
敬请期待
|
|
56
|
-
|
|
57
122
|
:::
|
|
@@ -6,7 +6,7 @@ sidebar_position: 2
|
|
|
6
6
|
|
|
7
7
|
**Modern.js 的构建能力由 [Modern.js Builder](https://modernjs.dev/builder) 提供。**
|
|
8
8
|
|
|
9
|
-
Modern.js Builder 是 Modern.js 体系的核心组件之一,它是一个面向 Web 开发场景的构建引擎,可以脱离 Modern.js 被独立使用。Modern.js Builder 同时支持 webpack 和
|
|
9
|
+
Modern.js Builder 是 Modern.js 体系的核心组件之一,它是一个面向 Web 开发场景的构建引擎,可以脱离 Modern.js 被独立使用。Modern.js Builder 同时支持 webpack 和 Rspack 等多种打包工具,默认情况下使用最成熟的 webpack 进行打包。
|
|
10
10
|
|
|
11
11
|
## 构建架构
|
|
12
12
|
|