Rsbuild Instance

本章节描述了 Rsbuild 实例对象上所有的属性和方法。

rsbuild.context

rsbuild.context 是一个只读对象,提供一些上下文信息。

context.version

当前使用的 @rsbuild/core 版本。

  • 类型:
type Version = string;

context.entry

构建入口对象,对应 source.entry 选项。

  • 类型:
type RsbuildEntry = Record<string, string | string[] | EntryDescription>;

如果 source.entry 被设置为函数,并针对不同的 target 返回了不同的 entry 对象,那么 context.entry 仅会包含 web target 对应的入口对象。

context.targets

构建产物类型,对应调用 Rsbuild 配置里的 output.targets 选项。

  • 类型:
type RsbuildTarget = 'web' | 'node' | 'web-worker' | 'service-worker';

type Context = {
  targets: RsbuildTarget[];
};

context.rootPath

当前执行构建的根路径,对应调用 createRsbuild 时传入的 cwd 选项。

  • 类型:
type RootPath = string;

context.distPath

构建产物输出目录的绝对路径,对应 RsbuildConfig 中的 output.distPath.root 配置项。

  • 类型:
type DistPath = string;

context.cachePath

构建过程中生成的缓存文件所在的绝对路径。

  • 类型:
type CachePath = string;

context.tsconfigPath

tsconfig.json 文件的绝对路径,若项目中不存在 tsconfig.json 文件,则为 undefined

  • 类型:
type TsconfigPath = string | undefined;

context.devServer

Dev Server 相关信息,包含了当前 Dev Server 的 hostname 和端口号。

  • 类型:
type DevServer = {
  hostname: string;
  port: number;
};

context.bundlerType

当前执行构建的构建工具类型。

  • 类型:
type bundlerType = 'rspack' | 'webpack';

Rsbuild 内部支持切换到 webpack 进行对照测试,因此提供了该字段进行区分,通常你不需要使用此字段。

rsbuild.build

调用 build 方法时,会执行一次生产环境构建。

  • 类型:
type BuildOptions = {
  mode?: 'development' | 'production';
  watch?: boolean;
  // 自定义 Compiler 对象
  compiler?: Compiler | MultiCompiler;
};

function Build(options?: BuildOptions): Promise<void>;
  • 示例:
import { logger } from '@rsbuild/core';

// build
await rsbuild.build();

// build and handle the error
try {
  await rsbuild.build();
} catch (err) {
  logger.error('Failed to build.');
  logger.error(err);
  process.exit(1);
}

开发环境构建

如果需要执行一次开发环境构建,可以将 mode 参数设置为 'development'

await rsbuild.build({
  mode: 'development',
});

监听文件变化

如果需要自动监听文件变化并重新执行构建,可以将 watch 参数设置为 true

await rsbuild.build({
  watch: true,
});

自定义 Compiler

个别情况下,你可能希望使用自定义的 compiler:

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

const compiler = rspack({
  // ...
});
await rsbuild.build({
  compiler,
});

rsbuild.startDevServer

启动本地 dev server。

  • 类型:
type StartDevServerOptions = {
  // 自定义 Compiler 对象
  compiler?: Compiler | MultiCompiler;
  // 是否在启动时静默获取端口号,默认为 false
  getPortSilently?: boolean;
};

type StartServerResult = {
  urls: string[];
  port: number;
  server: Server;
};

function StartDevServer(
  options?: StartDevServerOptions,
): Promise<StartServerResult>;
  • 示例:

启动 Dev Server:

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

// Start dev server
await rsbuild.startDevServer();

// Start dev server and handle the error
try {
  await rsbuild.startDevServer();
} catch (err) {
  logger.error('Failed to start dev server.');
  logger.error(err);
  process.exit(1);
}

成功启动 Dev Server 后,可以看到以下日志信息:

> Local: http://localhost:3000 > Network: http://192.168.0.1:3000

startDevServer 会返回以下参数:

  • urls:访问 Dev Server 的 URLs
  • port 实际监听的端口号
  • server:Server 实例对象
const { urls, port, server } = await rsbuild.startDevServer();
console.log(urls); // ['http://localhost:3000', 'http://192.168.0.1:3000']
console.log(port); // 3000

// 关闭 Dev Server
await server.close();

自定义 Compiler

个别情况下,你可能希望使用自定义的 compiler:

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

const compiler = rspack({
  // ...
});
await rsbuild.startDevServer({
  compiler,
});

静默获取端口号

某些情况下,默认启动的端口号已经被占用,此时 Rsbuild 会自动递增端口号,直至找到一个可用端口。这个过程会输出提示日志,如果你不希望这段日志,可以将 getPortSilently 设置为 true

await rsbuild.startDevServer({
  getPortSilently: true,
});

rsbuild.createDevServer

Rsbuild 配备了一个内置的开发服务器,当你执行 rsbuild dev 时,将启动 Rsbuild dev server,并提供页面预览、路由、模块热更新等功能。

如果你希望将 Rsbuild dev server 集成到自定义的 server 中,可以通过该方法获取 Rsbuild dev server 的实例方法,进行按需调用。

  • 类型:
type RsbuildDevServer = {
  /** 启动 Rsbuild DevServer */
  listen: () => Promise<{
    urls: string[];
    port: number;
    server: Server;
  }>;

  /** 以下 API 在使用自定义 Server 时会用到 */

  /** 解析后的端口号 (默认情况下,Rsbuild Server 会监听 `3000` 端口,并在端口被占用时自动递增端口号。) */
  port: number;

  /** Connect 实例,包含 Rsbuild 内置中间件 */
  middlewares: Middlewares;

  /** 通知 Rsbuild 自定义 Server 已启动 */
  afterListen: () => Promise<void>;

  /** 订阅 http upgrade 事件 */
  onHTTPUpgrade: UpgradeEvent;

  /** 关闭 Rsbuild DevServer */
  close: () => Promise<void>;
};

type CreateDevServerOptions = {
  /** 自定义 Compiler 对象 */
  compiler?: Compiler | MultiCompiler;

  /** 是否在启动时静默获取端口号,默认为 false */
  getPortSilently?: boolean;

  /** 是否触发 Rsbuild 编译,默认为 true */
  runCompile?: boolean;
};

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

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

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

export async function startDevServer() {
  // 初始化 Rsbuild
  const rsbuild = await createRsbuild({});

  const app = express();

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

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

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

  // 订阅服务器的 http 升级事件来处理 WebSocket 升级
  httpServer.on('upgrade', rsbuildServer.onHTTPUpgrade);
}

详细使用情况可参考:示例

如果你希望直接使用 Rsbuild DevServer 启动项目,可以直接使用 Rsbuild - startDevServer 方法。 startDevServer 实际上是以下代码的语法糖:

const server = await rsbuild.createDevServer();

await server.listen();

rsbuild.preview

在本地启动 Server 来预览生产环境构建的产物,需要在 rsbuild.build 方法之后执行。

  • 类型:
type StartServerResult = {
  urls: string[];
  port: number;
  server: Server;
};

function server(): Promise<StartServerResult>;
  • 示例:

启动 Server:

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

// Start preview server
await rsbuild.preview();

// Start preview server and handle the error
try {
  await rsbuild.preview();
} catch (err) {
  logger.error('Failed to start preview server.');
  logger.error(err);
  process.exit(1);
}

preview 会返回以下参数:

  • urls:访问 Server 的 URLs
  • port 实际监听的端口号
  • server:Server 实例对象
const { urls, port, server } = await rsbuild.preview();
console.log(urls); // ['http://localhost:3000', 'http://192.168.0.1:3000']
console.log(port); // 3000

// 关闭 Server
await server.close();

rsbuild.createCompiler

创建一个 compiler 对象。

createRsbuildtarget 选项包含一个值时,返回值为 Compiler;当 target 包含多个值时,返回值为 MultiCompiler

  • 类型:
function CreateCompiler(): Promise<Compiler | MultiCompiler>;
  • 示例:
const compiler = await rsbuild.createCompiler();

大部分场景下,不需要使用该 API,除非需要进行自定义 Dev Server 等高级操作。

rsbuild.addPlugins

注册一个或多个 Rsbuild 插件,可以被多次调用。

该方法需要在开始编译前调用,如果在开始编译之后调用,则不会影响编译结果。

  • 类型:
type AddPluginsOptions = { before?: string } | { after?: string };

function AddPlugins(
  plugins: RsbuildPlugins[],
  options?: AddPluginsOptions,
): Promise<void>;
  • 示例:
rsbuild.addPlugins([pluginFoo(), pluginBar()]);

// 在 bar 插件之前插入
rsbuild.addPlugins([pluginFoo()], { before: 'bar' });

// 在 bar 插件之后插入
rsbuild.addPlugins([pluginFoo()], { after: 'bar' });

rsbuild.getPlugins

获取当前 Rsbuild 实例中注册的所有 Rsbuild 插件。

  • 类型:
function GetPlugins(): RsbuildPlugin[];
  • 示例:
console.log(rsbuild.getPlugins());

rsbuild.removePlugins

移除一个或多个 Rsbuild 插件,可以被多次调用。

该方法需要在开始编译前调用,如果在开始编译之后调用,则不会影响编译结果。

  • 类型:
function RemovePlugins(pluginNames: string[]): void;
  • 示例:
// 添加插件
const pluginFoo = pluginFoo();
rsbuild.addPlugins(pluginFoo);

// 移除插件
rsbuild.removePlugins([pluginFoo.name]);

rsbuild.isPluginExists

判断某个插件是否已经被注册。

  • 类型:
function IsPluginExists(pluginName: string): boolean;
  • 示例:
rsbuild.addPlugins([pluginFoo()]);

rsbuild.isPluginExists(pluginFoo().name); // true

rsbuild.initConfigs

initConfigs 方法用于初始化 Rsbuild 内部的配置,并返回 Rsbuild 内部生成的 Rspack 配置。

通常你不需要调用 initConfigs 方法,因为调用 rsbuild.buildrsbuild.startDevServer 等方法时会自动调用 initConfigs。

  • 类型:
function InitConfigs(): Promise<{
  rspackConfigs: RspackConfig[];
}>;
  • 示例:
const { rspackConfigs } = await rsbuild.initConfigs();

console.log(rspackConfigs);

rsbuild.inspectConfig

inspectConfig 方法通常用于调试 Rsbuild 内部的配置,它会返回 Rsbuild 内部生成的 Rsbuild 配置和 Rspack 配置,将它们序列化为字符串,并支持写入到磁盘上。

如果你需要在构建过程中查看 Rsbuild 和 Rspack 配置,可以使用 调试模式,也可以通过 onBeforeBuildonBeforeCreateCompile 等 hooks 来获取。

  • 类型:
type InspectConfigOptions = {
  // 查看指定环境下的配置
  // 默认为 "development",可以设置为 "production"
  env?: RsbuildMode;
  // 是否开启冗余模式,展示配置中函数的完整内容
  // 默认为 `false`
  verbose?: boolean;
  // 指定输出路径
  // 默认为 `output.distPath.root` 配置的值
  outputPath?: string;
  // 是否将结果写入到磁盘中
  // 默认为 `false`
  writeToDisk?: boolean;
};

async function InspectConfig(options?: InspectConfigOptions): Promise<{
  rsbuildConfig: string;
  bundlerConfigs: string[];
  origin: {
    rsbuildConfig: RsbuildConfig;
    bundlerConfigs: BundlerConfigs[];
  };
}>;
  • 示例:

拿到字符串格式的 Config 内容:

const { rsbuildConfig, bundlerConfigs } = await rsbuild.inspectConfig();

console.log(rsbuildConfig, bundlerConfigs);

直接将配置内容写入到磁盘上:

await rsbuild.inspectConfig({
  writeToDisk: true,
});

rsbuild.onBeforeCreateCompiler

onBeforeCreateCompiler 是在创建底层 Compiler 实例前触发的回调函数,当你执行 rsbuild.startDevServerrsbuild.buildrsbuild.createCompiler 时,都会调用此钩子。

你可以通过 bundlerConfigs 参数获取到 Rspack 配置数组,数组中可能包含一份或多份 Rspack 配置,这取决于 Rsbuild output.targets 配置的值。

  • 类型:
function OnBeforeCreateCompiler(
  callback: (params: {
    bundlerConfigs: WebpackConfig[] | RspackConfig[];
  }) => Promise<void> | void,
): void;
  • 示例:
rsbuild.onBeforeCreateCompiler(({ bundlerConfigs }) => {
  console.log('the Rspack config is ', bundlerConfigs);
});

rsbuild.onAfterCreateCompiler

onAfterCreateCompiler 是在创建 Compiler 实例后、执行构建前触发的回调函数,当你执行 rsbuild.startDevServerrsbuild.buildrsbuild.createCompiler 时,都会调用此钩子。

你可以通过 compiler 参数获取到 Compiler 实例对象:

  • 类型:
function OnAfterCreateCompiler(callback: (params: {
  compiler: Compiler | MultiCompiler;
}) => Promise<void> | void;): void;
  • 示例:
rsbuild.onAfterCreateCompiler(({ compiler }) => {
  console.log('the compiler is ', compiler);
});

rsbuild.onBeforeBuild

onBeforeBuild 是在执行生产环境构建前触发的回调函数。

你可以通过 bundlerConfigs 参数获取到 Rspack 配置数组,数组中可能包含一份或多份 Rspack 配置,这取决于 Rsbuild output.targets 配置的值。

  • 类型:
function OnBeforeBuild(
  callback: (params: {
    bundlerConfigs?: WebpackConfig[] | RspackConfig[];
  }) => Promise<void> | void,
): void;
  • 示例:
rsbuild.onBeforeBuild(({ bundlerConfigs }) => {
  console.log('the Rspack config is ', bundlerConfigs);
});

rsbuild.onAfterBuild

onAfterBuild 是在执行生产环境构建后触发的回调函数,你可以通过 stats 参数获取到构建结果信息:

另外,在 watch 模式下你可以通过 isFirstCompile 来判断是否为首次构建。

  • 类型:
function OnAfterBuild(
  callback: (params: {
    isFirstCompile: boolean;
    stats?: Stats | MultiStats;
  }) => Promise<void> | void,
): void;
  • 示例:
rsbuild.onAfterBuild(({ stats }) => {
  console.log(stats?.toJson());
});

rsbuild.onBeforeStartDevServer

在启动开发服务器前调用。

  • 类型:
function OnBeforeStartDevServer(callback: () => Promise<void> | void): void;
  • 示例:
rsbuild.onBeforeStartDevServer(() => {
  console.log('before start!');
});

rsbuild.onAfterStartDevServer

在启动开发服务器后调用。你可以通过 port 参数获得开发服务器监听的端口号,通过 routes 获得页面路由信息。

  • 类型:
type Routes = Array<{
  entryName: string;
  pathname: string;
}>;

function OnAfterStartDevServer(
  callback: (params: { port: number; routes: Routes }) => Promise<void> | void,
): void;
  • 示例:
rsbuild.onAfterStartDevServer(({ port, routes }) => {
  console.log('this port is: ', port);
  console.log('this routes is: ', routes);
});

rsbuild.onCloseDevServer

关闭开发服务器时调用。

  • 类型:
function onCloseDevServer(callback: () => Promise<void> | void): void;
  • 示例:
rsbuild.onCloseDevServer(async () => {
  console.log('close dev server!');
});

rsbuild.onBeforeStartProdServer

在启动生产预览服务器前调用。

  • 类型:
function OnBeforeStartProdServer(callback: () => Promise<void> | void): void;
  • 示例:
rsbuild.onBeforeStartProdServer(() => {
  console.log('before start!');
});

rsbuild.onAfterStartProdServer

在启动生产预览服务器后调用,你可以通过 port 参数获得生产服务器监听的端口号,通过 routes 获得页面路由信息。

  • 类型:
type Routes = Array<{
  entryName: string;
  pathname: string;
}>;

function OnAfterStartProdServer(
  callback: (params: { port: number; routes: Routes }) => Promise<void> | void,
): void;
  • 示例:
rsbuild.onAfterStartProdServer(({ port, routes }) => {
  console.log('this port is: ', port);
  console.log('this routes is: ', routes);
});

rsbuild.onDevCompileDone

在每次开发环境构建结束后调用,你可以通过 isFirstCompile 来判断是否为首次构建。

  • 类型:
function OnDevCompileDone(
  callback: (params: {
    isFirstCompile: boolean;
    stats: Stats | MultiStats;
  }) => Promise<void> | void,
): void;
  • 示例:
rsbuild.onDevCompileDone(({ isFirstCompile }) => {
  if (isFirstCompile) {
    console.log('first compile!');
  } else {
    console.log('re-compile!');
  }
});

rsbuild.onExit

在进程即将退出时调用,这个钩子只能执行同步代码。

  • 类型:
function OnExit(callback: () => void): void;
  • 示例:
rsbuild.onExit(() => {
  console.log('exit!');
});

rsbuild.getRsbuildConfig

获取 Rsbuild 配置。

  • 类型:
type GetRsbuildConfig = {
  (): Readonly<RsbuildConfig>;
  (type: 'original' | 'current'): Readonly<RsbuildConfig>;
  (type: 'normalized'): NormalizedConfig;
};
  • 参数:

你可以通过 type 参数来指定读取的 Rsbuild 配置类型:

// 获取用户定义的原始 Rsbuild 配置。
getRsbuildConfig('original');

// 获取当前的 Rsbuild 配置。
// 在 Rsbuild 的不同执行阶段,该配置的内容会发生变化。
// 比如 `modifyRsbuildConfig` 钩子执行后会修改当前 Rsbuild 配置的内容。
getRsbuildConfig('current');

// 获取归一化后的 Rsbuild 配置。
// 该方法必须在 `modifyRsbuildConfig` 钩子执行完成后才能被调用。
// 等价于 `getNormalizedConfig` 方法。
getRsbuildConfig('normalized');
  • 示例:
rsbuild.onBeforeBuild(() => {
  const config = api.getRsbuildConfig();
  console.log(config.html?.title);
});

rsbuild.getNormalizedConfig

获取归一化后的 Rsbuild 配置,该方法必须在 modifyRsbuildConfig 钩子执行完成后才能被调用。

相较于 getRsbuildConfig 方法,该方法返回的配置经过了归一化处理,配置的类型定义会得到收敛,比如 config.htmlundefined 类型将被移除。

推荐优先使用该方法获取配置。

  • 类型:
function GetNormalizedConfig(): Readonly<NormalizedConfig>;
  • 示例:
rsbuild.onBeforeBuild(() => {
  const config = api.getNormalizedConfig();
  console.log(config.html.title);
});

rsbuild.getHTMLPaths

获取所有 HTML 产物的路径信息。

该方法会返回一个对象,对象的 key 为 entry 名称,value 为 HTML 文件在产物目录下的相对路径。

  • 类型:
function GetHTMLPaths(): Record<string, string>;
  • 示例:
rsbuild.onBeforeBuild(() => {
  const htmlPaths = api.getHTMLPaths();
  console.log(htmlPaths); // { main: 'html/main/index.html' };
});