For AI agents: the complete documentation index is available at /zh/llms.txt, the full documentation bundle is available at /zh/llms-full.txt, and this page is available as Markdown at /zh/guides/upgrade/web-server.md.
  • 简体中文
  • 自定义 Web Server 变化

    本章节覆盖两类旧版自定义 Server API 的升级

    • unstableMiddleware
    • Hook

    这两种写法在旧版中互斥,迁移时请根据项目实际使用的能力选择对应路径。

    unstableMiddleware

    核心差异

    • 文件结构:server/index.ts → server/modern.server.ts
    • 导出方式:unstableMiddleware 数组 → defineServerConfig
    • Context API:Modern.js Server Context → Hono Context(c.req/c.res)
    • 中间件执行:旧版可不调用 next(),新版必须调用后续链路才会执行
    • 响应方式:c.response.raw() → c.text() / c.json()

    文件与导出

    // 旧版 - server/index.ts
    export const unstableMiddleware: UnstableMiddleware[] = [
      middleware1,
      middleware2,
    ];
    
    // 新版 - server/modern.server.ts
    import { defineServerConfig } from '@modern-js/server-runtime';
    
    export default defineServerConfig({
      middlewares: [
        { name: 'middleware1', handler: middleware1 },
        { name: 'middleware2', handler: middleware2 },
      ],
    });

    类型与 next 调用

    // 旧版
    import type {
      UnstableMiddleware,
      UnstableMiddlewareContext,
    } from '@modern-js/server-runtime';
    const middleware: UnstableMiddleware = async (
      c: UnstableMiddlewareContext,
      next,
    ) => {
      return c.response.raw('response'); // 不调用 next 也会继续渲染
    };
    
    // 新版
    import {
      defineServerConfig,
      type MiddlewareHandler,
    } from '@modern-js/server-runtime';
    const middleware: MiddlewareHandler = async (c, next) => {
      await next(); // 必须调用
      return c.text('response');
    };

    Context API 对照

    旧版 API新版 API说明
    c.request.cookiegetCookie(c, 'key')Cookie 读取
    c.req.cookie()getCookie(c, 'key')Hono v4 已废弃
    c.request.pathnamec.req.path请求路径
    c.request.hostc.req.header('Host')请求主机
    c.request.queryc.req.query()查询参数
    c.request.headersc.req.header()请求头
    c.response.statusc.status()响应状态码
    c.response.setc.res.headers.set设置响应头
    c.response.rawc.text / c.json响应体

    afterRender Hook

    afterRender Hook 用于在页面渲染完成后对 HTML 进行处理。在新版中,需要使用 renderMiddlewares 来实现相同的功能。

    核心差异

    • 文件结构:server/index.ts → server/modern.server.ts
    • 导出方式:hook 对象中的 afterRender → defineServerConfig 中的 renderMiddlewares
    • 处理方式:直接修改 HTML 字符串 → 通过中间件获取和修改响应

    迁移示例

    // 旧版 - server/index.ts
    export const afterRender = (ctx, next) => {
      ctx.template = ctx.template
        .replace('<head>', '<head><meta name="author" content="ByteDance">')
        .replace('<body>', '<body><div id="loading">Loading...</div>')
        .replace('</body>', '<script>console.log("Page loaded")</script></body>');
      next();
    };
    
    // 新版 - server/modern.server.ts
    import {
      defineServerConfig,
      type MiddlewareHandler,
    } from '@modern-js/server-runtime';
    
    const renderMiddleware: MiddlewareHandler = async (c, next) => {
      await next(); // 先等待页面渲染
      const { res } = c;
      const html = await res.text();
    
      const modified = html
        .replace('<head>', '<head><meta name="author" content="ByteDance">')
        .replace('<body>', '<body><div id="loading">Loading...</div>')
        .replace('</body>', '<script>console.log("Page loaded")</script></body>');
    
      c.res = c.body(modified, { status: res.status, headers: res.headers });
    };
    
    export default defineServerConfig({
      renderMiddlewares: [
        { name: 'custom-content-injection', handler: renderMiddleware },
      ],
    });