Rspack 0.2 发布公告

2023 年 6 月 2 日

距离 Rspack 0.1 发布已经过去了将近三个月,我们非常感谢社区给予的关注和反馈。

在 0.2 版本中,我们添加了许多功能,例如:realContentHash、DataURI、支持 ESM 格式、增强了与 webpack 的兼容性,并优化了许多细节。此外,得益于与 webpack API 的兼容性,我们也进一步实现了对周边生态的兼容,完成了对 vue-loader 17 版(对应 Vue3)和 15 版(对应 Vue2)的兼容性测试。现在你可以尝试在 Vue2/3 项目中使用 Rspack。

我们期待你体验 0.2 版本带来的这些新改进,并欢迎你提供反馈。

主要功能更新

加载器

0.2 版本完成了对大部分加载器 API 的兼容,包括:inline match resource、pitching loader 和 inline loader。更多 API 进一步增强了与 webpack 加载器的兼容性,具体细节可以在我们的 webpack 兼容性更新中查看 加载器 API

插件钩子

添加了新的插件钩子。

编译器钩子

  1. beforeCompile
  2. afterCompile

编译钩子

  1. optimizeModules
  2. optimizeChunkModule
  3. finishModules
  4. chunkAsset

NormalModuleFactory 钩子

  1. beforeResolve
  2. afterResolve
  3. ResolveForScheme

ContextModuleFactory 钩子

  1. beforeResolve

realContentHash

我们实现了 optimization.realContentHash,它根据最终产物的文件内容计算 Hash。这使得生成的 Hash 更加稳定,并更好地用于缓存。在 0.2 版本中,此功能将在生产环境构建中默认启用。

ESM/System 格式

在新版本中,可以生成 System/ESM 产物,输出 ESM 产物的配置如下

rspack.config.js
module.exports = {
  // …
  experiments: {
    outputModule: true,
  },
  output: {
    chunkFormat: 'module',
    chunkLoading: 'import',
    library: {
      type: 'module',
    },
  },
};

新的 SplitChunksPlugin 实现

我们对 Rspack 中 SplitChunksPlugin 的现有实现进行了重构,使 SplitChunksPlugin 的行为更加可预测,并降低了排查相关问题的花费。

重构之后,我们有信心在 SplitChunksPlugin 上实现更多功能。我们很高兴地宣布,在 0.2 版本中,SplitChunksPlugin 支持以下配置选项

  • splitChunks.maxSize
  • splitChunks.maxAsyncSize
  • splitChunks.maxInitialSize
  • splitChunks.maxAsyncRequests
  • splitChunks.maxInitialRequests

在 0.2 版本中,我们将默认使用新的 SplitChunksPlugin。如果你遇到问题,请及时提供反馈,我们会尽快修复。你可以通过使用 experiments.newSplitChunks: false 选项切换回弃用的实现,但我们强烈建议使用新版本。在 0.3 版本中,我们将移除弃用的实现。

DataURI 支持

我们实现了对 DataURI 的支持。现在你可以编写以下代码来实现虚拟模块

import x from 'data:text/javascript,export default 42';

此外,我们支持 mimetypescheme 作为两种类型的模块规则条件。例如,你可以通过以下方法使 scheme'data' 的资源不再被视为内联处理,而是作为独立的资源文件

rspack.config.js
module.exports = {
  module: {
    rules: [
      {
        scheme: 'data',
        type: 'asset/resource',
      },
    ],
  },
};

重大变更

  • 文件名生成逻辑对齐

    在 0.1.12 版本中,我们进一步与 webpack 对齐了文件名生成逻辑,并重构了文件名生成的实现。但是,output.filenameoutput.chunkFilenameoutput.cssFilenameoutput.cssChunkFilename 中的 [ext] 将不再被替换。此行为现在与 webpack 一致,但对于 Rspack 0.1.12 之前的版本来说是一个重大变更。如果你在上述 4 个文件名配置中使用了 [ext],你需要将其更改为相应的 .js.css,例如

    rspack.config.js
    module.exports = {
      output: {
    -    filename: "[name][ext]",
    +    filename: "[name].js",
    
    -    chunkFilename: "async/[name][ext]",
    +    chunkFilename: "async/[name].js",
    
    -    cssFilename: "[name][ext]",
    +    cssFilename: "[name].css",
    
    -    cssChunkFilename: "async/[name][ext]",
    +    cssChunkFilename: "async/[name].css",
      }
    }

    详情:https://github.com/web-infra-dev/rspack/issues/3270

  • 在生产环境中默认启用 realContentHash

    详情:https://github.com/web-infra-dev/rspack/pull/3338

  • 修改了 Resolve 的扩展名

    详情:https://github.com/web-infra-dev/rspack/pull/3242

  • 修改了 @rspack/dev-middleware 和 @rspack/html-plugin 的导出方法,并移除了 @rspack/dev-middleware 导出的 getRspackMemoryAssets

    详情:https://github.com/web-infra-dev/rspack/pull/3358

Webpack 兼容性更新

随着我们支持越来越多的 webpack API,我们也与更多社区插件和加载器兼容。我们已经适配了一些社区中需求量很大的插件和加载器。

fork-ts-checker-webpack-plugin

Rspack 中对 TypeScript 的类型检查是高度需求的。Rspack 已经完全适配了 fork-ts-checker-webpack-plugin。你可以使用此插件在编译期间执行 TypeScript 类型检查。但是,由于 TypeScript 的类型检查通常非常耗时,这使得在大型项目上进行类型检查所需的时间可能远远超过 Rspack 本身的构建时间。在开发模式下,此插件不会阻塞构建,但在构建模式下,此插件会阻塞构建。请根据你的实际需求选择是否启用此插件。

license-webpack-plugin

社区中广泛报道的需求是支持从代码中提取许可证。现在,Rspack 可以通过 license-webpack-plugin 满足从代码中提取许可证的需求。

style-loader & css-loader

尽管 Rspack 支持并默认启用 webpack 的 experiments.css 功能,但仍然有许多社区强烈依赖于 style-loader & css-loader。我们在 0.2.0 中完成了对 style-loader 和 css-loader 的支持,这也使我们能够更好地适应 Svelte 和 Vue 等框架。

node-loader

在使用 Rspack 打包 NestJS 等 Node 应用时,一个常见需求是打包包含附加组件的库。这些库的原生依赖项不能直接打包到 js 中,因此需要特殊处理。Rspack 已经适配了 node-loader,所以你现在可以使用 Rspack 构建 node 应用。

Rspack 还对 webpack 的插件进行了额外的适配。我们已经跟踪了已适配的插件和加载器,位于 loader-compatplugin-compat。如果你发现你正在使用的社区插件或加载器也兼容,欢迎将其提交给我们,以便我们将其列入我们的兼容性矩阵。

框架生态更新

Modern.js 框架

得益于Modern.js 框架和 Rspack 的紧密协作和并行迭代,Modern.js Rspack 模式已覆盖框架 85% 的功能,支持 SSR、BFF、微前端场景,并与 TypeScript 类型检查、代码兼容性检测等功能保持一致。

在字节跳动,超过 80 个项目正在使用 Modern.js Rspack 模式。其中一些项目已经部署到生产环境,并获得了 10 倍的构建性能提升。

Modern.js 文档

除了 Modern.js 框架之外,Modern.js 体系下的文档站点解决方案 - Modern.js Doc - 也已将打包器从 webpack 切换到 Rspack,并基于 Rust 重写了 MDX 编译过程。

与之前使用 webpack 的版本相比,当前版本的构建速度可以缩短到秒级。以 Modern.js 官方网站文档为例,项目的启动和构建时间已经从 30 秒缩短到不到 2 秒。未来,我们计划将 Modern.js Doc 重命名为 Rspress,作为 Rspack 的官方文档站点解决方案,并通过单独的仓库进行维护。

欢迎访问 Modern.js 代码仓库,体验上述内容。

Vue

Rspack 0.2 已实现与 vue-loader 的兼容!对于 Vue3 项目,可以使用 Rspack 的原生 CSS 和 TS 处理器来提升 Vue 项目的编译速度。您只需将 vue-loader 升级到 17.2.2 版本或更高版本,并设置 experimentalInlineMatchResource: true 即可。有关 Vue3/Vue2 支持的更多信息,请参考 guide-vue

Svelte

得益于 Rspack 对 Loader API 的出色支持以及 svelte-loader 的优秀设计,Rspack 已完全适配 svelte-loader。因此,您可以直接在 Rspack 中使用 svelte-loader 进行 svelte 应用开发。您可以参考 example-svelte 来完成 svelte-loader 相关配置。

Storybook

在 Storybook 团队的帮助下,Rspack 已完成对 Storybook React 版本的支持。您可以按照 迁移 Storybook 方法,从 webpack 版本迁移到 Rspack 版本。实际项目测试表明,在不开启 docgen 功能的情况下,Rspack 版本比 Webpack 版本快 5-10 倍。当开启 docgen 时,由于 Rspack 仍然依赖 babel 来处理 docgen,性能会受到影响,但仍然有 2-3 倍的提升。

Angular

Valor 团队的帮助下,Rspack 已完成对 Angular 的初步支持。您可以使用 Rspack 来构建 Angular 应用程序,但对 dev 和 HMR 的支持尚未完全适配。我们将在 0.2.x 版本中继续跟进 Angular 的支持。

NestJS

RosaNxValor 的帮助下,Rspack 已完成对 NestJS 的编译支持。您可以使用 Rspack 来打包 NestJS 应用程序,实际项目测试表明,Rspack 比 webpack 版本有 5-10 倍的构建性能提升。

基准测试

增加了与 esbuild 的基准测试比较。有关更多详细信息,请参考以下链接:https://github.com/web-infra-dev/performance-compare

benchmark

开发指南

Rspack 团队珍惜开源社区的宝贵贡献,并希望积极促进协作。我们致力于保持开放的态度,努力在每一步都与社区互动并参与。

这就是我们目前正在编写一份全面的开发指南的原因,该指南为贡献者提供了所有必要的材料,以促进 Rspack 的开发。

当前版本的指南包含构建、测试、调试和分析 Rspack 所需的所有必要材料。此外,它还包括贡献程序,例如创建最小的可重现示例。未来,该指南将提供对 Rspack 架构的深入概述,使贡献者能够深入了解项目的复杂内部工作原理。

测试基础设施

为了自信地发布,我们目前正在

  • 在 Rspack 仓库中构建和测试一系列示例(目前有 38 个示例)
  • 将 webpack 仓库中的所有 webpack 测试移植过来
  • 在 Node 14、16 和 18 上运行所有测试
  • 维护一个独立的 ecosystem-ci 仓库用于集成测试

每日构建

为了加快迭代速度,Rspack 每天都会发布带有 "@nightly" 标签的版本到 npm。

鸣谢

随着 Rspack 0.2 的发布,我们衷心感谢所有为这个版本付出努力的贡献者。

特别感谢

  • @TheLarkInn@alexander-akait,他们回答并解决了 Rspack 团队关于 Webpack 的许多问题。
  • @zackarychapple@valorkin@edusperoni@Coly101 帮助 Rspack 团队完成了对 Angular 的基本支持,以及 @zackarychapple 对本发布博文的审阅。
  • @suxin2017,他在 Rspack 中支持了 System.js 格式和 optional-dependency 功能,并在 Windows 兼容性方面做出了很多贡献。
  • @faga295,他在 Rspack 中支持了压缩代码注释功能和 rspack 预览功能。
  • @lippzhang,他在使 Rspack 的行为与 Webpack 保持一致方面做出了很多贡献。
  • @HerringtonDarkholme,他允许 Rspack 使用 rspack.config.ts 作为配置文件。
  • @dhruvkelawala,他在 Rspack 中实现了 builtins.provide 功能。
  • @magic-akari,他在 Rspack 中支持了 new URL("./foo", import.meta.url) 语法。
  • @tuchg,他在 Rspack 中支持了 .wasm 文件的打包。

我们还要感谢所有 Rspack 的用户,感谢你们对这样一个年轻的开源项目的信任。你们的宝贵反馈是我们项目改进和优化的关键。你们的支持和信任是我们前进的动力。

最后,让我们共同庆祝 Rspack 0.2 的发布,并期待未来的发展和更多合作机会。再次感谢所有支持和关注 Rspack 的朋友们!