Rspack 2.2 发布:30+ 项性能优化,拥抱 Solid 2.0

我们很高兴地宣布,Rspack 2.2 现已发布!


值得关注的变更如下:

  • 性能
    • 性能提升
    • HMR 改进
    • 更短的模块 ID
  • 新特性
    • import.meta 改进
    • 支持 Browserslist Baseline
    • 支持更多平台
  • 生态
    • Rsbuild
    • Rstest
    • Rslint
    • Rslib
    • Rspress
    • Agent plugin
  • 升级指南

性能

性能提升

Rspack 2.2 包含 30 多项性能优化,例如:

  • 优化模块合并、chunk 拆分和 Source Map 生成等核心流程性能。在基准测试中,生产构建时间从 1822 ms 降至 1725 ms,提升约 5%。
  • 优化 CopyRspackPlugin 的性能。在复制大量文件时,性能提升约 3~4 倍。
  • 优化 Wasm 产物的包体积,从 29.5 MB 降至 28.4 MB,减少约 1.1 MB。
  • 并行编译 SWC Wasm 插件,这减少了插件加载时间。例如,coverage-instrument 插件的加载时间减少约 80%。
  • 内置 CSS 的解析速度提升了约 3 倍:
场景 优化前 优化后 性能提升
CSS 开发构建 320.3 ms 87.2 ms 3.7 倍
CSS 生产构建 354.1 ms 121 ms 2.9 倍

HMR 改进

Rspack 2.2 避免了 HMR 中不必要的 CSS 请求。此前,即使只修改了 JavaScript 代码,浏览器也会在热更新时请求相关的 CSS 文件,比较内容后再判断是否需要更新样式。样式表越大,这一步带来的额外耗时就越明显。

#14682 中,Rspack 改为在构建阶段判断 CSS 是否发生变化,使浏览器仅在需要时请求 CSS 资源,从而避免不必要的 HTTP 请求。因此,JavaScript 热更新耗时不再随样式表体积明显增加:

样式表体积 优化前 优化后
0.5 MB ~50 ms ~5 ms
2.1 MB ~170 ms ~5 ms
4.1 MB ~385 ms ~6 ms

此外,#14580 修复了 mini-css-extract-plugin 热更新时样式短暂失效的问题,避免页面闪烁。

更短的模块 ID

Rspack 现在支持为模块和 chunk 生成更短的 ID。相比当前的 deterministic 策略,新的 compat-hashed 策略会从稳定 hash 中选取最短可用前缀,在保持 ID 稳定和运行时索引效率的同时,进一步减小产物体积。

在一个真实项目中,产物体积变化如下:

指标 deterministic compat-hashed 体积减少
Minified JS 25,795.2 KB 25,710.6 KB 84.6 KB(0.33%)
Minified + gzip 7,103.3 KB 7,041.7 KB 61.6 KB(0.87%)

通过 optimization.chunkIdsoptimization.moduleIds 选项即可开启:

js 复制代码
// rspack.config.mjs
export default {
  optimization: {
    chunkIds: 'compat-hashed',
    moduleIds: 'compat-hashed',
  },
};

新特性

import.meta 改进

Rspack 现在支持通过 import.meta 来访问 Rspack 特有的模块变量。相比 CommonJS 风格的变量,新用法更符合 ESM 规范,推荐在 ESM 模块中优先使用:

js 复制代码
// Before
__webpack_public_path__ = '/assets/';

// After
import.meta.rspackPublicPath = '/assets/';

此外,import.meta.glob 新增了 caseSensitive 选项。设置为 false 时,glob 匹配会忽略文件路径的大小写:

js 复制代码
const modules = import.meta.glob('./pages/**/*.js', {
  caseSensitive: false,
});

支持 Browserslist Baseline

Rspack 现在支持 Browserslist 的 Baseline 查询。你可以根据 Baseline 特性集来指定目标浏览器版本。例如,兼容 Baseline 广泛可用的特性,可以配置:

js 复制代码
// rspack.config.mjs
export default {
  target: 'browserslist:baseline widely available',
};

你也可以使用 baseline widely available on 2025-05-01 按指定日期查询,详见 target 配置文档

支持更多平台

Rspack 为更多 Linux 平台提供了预编译的原生 binding:

  • RISC-V 64 位:linux-riscv64-gnulinux-riscv64-musl
  • ppc64le 和 s390x 架构:linux-ppc64-gnulinux-s390x-gnu

在这些平台上安装 Rspack 时,可以直接使用对应的原生 binding,无需回退到 Wasm binding。完整的平台列表请参考环境准备

生态

Rsbuild

Rsbuild 2.2 已经与 Rspack 2.2 同步发布。

导入源文本

Rsbuild 现在支持使用 import attributes 语法 将文件原始内容作为字符串导入:

ts 复制代码
import rawCSS from './example.css' with { type: 'text' };

这与 TC39 的 Import Text 提案 保持一致。

Node.js 拆包优化

Node.js 构建现在会默认启用 chunk 拆分,将共享模块提取为独立的 chunk,从而减少重复代码和 SSR 内存占用。

下面是 TanStack Start 用户提供的 实测数据

指标 Rsbuild 2.1 Rsbuild 2.2 变化
服务端产物体积 298 MB 4.1 MB 减少 98%
访问所有路由后的内存占用 486 MB 129 MB 减少 73%
路由平均访问耗时 7.2 ms 1.6 ms 减少 78%
共享组件的 HMR 耗时 7.1 s 0.98 s 减少 86%

测试应用包含 300 个路由和 400 个共享组件,实际收益取决于项目规模和模块结构。

支持 Solid v2

Rsbuild 现在支持 Solid v2 RC,并默认使用 Solid 全新的 Rust 编译器。在 Solid 官方基准测试中,新编译器的编译速度相比此前的 Babel 实现提升 20 倍以上

升级 @rsbuild/plugin-solid 至 v2 beta 版本,然后移除 Babel 插件即可体验:

diff 复制代码
-import { pluginBabel } from '@rsbuild/plugin-babel';
import { pluginSolid } from '@rsbuild/plugin-solid';

export default {
  plugins: [
-   pluginBabel({
-     include: /\.(?:jsx|tsx)$/,
-   }),
    pluginSolid(),
  ],
};

Octane 模板

create-rsbuild 现在支持创建 Octane 项目。Octane 是一个高性能 JavaScript UI 框架。你可以使用 React API 编写组件,Octane 会将这些组件编译为直接更新 DOM 的代码。

运行以下命令即可创建一个 Octane 项目:

bash 复制代码
npx -y create-rsbuild@latest my-app -t octane-ts

动态端口

Rsbuild 现在支持将 server.port 设置为 0,由操作系统自动分配一个可用端口:

ts 复制代码
// rsbuild.config.ts
export default {
  server: {
    port: 0,
  },
};

这在测试场景中尤其有用,可以避免多个测试同时启动 Rsbuild server 时发生端口冲突。

定制压缩配置

Rsbuild 现在支持同时配置多种压缩选项。为 minify.jsOptions 传入数组,可以针对不同产物设置不同的压缩策略。例如,仅移除主 bundle 中的 console 调用:

ts 复制代码
// rsbuild.config.ts
export default {
  output: {
    minify: {
      jsOptions: [
        {
          include: /main\./,
          minimizerOptions: {
            compress: { drop_console: true },
          },
        },
        {
          exclude: /main\./,
          minimizerOptions: {
            compress: { drop_console: false },
          },
        },
      ],
    },
  },
};

自定义重启流程

基于 Rsbuild 的框架和工具现在可以自行控制重启流程。

Rsbuild 的 JavaScript API 现已支持 restart 选项,用于处理开发服务器(rsbuild dev)或监听构建(rsbuild build --watch)的重启请求:

ts 复制代码
import { createRsbuild } from '@rsbuild/core';

await createRsbuild({
  restart: (restart) => {
    // 自定义重启逻辑
  },
});

Rsbuild 插件也可以通过监听 onRestart hook 来执行自定义逻辑。

Rstest

模块联邦测试

Rstest 现在支持模块联邦测试:可以在 Node.js、JSDOM 和 Browser Mode 环境中,直接测试通过模块联邦暴露的真实远程模块。

在 Rstest 配置文件中引入 @module-federation/rstest 即可:

ts 复制代码
// rstest.config.ts
import { federation } from '@module-federation/rstest';
import { defineConfig } from '@rstest/core';

export default defineConfig({
  plugins: [
    federation({
      name: 'host',
      // options
    }),
  ],
});

详见 Module Federation × Rstest 集成文档

Playwright E2E 测试

Rstest 新增了 @rstest/playwright,让 E2E 测试也能使用 Rstest 的测试运行器、配置和报告能力。

它提供 Playwright 风格的断言 API,可用于测试本地开发服务器、预览服务器或已部署的应用,并与单元测试共享一致的工作流:

ts 复制代码
import { expect, test } from '@rstest/playwright';

test('home page', async ({ page, serve }) => {
  const { url } = await serve('./dist/index.html');

  await page.goto(url);
  await expect(page.locator('h1')).toHaveText('Home');
});

预打包测试环境

Rstest 现在支持预打包 DOM 测试环境。开启后,Rstest 会预打包 jsdomhappy-dom,并在多个 worker 之间复用产物,避免为每个测试文件重复解析和初始化环境。对于 DOM 测试较多的项目,这可以显著缩短整体测试耗时。

基准测试 中,一个包含 1000 个测试用例的项目取得了以下收益:

测试环境 原生加载 预打包 耗时降低
jsdom 30.0.1 16.99 s 10.57 s 37.8%
happy-dom 20.11.1 6.35 s 2.98 s 53.0%

该能力默认关闭,可通过 testEnvironment.prebundle 开启:

ts 复制代码
// rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  testEnvironment: {
    name: 'jsdom',
    prebundle: 'auto',
  },
});

设置为 'auto' 时,Rstest 只会预打包已验证兼容的环境版本;如果无法构建、加载或验证预打包产物,则会自动回退到原生加载。实际收益会因项目规模和运行环境而异。

Rslint

更多 Lint 规则

Rslint 现在内置支持超过 500 条 lint 规则,并实现了 @typescript-eslint全部规则和预设

例如,你可以通过 recommendedTypeChecked 预设来启用所有推荐的类型感知规则:

ts 复制代码
// rslint.config.ts
import { defineConfig, js, ts } from '@rslint/core';

export default defineConfig([
  js.configs.recommended,
  ts.configs.recommendedTypeChecked,
]);

配置类型提示

defineConfig 现在为 ESLint core 和 @typescript-eslint 规则提供完整的类型提示,包括规则名称和选项类型。

ts 复制代码
// rslint.config.ts
import { defineConfig } from '@rslint/core';

export default defineConfig([
  {
    rules: {
      '@typescript-eslint/no-floating-promises': 'error',
      '@typescript-eslint/no-unused-vars': [
        'error',
        { argsIgnorePattern: '^_' },
      ],
    },
  },
]);

内置常用 globals

@rslint/core 现在提供内置的 globals 对象,其中包含浏览器、Node.js 和 Rstest 等常用环境的全局变量定义:

ts 复制代码
// rslint.config.ts
import { defineConfig, globals } from '@rslint/core';

export default defineConfig([
  {
    languageOptions: {
      globals: globals.browser,
    },
  },
]);

JavaScript API

@rslint/core 现在提供了与 ESLint v10 形态对齐的 JavaScript API

ts 复制代码
import { Rslint } from '@rslint/core';

const rslint = new Rslint({ fix: true });
const results = await rslint.lintFiles(['src/**/*.ts']);

await Rslint.outputFixes(results);

JavaScript API 也支持通过 lintText 检查内存中的源码,并使用 virtualFiles 提供配置、tsconfig.json 和项目文件,适合用于编辑器和 Playground 等不直接依赖磁盘文件的集成场景。

Rslib

支持 TypeScript 7

Rslib 0.23.2 支持使用 TypeScript 7 生成类型声明文件。安装 TypeScript 7 后,Rslib 会自动启用原生 TypeScript,类型声明文件生成速度可提升约 5 至 10 倍

bash 复制代码
pnpm add typescript@latest -D

Rslib 1.0 即将发布

Rslib 1.0 RC 版本现已发布,正式版也即将到来。如果你正在使用 Rslib 0.x,可以参考 从 0.x 升级到 v1 指南,了解相关不兼容更新。

Rspress

Rspress 在 AFDocs Agent-friendly 评分中达到 100/100。

Rspress 通过 llms.txtSSG-MDAccept: text/markdowninjectLlmsHint 等能力,让 Agent 更容易发现、读取和理解文档。更多设计与实践可以参考 怎样构建一个 Agent-friendly 的网站

Agent plugin

Rstack 推出了基于 Agent Plugins 1.0 的 Rstack Agent Plugin,可以在 GitHub Copilot、Codex、Cursor 等所有支持该插件规范的 Agent 客户端中使用。

只需安装一个插件,即可获得完整的 Rstack Skills 集合,让 Agent 更好地开发和维护 Rstack 项目。

安装方式:

一键安装 Rstack Agent Plugin:复制以下提示词发送给你的 Agent。

text 复制代码
Install the Rstack Agent Plugin from https://github.com/rstackjs/agent-skills.

查看 Rstack Agent Skills 了解更多。

升级指南

Wasm 插件

Rspack 2.2 将 swc_core 从 76 升级至 77,这改变了 SWC Wasm 插件边界上的 AST 序列化格式。基于旧版 SWC 构建的 Wasm 插件将无法继续加载,构建时会抛出如下错误:

text 复制代码
The version of the SWC Wasm plugin you're using might not be compatible with 'builtin:swc-loader'.

如果你正在使用 SWC Wasm 插件,请使用 SWC 77 重新构建插件,或升级到兼容 SWC 77 的版本。可以在 plugins.swc.rs 中查找与当前 Rspack 版本匹配的插件版本。

详见:常见问题 - SWC 插件版本不匹配

RSC 插件

此前,RSC 插件会通过包装客户端引用(Client Reference),在渲染组件时插入 CSS <link> 标签。由于包装后的导出不再是原始的 Client Reference,某些导出形式可能无法保留 Client Reference 标识。

Rspack 2.2 不再包装客户端引用,而是通过 React 的 preinit 加载客户端组件的 CSS。

这项调整改变了 RSC 中客户端组件 CSS 的加载方式,是一项针对 RSC 框架集成的破坏性变更。如果你正在集成 Rspack RSC 插件,请将 react-server-dom-rspack 同步升级到 0.1.0

相关推荐
额额额对了1 小时前
Linux 进程管理详解:从概念到实战
java·服务器·前端
fatcoder1 小时前
玩转 Redis · Set 篇
前端·redis·后端
爱喝麻油的小哆1 小时前
🐾 Day 5|桌面数字人-接入llm可以对话啦
前端·three.js
我叫黑大帅1 小时前
关于没有对生产者做校验的思考
前端·面试·架构
掘金者阿豪1 小时前
你的公网 IP 是专线还是动态变化的?一文讲透动态 IP 与固定 IP 的那些事
前端·后端
invicinble1 小时前
把握理解技术文章转化为工程水平的深度理解
前端
前端炒粉1 小时前
fetch+readablestream(Streamable)流式输出
java·服务器·前端
风骏时光牛马2 小时前
AIRAG服务异常监控告警
前端
大厂码农老A2 小时前
汤森路透的座上宾?Qwen3.5-397B-A17B到底有什么本事?
前端·人工智能·后端