@modern-js/main-doc 2.49.4 → 2.50.0
Sign up to get free protection for your applications and to get access to all the features.
- package/docs/en/apis/app/runtime/web-server/middleware.mdx +7 -1
- package/docs/en/apis/app/runtime/web-server/unstable_middleware.mdx +134 -0
- package/docs/en/guides/advanced-features/web-server.mdx +42 -4
- package/docs/zh/apis/app/runtime/web-server/middleware.mdx +7 -0
- package/docs/zh/apis/app/runtime/web-server/unstable_middleware.mdx +133 -0
- package/docs/zh/guides/advanced-features/web-server.mdx +33 -0
- package/package.json +5 -5
@@ -1,10 +1,17 @@
|
|
1
1
|
---
|
2
2
|
title: Middleware
|
3
3
|
---
|
4
|
+
|
4
5
|
# Middleware
|
5
6
|
|
6
7
|
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.
|
7
8
|
|
9
|
+
:::note
|
10
|
+
In the next major release, Modern.js will use new middleware to replace this approach.
|
11
|
+
|
12
|
+
It is recommended to use [UnstableMiddleware](/apis/app/runtime/web-server/unstable_middleware) to handle page requests.
|
13
|
+
:::
|
14
|
+
|
8
15
|
:::note
|
9
16
|
For more detail, see [Extend Web Server](/guides/advanced-features/web-server).
|
10
17
|
|
@@ -125,7 +132,6 @@ export const middleware: SomeType = (ctx, next) => {
|
|
125
132
|
|
126
133
|
By default, the framework extension capability of Web Server is turned off after installing the framework extension plugin. If you want to use the framework extension, you can turn it on through ['server.enableFrameworkExt'](/configure/app/server/enable-framework-ext.html).
|
127
134
|
|
128
|
-
|
129
135
|
:::info
|
130
136
|
The type name exported by the framework extension may not 'Middleware', but is named by the framework extension plugin.
|
131
137
|
:::
|
@@ -0,0 +1,134 @@
|
|
1
|
+
---
|
2
|
+
title: Unstable Middleware
|
3
|
+
---
|
4
|
+
|
5
|
+
# Unstable Middleware
|
6
|
+
|
7
|
+
Used to extend the built-in Web Server in Modern.js.
|
8
|
+
UnstableMiddleware will replace [Middleware](/apis/app/runtime/web-server/middleware) in the future.
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
```ts title="server/index.ts"
|
13
|
+
import { UnstableMiddleware } from '@modern-js/runtime/server';
|
14
|
+
|
15
|
+
export const unstableMiddlewares: UnstableMiddleware[] = [];
|
16
|
+
```
|
17
|
+
|
18
|
+
## Types
|
19
|
+
|
20
|
+
**UnstableMiddleware**
|
21
|
+
|
22
|
+
```ts
|
23
|
+
type UnstableMiddleware<
|
24
|
+
V extends Record<string, unknown> = Record<string, unknown>,
|
25
|
+
> = (
|
26
|
+
c: UnstableMiddlewareContext<V>,
|
27
|
+
next: UnstableNext,
|
28
|
+
) => Promise<void | Response>;
|
29
|
+
```
|
30
|
+
|
31
|
+
**UnstableMiddlewareContext**
|
32
|
+
|
33
|
+
```ts
|
34
|
+
type Body = ReadableStream | ArrayBuffer | string | null;
|
35
|
+
|
36
|
+
type UnstableMiddlewareContext<
|
37
|
+
V extends Record<string, unknown> = Record<string, unknown>,
|
38
|
+
> = {
|
39
|
+
request: Request;
|
40
|
+
response: Response;
|
41
|
+
get: Get<V>;
|
42
|
+
set: Set<V>;
|
43
|
+
header: (name: string, value: string, options?: { append?: boolean }) => void;
|
44
|
+
status: (code: number) => void;
|
45
|
+
redirect: (location: string, status?: number) => Response;
|
46
|
+
body: (data: Body, init?: ResponseInit) => Response;
|
47
|
+
html: (
|
48
|
+
data: string | Promise<string>,
|
49
|
+
init?: ResponseInit,
|
50
|
+
) => Response | Promise<Response>;
|
51
|
+
};
|
52
|
+
```
|
53
|
+
|
54
|
+
**UnstableNext**
|
55
|
+
|
56
|
+
```ts
|
57
|
+
type UnstableNext = () => Promise<void>;
|
58
|
+
```
|
59
|
+
|
60
|
+
## Examples
|
61
|
+
|
62
|
+
### Web Server Timing
|
63
|
+
|
64
|
+
```ts
|
65
|
+
import { UnstableMiddleware } from '@modern-js/runtime/server';
|
66
|
+
|
67
|
+
const time: UnstableMiddleware = async (c, next) => {
|
68
|
+
const start = Date.now();
|
69
|
+
|
70
|
+
await next();
|
71
|
+
|
72
|
+
const end = Date.now();
|
73
|
+
|
74
|
+
console.log(`${end - start}`);
|
75
|
+
};
|
76
|
+
|
77
|
+
export const unstableMiddlewares: UnstableMiddleware = [time];
|
78
|
+
```
|
79
|
+
|
80
|
+
### Injecting Server Data for DataLoader Consumption
|
81
|
+
|
82
|
+
```ts title="shared/index.ts"
|
83
|
+
export type Vars = {
|
84
|
+
message: string;
|
85
|
+
};
|
86
|
+
```
|
87
|
+
|
88
|
+
```ts title="server/index.ts"
|
89
|
+
import {
|
90
|
+
UnstableMiddleware,
|
91
|
+
UnstableMiddlewareContext,
|
92
|
+
} from '@modern-js/runtime/server';
|
93
|
+
import type { Vars } from '../shared/index';
|
94
|
+
|
95
|
+
const setPayload: UnstableMiddleware = async (
|
96
|
+
c: UnstableMiddlewareContext<Vars>,
|
97
|
+
next,
|
98
|
+
) => {
|
99
|
+
c.set('message', 'facker');
|
100
|
+
|
101
|
+
await next();
|
102
|
+
};
|
103
|
+
|
104
|
+
export const unstableMiddlewares: UnstableMiddleware = [setPayload];
|
105
|
+
```
|
106
|
+
|
107
|
+
```ts title="src/routes/page.data.ts"
|
108
|
+
import type { Payload } from '../../shared/index';
|
109
|
+
import { LoaderFunctionArgs } from '@modern-js/runtime/router';
|
110
|
+
|
111
|
+
export const loader = async ({ context }: LoaderFunctionArgs<Vars>) => {
|
112
|
+
const message = context?.get('message');
|
113
|
+
|
114
|
+
// ...
|
115
|
+
};
|
116
|
+
```
|
117
|
+
|
118
|
+
### Redirect
|
119
|
+
|
120
|
+
```ts
|
121
|
+
import { UnstableMiddleware } from '@modern-js/runtime/server';
|
122
|
+
|
123
|
+
const auth: UnstableMiddleware = async (c, next) => {
|
124
|
+
const user = getUser(c.request);
|
125
|
+
|
126
|
+
if (!user) {
|
127
|
+
return c.redirect('/login');
|
128
|
+
}
|
129
|
+
|
130
|
+
await next();
|
131
|
+
};
|
132
|
+
|
133
|
+
export const unstableMiddlewares: UnstableMiddleware = [auth];
|
134
|
+
```
|
@@ -50,15 +50,18 @@ The Hook provided by Modern.js is used to control the built-in logic in the Web
|
|
50
50
|
Currently, two Hooks are provided: `AfterMatch` and `AfterRender`, which can be used to modify the rendering results. It can be written in `server/index.ts` as follows:
|
51
51
|
|
52
52
|
```ts
|
53
|
-
import type {
|
53
|
+
import type {
|
54
|
+
AfterMatchHook,
|
55
|
+
AfterRenderHook,
|
56
|
+
} from '@modern-js/runtime/server';
|
54
57
|
|
55
58
|
export const afterMatch: AfterMatchHook = (ctx, next) => {
|
56
59
|
next();
|
57
|
-
}
|
60
|
+
};
|
58
61
|
|
59
62
|
export const afterRender: AfterRenderHook = (ctx, next) => {
|
60
63
|
next();
|
61
|
-
}
|
64
|
+
};
|
62
65
|
```
|
63
66
|
|
64
67
|
Projects should follow these best practices when using Hook:
|
@@ -75,13 +78,21 @@ For more detail, see [Hook](/apis/app/runtime/web-server/hook).
|
|
75
78
|
|
76
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.
|
77
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
|
+
|
78
87
|
Modern.js provides a set of APIs by default for projects to use:
|
79
88
|
|
80
89
|
```ts
|
81
90
|
import { Middlewre } from '@modern-js/runtime/server';
|
82
91
|
|
83
92
|
export const middleware: Middlewre = (context, next) => {
|
84
|
-
const {
|
93
|
+
const {
|
94
|
+
source: { req, res },
|
95
|
+
} = context;
|
85
96
|
console.log(req.url);
|
86
97
|
next();
|
87
98
|
};
|
@@ -99,6 +110,33 @@ Projects should follow these best practices when using Middleware:
|
|
99
110
|
|
100
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.**
|
101
112
|
|
113
|
+
### UnstableMiddleware
|
114
|
+
|
115
|
+
Modern.js will provide new Middleware to add pre-processing middleware to the Web Server, supporting the execution of custom logic before and after handling the page.
|
116
|
+
|
117
|
+
```ts title="server/index.ts"
|
118
|
+
import {
|
119
|
+
UnstableMiddleware,
|
120
|
+
UnstableMiddlewareContext,
|
121
|
+
} from '@modern-js/runtime/server';
|
122
|
+
|
123
|
+
const time: UnstableMiddleware = async (c: UnstableMiddlewareContext, next) => {
|
124
|
+
const start = Date.now();
|
125
|
+
|
126
|
+
await next();
|
127
|
+
|
128
|
+
const end = Date.now();
|
129
|
+
|
130
|
+
console.log(`dur=${end - start}`);
|
131
|
+
};
|
132
|
+
|
133
|
+
export const unstableMiddleware: UnstableMiddleware[] = [time];
|
134
|
+
```
|
135
|
+
|
136
|
+
:::note
|
137
|
+
For detailed API and more usage, please refer to [UnstableMiddleware](/apis/app/runtime/web-server/unstable_middleware)
|
138
|
+
:::
|
139
|
+
|
102
140
|
## Managed Page Requests with BFF
|
103
141
|
|
104
142
|
The second way is to use BFF to Managed page rendering. In this way, all requests will first hit the BFF service.
|
@@ -1,10 +1,17 @@
|
|
1
1
|
---
|
2
2
|
title: Middleware
|
3
3
|
---
|
4
|
+
|
4
5
|
# Middleware
|
5
6
|
|
6
7
|
用于拓展 Modern.js 内置的 Web Server,与 [Hook](/apis/app/runtime/web-server/hook) 不同的是,Middleware 可以直接操作 Node 原生的请求、响应对象,并且可以使用框架拓展。
|
7
8
|
|
9
|
+
:::note
|
10
|
+
在下一个大版本,Modern.js 将会使用新 Middleware 来替代该写法。
|
11
|
+
|
12
|
+
推荐使用 [UnstableMiddleware](/apis/app/runtime/web-server/unstable_middleware) 处理页面请求。
|
13
|
+
:::
|
14
|
+
|
8
15
|
:::note
|
9
16
|
更多内容可以查看[自定义 Web Server](/guides/advanced-features/web-server)。
|
10
17
|
:::
|
@@ -0,0 +1,133 @@
|
|
1
|
+
---
|
2
|
+
title: Unstable Middleware
|
3
|
+
---
|
4
|
+
|
5
|
+
# Unstable Middleware
|
6
|
+
|
7
|
+
用于拓展 Modern.js 内置的 Web Server。 未来 UnstableMiddleware 将替代 [Middleware](/apis/app/runtime/web-server/middleware)
|
8
|
+
|
9
|
+
## 使用
|
10
|
+
|
11
|
+
```ts title="server/index.ts"
|
12
|
+
import { UnstableMiddleware } from '@modern-js/runtime/server';
|
13
|
+
|
14
|
+
export const unstableMiddlewares: UnstableMiddleware = [];
|
15
|
+
```
|
16
|
+
|
17
|
+
## 类型
|
18
|
+
|
19
|
+
**UnstableMiddleware**
|
20
|
+
|
21
|
+
```ts
|
22
|
+
type UnstableMiddleware<
|
23
|
+
V extends Record<string, unknown> = Record<string, unknown>,
|
24
|
+
> = (
|
25
|
+
c: UnstableMiddlewareContext<V>,
|
26
|
+
next: UnstableNext,
|
27
|
+
) => Promise<void | Response>;
|
28
|
+
```
|
29
|
+
|
30
|
+
**UnstableMiddlewareContext**
|
31
|
+
|
32
|
+
```ts
|
33
|
+
type Body = ReadableStream | ArrayBuffer | string | null;
|
34
|
+
|
35
|
+
type UnstableMiddlewareContext<
|
36
|
+
V extends Record<string, unknown> = Record<string, unknown>,
|
37
|
+
> = {
|
38
|
+
request: Request;
|
39
|
+
response: Response;
|
40
|
+
get: Get<V>;
|
41
|
+
set: Set<V>;
|
42
|
+
header: (name: string, value: string, options?: { append?: boolean }) => void;
|
43
|
+
status: (code: number) => void;
|
44
|
+
redirect: (location: string, status?: number) => Response;
|
45
|
+
body: (data: Body, init?: ResponseInit) => Response;
|
46
|
+
html: (
|
47
|
+
data: string | Promise<string>,
|
48
|
+
init?: ResponseInit,
|
49
|
+
) => Response | Promise<Response>;
|
50
|
+
};
|
51
|
+
```
|
52
|
+
|
53
|
+
**UnstableNext**
|
54
|
+
|
55
|
+
```ts
|
56
|
+
type UnstableNext = () => Promise<void>;
|
57
|
+
```
|
58
|
+
|
59
|
+
## 用例
|
60
|
+
|
61
|
+
### web server 耗时打点
|
62
|
+
|
63
|
+
```ts
|
64
|
+
import { UnstableMiddleware } from '@modern-js/runtime/server';
|
65
|
+
|
66
|
+
const time: UnstableMiddleware = async (c, next) => {
|
67
|
+
const start = Date.now();
|
68
|
+
|
69
|
+
await next();
|
70
|
+
|
71
|
+
const end = Date.now();
|
72
|
+
|
73
|
+
console.log(`${end - start}`);
|
74
|
+
};
|
75
|
+
|
76
|
+
export const unstableMiddlewares: UnstableMiddleware = [time];
|
77
|
+
```
|
78
|
+
|
79
|
+
### 注入服务端数据,供页面 dataLoader 消费
|
80
|
+
|
81
|
+
```ts title="shared/index.ts"
|
82
|
+
export type Vars = {
|
83
|
+
message: string;
|
84
|
+
};
|
85
|
+
```
|
86
|
+
|
87
|
+
```ts title="server/index.ts"
|
88
|
+
import {
|
89
|
+
UnstableMiddleware,
|
90
|
+
UnstableMiddlewareContext,
|
91
|
+
} from '@modern-js/runtime/server';
|
92
|
+
import type { Vars } from '../shared/index';
|
93
|
+
|
94
|
+
const setPayload: UnstableMiddleware = async (
|
95
|
+
c: UnstableMiddlewareContext<Vars>,
|
96
|
+
next,
|
97
|
+
) => {
|
98
|
+
c.set('message', 'facker');
|
99
|
+
|
100
|
+
await next();
|
101
|
+
};
|
102
|
+
|
103
|
+
export const unstableMiddlewares: UnstableMiddleware = [setPayload];
|
104
|
+
```
|
105
|
+
|
106
|
+
```ts title="src/routes/page.data.ts"
|
107
|
+
import type { Payload } from '../../shared/index';
|
108
|
+
import { LoaderFunctionArgs } from '@modern-js/runtime/router';
|
109
|
+
|
110
|
+
export const loader = async ({ context }: LoaderFunctionArgs<Vars>) => {
|
111
|
+
const message = context?.get('message');
|
112
|
+
|
113
|
+
// ...
|
114
|
+
};
|
115
|
+
```
|
116
|
+
|
117
|
+
### 重定向
|
118
|
+
|
119
|
+
```ts
|
120
|
+
import { UnstableMiddleware } from '@modern-js/runtime/server';
|
121
|
+
|
122
|
+
const auth: UnstableMiddleware = async (c, next) => {
|
123
|
+
const user = getUser(c.request);
|
124
|
+
|
125
|
+
if (!user) {
|
126
|
+
return c.redirect('/login');
|
127
|
+
}
|
128
|
+
|
129
|
+
await next();
|
130
|
+
};
|
131
|
+
|
132
|
+
export const unstableMiddlewares: UnstableMiddleware = [auth];
|
133
|
+
```
|
@@ -76,6 +76,12 @@ export const afterRender: AfterRenderHook = (ctx, next) => {
|
|
76
76
|
|
77
77
|
对于某些项目,可能在服务端有更多的需求,Modern.js 提供了 Middleware 为 Web Server 添加前置中间件。它只能运行在 Node 环境下,因此如果项目被部署到其他环境中,如 Worker 环境,则不可以使用 Middleware。
|
78
78
|
|
79
|
+
:::note
|
80
|
+
下一个大版本,Modern.js 将会使用新 Middleware 来替代该写法。
|
81
|
+
|
82
|
+
推荐使用 [UnstableMiddleware](/guides/advanced-features/web-server.html#unstablemiddleware) 处理页面请求。
|
83
|
+
:::
|
84
|
+
|
79
85
|
Modern.js 默认提供了一套 API 供项目使用:
|
80
86
|
|
81
87
|
```ts
|
@@ -102,6 +108,33 @@ export const middleware: Middlewre = (context, next) => {
|
|
102
108
|
|
103
109
|
**总的来说,CSR 项目中,使用 Hook 基本能满足简单场景的所有需求。SSR 项目中,可以使用 Middleware 做更复杂的 Node 扩展。**
|
104
110
|
|
111
|
+
### UnstableMiddleware
|
112
|
+
|
113
|
+
Modern.js 将提供新 Middleware 为 Web Server 添加前置中间件,支持在处理页面的前后执行自定义逻辑。
|
114
|
+
|
115
|
+
```ts title="server/index.ts"
|
116
|
+
import {
|
117
|
+
UnstableMiddleware,
|
118
|
+
UnstableMiddlewareContext,
|
119
|
+
} from '@modern-js/runtime/server';
|
120
|
+
|
121
|
+
const time: UnstableMiddleware = async (c: UnstableMiddlewareContext, next) => {
|
122
|
+
const start = Date.now();
|
123
|
+
|
124
|
+
await next();
|
125
|
+
|
126
|
+
const end = Date.now();
|
127
|
+
|
128
|
+
console.log(`dur=${end - start}`);
|
129
|
+
};
|
130
|
+
|
131
|
+
export const unstableMiddleware: UnstableMiddleware[] = [time];
|
132
|
+
```
|
133
|
+
|
134
|
+
:::note
|
135
|
+
详细 API 和更多用法查看 [UnstableMiddleware](/apis/app/runtime/web-server/unstable_middleware)
|
136
|
+
:::
|
137
|
+
|
105
138
|
## 通过 BFF 托管页面请求
|
106
139
|
|
107
140
|
第二种方式,是利用 BFF 来托管页面渲染,这种方式下,所有的请求都会先打到 BFF 的服务。
|
package/package.json
CHANGED
@@ -15,17 +15,17 @@
|
|
15
15
|
"modern",
|
16
16
|
"modern.js"
|
17
17
|
],
|
18
|
-
"version": "2.
|
18
|
+
"version": "2.50.0",
|
19
19
|
"publishConfig": {
|
20
20
|
"registry": "https://registry.npmjs.org/",
|
21
21
|
"access": "public",
|
22
22
|
"provenance": true
|
23
23
|
},
|
24
24
|
"dependencies": {
|
25
|
-
"@modern-js/sandpack-react": "2.
|
25
|
+
"@modern-js/sandpack-react": "2.50.0"
|
26
26
|
},
|
27
27
|
"peerDependencies": {
|
28
|
-
"@modern-js/builder-doc": "^2.
|
28
|
+
"@modern-js/builder-doc": "^2.50.0"
|
29
29
|
},
|
30
30
|
"devDependencies": {
|
31
31
|
"classnames": "^2",
|
@@ -39,8 +39,8 @@
|
|
39
39
|
"@rspress/shared": "1.18.2",
|
40
40
|
"@types/node": "^16",
|
41
41
|
"@types/fs-extra": "9.0.13",
|
42
|
-
"@modern-js/doc-plugin-auto-sidebar": "2.
|
43
|
-
"@modern-js/builder-doc": "2.
|
42
|
+
"@modern-js/doc-plugin-auto-sidebar": "2.50.0",
|
43
|
+
"@modern-js/builder-doc": "2.50.0"
|
44
44
|
},
|
45
45
|
"scripts": {
|
46
46
|
"dev": "rspress dev",
|