CC 4.0 协议声明

本节内容派生于以下链接指向的内容 ,并遵守 CC BY 4.0 许可证的规定。

以下内容如果没有特殊声明,可以认为都是基于原内容的修改和删减后的结果。

JavaScript API

Rspack 提供了一组 JavaScript API,可在 Node.js 或 Bun 等 JavaScript 运行时中使用。

当你需要自定义构建或开发流程时,JavaScript API 非常有用,因为此时所有的报告和错误处理都必须自行实现,Rspack 仅仅负责编译的部分。所以 stats 配置选项不会在 rspack() 调用中生效。

提示

@rspack/core 是基于 Webpack JavaScript API 设计的,旨在提供一致的功能和相似的使用体验。

安装

开始使用 Rspack 的 JavaScript API 之前,首先你需要安装 @rspack/core

npm
yarn
pnpm
bun
npm add @rspack/core -D

在 JavaScript 文件中,引入 @rspack/core 模块:

build.js
import { rspack } from '@rspack/core';

rspack()

导入的 rspack 函数会将配置对象传给 Rspack,如果同时传入回调函数会在 Rspack compiler 运行时被执行:

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

rspack({}, (err, stats) => {
  if (err || stats.hasErrors()) {
    // ...
  }
  // 处理完成
});
function rspack(
  options: MultiRspackOptions | RspackOptions,
  callback?: Callback<Error, MultiStats | Stats>,
): null | MultiCompiler | Compiler;
提示

err 对象不包含编译错误,必须使用 stats.hasErrors() 单独处理,文档的错误处理将对这部分进行详细介绍。err 对象只包含 Rspack 相关的问题,例如配置错误等。

提示

你也可以为 rspack() 函数提供一个配置数组。更多详细信息,请查看 MultiCompiler 章节。

Compiler 实例

如果你不向 rspack 传入可执行的回调函数,它会返回一个 Rspack Compiler 实例。你可以通过手动执行它或者为它的构建时添加一个监听器,就像 CLI 类似。Compiler 实例提供了以下方法:

  • .run(callback)
  • .watch(watchOptions, handler)

通常情况下,仅会创建一个主要 Compiler 实例,虽然可以创建一些子 compiler 来代理到特定任务。Compiler 基本上只是执行最低限度的功能,以维持生命周期运行的功能。它将所有的加载、打包和写入工作,都委托到注册过的插件上。

Compiler 实例上的 hooks 属性,用于将一个插件注册到 Compiler 的生命周期中的所有钩子事件上。Rspack 使用 RspackOptionsApply 来配置 Compiler 实例以及所有内置插件。

关于 Compiler 的更多细节请参考 Compiler API

执行

使用 run 方法启动所有编译工作。完成之后,执行传入的的 callback 函数。最终记录下来的概括信息(stats)和错误(errors),都应在这个 callback 函数中获取。

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

const compiler = rspack({
  // ...
});

compiler.run((err, stats) => {
  // ...

  compiler.close(closeErr => {
    // ...
  });
});
警告

该 API 不支持并发编译。当你使用 runwatch 时,请先调用 close 并等待其完成,然后再调用 runwatch。并发编译会破坏输出文件。

监听

调用 watch 方法会触发 Rspack 执行,但之后会监听变更(很像 CLI 命令: rspack --watch),一旦 Rspack 检测到文件变更,就会重新执行编译。该方法返回一个 Watching 实例。

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

const compiler = rspack({
  // ...
});

const watching = compiler.watch(
  {
    // 示例
    aggregateTimeout: 300,
    poll: undefined,
  },
  (err, stats) => {
    // 这里打印 watch/build 结果...
    console.log(stats);
  },
);

Watching 配置选项的细节可以在这里查询。

警告

文件系统不正确的问题,可能会对单次修改触发多次构建。因此,在上面的示例中,一次修改可能会多次触发 console.log 语句。用户应该预知此行为,并且可能需要检查 stats.hash 来查看文件哈希是否确实变更。

关于 Watching 的更多细节请参考 Compiler.watch

Stats

stats 对象会被作为 rspack() 回调函数的第二个参数传递,可以通过它获取到代码编译过程中的有用信息,包括:

  • 错误和警告(如果有的话)
  • 计时信息
  • 模块和 chunk 信息

Rspack CLI 正是基于这些信息在控制台展示友好的格式输出。

提示

当使用 MultiCompiler 时,会返回一个 MultiStats 实例,它实现与 stats 相同的接口,也就是下面描述的方法。

关于 Stats 对象更多细节请参考 Stats API

MultiCompiler

MultiCompiler 模块可以让 Rspack 同时执行多个配置。如果传给 Rspack 的 JavaScript API 的 options 参数,该参数由是由多个配置对象构成的数组,Rspack 会相应地创建多个 compiler 实例,并且在所有 compiler 执行完毕后调用 callback 方法。

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

rspack(
  [
    { entry: './index1.js', output: { filename: 'bundle1.js' } },
    { entry: './index2.js', output: { filename: 'bundle2.js' } },
  ],
  (err, stats) => {
    process.stdout.write(stats.toString() + '\n');
  },
);

关于 MultiCompiler 对象更多细节请参考 MultiCompiler API

错误处理

完备的错误处理中需要考虑以下三种类型的错误:

  • 致命的 Rspack 错误(配置出错等)
  • 编译错误(缺失的模块,语法错误等)
  • 编译警告

下面是一个覆盖这些场景的示例:

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

rspack(
  {
    // ...
  },
  (err, stats) => {
    if (err) {
      console.error(err.stack || err);
      if (err.details) {
        console.error(err.details);
      }
      return;
    }

    const info = stats.toJson();

    if (stats.hasErrors()) {
      console.error(info.errors);
    }

    if (stats.hasWarnings()) {
      console.warn(info.warnings);
    }

    // Log result...
  },
);

自定义文件系统

与 webpack 的差异
  1. 当前 Rspack 对于 inputFileSystem 的支持存在限制,尚未实现与 webpack 一致的自定义文件系统读取能力。请参考:Issue #5091

  2. Rspack 在指定的输出文件系统,不再需要提供 mkdirpjoin 工具方法。

默认情况下,Rspack 使用普通文件系统来读取文件并将文件写入磁盘。但是,还可以使用不同类型的文件系统(内存, webDAV 等)来更改输入或输出行为。为了实现这一点,可以改变 inputFileSystemoutputFileSystem。例如,可以使用 memfs 替换默认的 outputFileSystem,以将文件写入到内存中,而不是写入到磁盘:

import { createFsFromVolume, Volume } from 'memfs';
import { rspack } from '@rspack/core';

const fs = createFsFromVolume(new Volume());
const compiler = rspack({
  /* 配置选项 */
});

compiler.outputFileSystem = fs;
compiler.run((err, stats) => {
  // 之后读取输出:
  const content = fs.readFileSync('...');
  compiler.close(closeErr => {
    // ...
  });
});