close
logologo
指南
配置
插件
API
社区
版本
更新日志
Rsbuild 0.x 文档
English
简体中文
指南
配置
插件
API
社区
更新日志
Rsbuild 0.x 文档
English
简体中文
logologo

开始

JavaScript API

JavaScript API

Rsbuild core
Rsbuild instance
Rsbuild types
Dev server API
Environment API
📝 在 GitHub 上编辑此页
上一页Rsbuild types
下一页Environment API

#Dev server API

Rsbuild 提供了一组 dev server 相关的 API,并允许你通过插件 hooks 或 JavaScript API 来访问。

#如何使用

  • 如果你是插件的作者,可以在 Rsbuild 插件中通过 onBeforeStartDevServer 钩子访问 dev server 实例。
const myPlugin = () => ({
  setup(api) {
    api.onBeforeStartDevServer(({ server }) => {
      console.log('the server is ', server);
    });
  },
});
  • 如果你在使用 Rsbuild 的 JavaScript API,可以通过 rsbuild.createDevServer 方法创建 dev server 实例。
const server = await rsbuild.createDevServer();

console.log('the server is ', server);

#示例

#与自定义 server 集成

下面是一个在 express 中集成 Rsbuild dev server 的例子:

import { createRsbuild } from '@rsbuild/core';
import express from 'express';

async function startDevServer() {
  // 初始化 Rsbuild
  const rsbuild = await createRsbuild({
    rsbuildConfig: {
      server: {
        middlewareMode: true,
      },
    },
  });
  const app = express();

  // 创建 Rsbuild dev server 实例
  const rsbuildServer = await rsbuild.createDevServer();

  // 使用 Rsbuild 的内置中间件
  app.use(rsbuildServer.middlewares);

  const server = app.listen(rsbuildServer.port, async () => {
    // 通知 Rsbuild 自定义 Server 已启动
    await rsbuildServer.afterListen();
  });

  // 激活 WebSocket 连接
  rsbuildServer.connectWebSocket({ server });
}

更多用法可参考:

  • 示例代码。
  • rsbuild.createDevServer
  • server.middlewareMode

#API

#类型定义

type EnvironmentAPI = {
  [name: string]: {
    /**
     * 获取当前环境的构建信息
     */
    getStats: () => Promise<Stats>;
    /**
     * 在服务端加载并执行构建产物
     *
     * @param entryName - 入口名称,和 Rsbuild source.entry 的某一个 key 值对应
     * @returns 入口模块的返回值
     */
    loadBundle: <T = unknown>(entryName: string) => Promise<T>;
    /**
     * 获取编译后的 HTML 模版内容
     */
    getTransformedHtml: (entryName: string) => Promise<string>;
  };
};

type RsbuildDevServer = {
  /**
   * `connect` 实例
   * 可用于向 dev server 附加自定义中间件
   */
  middlewares: Connect.Server;
  /**
   * Node.js HTTP 服务器实例
   * - 如果使用了 `server.https` 配置,则为 `Http2SecureServer`
   * - 如果开启了 `server.middlewareMode` 配置,则为 `null`
   */
  httpServer:
    | import('node:http').Server
    | import('node:http2').Http2SecureServer
    | null;
  /**
   * 监听 Rsbuild dev server
   * 当你使用自定义 server 时,不需要调用该方法
   */
  listen: () => Promise<{
    port: number;
    urls: string[];
    server: {
      close: () => Promise<void>;
    };
  }>;
  /**
   * Rsbuild server 提供的 environment API
   */
  environments: EnvironmentAPI;
  /**
   * 解析后的端口号
   * 默认情况下,Rsbuild server 会监听 `3000` 端口,如果端口被占用,则自动递增端口号
   */
  port: number;
  /**
   * 通知 Rsbuild 自定义 Server 已启动
   * Rsbuild 会在此阶段触发 `onAfterStartDevServer` 钩子
   */
  afterListen: () => Promise<void>;
  /**
   * 激活 WebSocket 连接
   * 这确保了 HMR 正常工作
   */
  connectWebSocket: (options: {
    server: import('node:http').Server | import('node:http2').Http2SecureServer;
  }) => void;
  /**
   * 关闭 Rsbuild server
   */
  close: () => Promise<void>;
  /**
   * 打印 server URLs
   */
  printUrls: () => void;
  /**
   * 启动服务器后,在浏览器中打开 URL
   */
  open: () => Promise<void>;
  /**
   * 允许中间件向 HMR 客户端发送一些消息,HMR 客户端将根据接收到的消息类型进行不同的处理。
   * - `static-changed`: 页面将会重新加载。
   */
  sockWrite: SockWrite;
};

type CreateDevServerOptions = {
  /**
   * 是否在启动时静默获取端口号,不输出任何日志
   * @default false
   */
  getPortSilently?: boolean;
  /**
   * 是否触发 Rsbuild 编译
   * @default true
   */
  runCompile?: boolean;
};

function CreateDevServer(
  options?: CreateDevServerOptions,
): Promise<RsbuildDevServer>;

#afterListen

  • 类型: () => Promise<void>

通知 Rsbuild 自定义的开发服务器已成功启动,Rsbuild 将在这个阶段触发 onAfterStartDevServer 钩子。

例如:

import express from 'express';
import { createRsbuild } from '@rsbuild/core';

const rsbuild = await createRsbuild();
const rsbuildServer = await rsbuild.createDevServer();
const app = express();

const server = app.listen(rsbuildServer.port, async () => {
  await rsbuildServer.afterListen();
});

#close

  • 类型: () => Promise<void>

调用 close() 方法来触发 onCloseDevServer 钩子,并执行必要的清理操作。

import { createRsbuild } from '@rsbuild/core';

const rsbuild = await createRsbuild();
const rsbuildServer = await rsbuild.createDevServer();

await rsbuildServer.close();

#connectWebSocket

  • 类型:
type ConnectWebSocket = (options: {
  server: import('node:http').Server | import('node:http2').Http2SecureServer;
}) => void;

激活 WebSocket 连接,这确保了 HMR 正常工作。

Rsbuild 内置了 WebSocket 处理器以支持 HMR 功能:

  1. 当用户通过浏览器访问页面时,会自动向服务器发起 WebSocket 连接请求。
  2. Rsbuild 开发服务器检测到连接请求后,会指示内置的 WebSocket 处理器进行处理。
  3. 浏览器与 Rsbuild WebSocket 处理器成功建立连接后,便可进行实时通信。
  4. 每次重新编译完成后,Rsbuild WebSocket 处理器会通知浏览器。随后,浏览器向开发服务器发送 hot-update.(js|json) 请求,以加载编译后的新模块。

当你使用自定义 server 时,可能会遇到 HMR 连接失败的问题。这是因为自定义 server 未能将 WebSocket 连接请求正确转发至 Rsbuild 的 WebSocket 处理器。此时,你需要调用 connectWebSocket 方法来让 Rsbuild 能够接收并处理来自浏览器的 WebSocket 连接请求。

import express from 'express';
import { createRsbuild } from '@rsbuild/core';

const rsbuild = await createRsbuild();
const rsbuildServer = await rsbuild.createDevServer();
const app = express();

const httpServer = app.listen(rsbuildServer.port);

rsbuildServer.connectWebSocket({ server: httpServer });

#environments

  • Type: EnvironmentAPI

提供 Rsbuild 的 environment API,这允许你在服务端获取特定环境下的构建产物信息。

rsbuild.config.ts
const rsbuildServer = await rsbuild.createDevServer();
const webStats = await rsbuildServer.environments.web.getStats();

console.log(webStats.toJson({ all: false }));

#sockWrite

  • 类型: (type: 'static-changed') => void

向 HMR 客户端传递一些消息,HMR 客户端将根据接收到的消息类型进行不同的处理。

例如,如果你发送一个 'static-changed' 的消息,页面将会重新加载。

const rsbuildServer = await rsbuild.createDevServer();
if (someCondition) {
  rsbuildServer.sockWrite('static-changed');
}

发送 content-changed 与 static-changed 具有相同的效果。由于 content-changed 已经被弃用,请优先使用 static-changed。