用于拓展 Modern.js 内置的 Web Server,与 Hook 不同的是,Middleware 可以直接操作 Node 原生的请求、响应对象,并且可以使用框架拓展。
NOTE
更多内容可以查看自定义 Web Server。
import { Middleware } from '@modern-js/runtime/server';
export const middleware: Middleware = async (context, next) => {};
export const middleware: Middleware[] = [
async (context, next) => {},
async (context, next) => {},
];
自定义 Web Server
使用该 API 前,请先执行 pnpm run new
新建「自定义 Web Server」源码目录。
pnpm run new
? 请选择你想要的操作 创建工程元素
? 新建「自定义 Web Server」源码目录
type Middleware = (
context: MiddlewareContext,
next: NextFunction,
) => Promise<void> | void;
type MiddlewareContext = {
response: {
set: (key: string, value: string) => void;
status: (code: number) => void;
cookies: {
get: (key: string) => string;
set: (key: string, value: string) => void;
delete: () => void;
clear: () => void;
apply: () => void;
};
raw: (
body: string,
{ status, headers }: { status: number; headers: Record<string, any> },
) => void;
locals: Record<string, any>;
};
request: {
url: string;
host: string;
pathname: string;
query: Record<string, any>;
cookie: string;
cookies: {
get: (key: string) => string;
};
headers: IncomingHttpHeaders;
};
source: {
req: IncomingMessage;
res: ServerResponse;
};
};
context
:提供当前 Hook 上下文。
response
:提供一系列处理响应的操作request
:提供一系列获取请求信息的操作source
:提供 Node.js 原生的 req
与 res
对象。next
:执行当前 Hook 的下一个监听函数(不影响整体服务端流程)。WARNING
next
函数的执行不影响后续内置流程,只控制下一个中间件是否执行。只有当响应被写入时,后续渲染流程才会中断。
export const Middleware = () => async (ctx, next) => {
const start = Date.now();
ctx.res.once('finish', () => {
console.log(Date.now() - start);
});
};
Modern.js 提供了 res.locals
属性用来存放当前请求的局部变量。
export const Middleware = () => async (ctx, next) => {
ctx.res.locals.id = 'Modern.js';
ctx.res.locals.rpc = createRpcInstance();
};
Middleware 还可以和 BFF 一样,使用运行时框架拓展。Modern.js 约定,当使用框架运行时拓展时,类型信息从 @modern-js/runtime/{namespace}
下导出,Middleware 可以使用框架语法,例如框架中间件写法,以下是伪代码:
import { SomeType } from '@modern-js/runtime/{namespace}';
export const middleware: SomeType = (ctx, next) => {
console.log(ctx.url);
next();
};
默认情况下,在安装框架拓展插件后,Web Server 的框架拓展能力是关闭的。如果希望使用框架拓展,可以通过 server.enableFrameworkExt
开启。
INFO
框架拓展导出的类型名不一定为 Middleware,命名由框架拓展插件。