Rspack 0.2 发布公告

2023 年 6 月 2 日

自 Rspack 0.1 版本发布的将近三个月以来,我们得到了非常多社区的关注和反馈,感谢大家对 Rspack 的支持。在 0.2 版本中,我们新增了诸多功能,如 realContentHash、DataURI、ESM format 的支持等,同时加强了与 Webpack 的兼容性,并优化了诸多细节。

另外,得益于对 Webpack API 良好的兼容性,我们对于周边生态也完成了进一步的兼容,例如,测试完成了对 vue-loader 17(对应 Vue3)和 15(对应 Vue2)版本的兼容,现在大家可以尝试在 Vue2 / 3 项目中使用 Rspack 了。我们期待您在 0.2 版本中体验到这些全新的改进,并欢迎您随时给我们提供反馈。

主要功能更新

Loader

0.2 版本完成了 loader 大部分 API 的兼容,其中包括了 inline match resource,pitching loader,inline loader 等。更多的 API 进一步提升了对 Webpack loader 的兼容性,详情可以参考下方 webpack 兼容性更新。更多信息请参考 Loader API

Plugin Hooks

新增一些插件的的钩子

Compiler hooks

  1. beforeCompile
  2. afterCompile

Compilation hooks

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

NormalModuleFactory hooks

  1. beforeResolve
  2. afterResolve
  3. ResolveForScheme

ContextModuleFactory hooks

  1. beforeResolve

realContentHash

我们实现了 optimization.realContentHash,它会根据最终产物的文件内容进行 Hash 的计算,因此它所生成的 Hash 更为稳定,对缓存有更好的利用率,在 0.2 版本中,对于生产环境的构建会默认开启这一功能。

ESM/System format

在新版本中,支持了生成 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 这两种 module rule condition,比如,你可以通过以下方式让 scheme'data' 的资源不再当作内联处理,而是作为单独的资源文件

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

Breaking Changes

  • 文件名生成逻辑对齐

    在 0.1.12 版本我们为了进一步对齐 webpack 的文件名生成逻辑,重构了文件名生成的实现,但导致 [ext] 在 output.filenameoutput.chunkFilenameoutput.cssFilenameoutput.cssChunkFilename 中的 [ext] 不会再被替换,这一行为现在和 webpack 保持一致,但对于 Rspack 0.1.12 之前的版本造成了 breaking change,如果你在以上 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 的 extensions

    详情: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,我们也兼容了更多的社区的 Plugin 和 Loader。我们适配了一些社区呼声较高的 Plugin 和 Loader。

fork-ts-checker-webpack-plugin

在 Rspack 里进行 TypeScript 的类型检查是一个广泛的需求,Rspack 已经完全适配了 fork-ts-checker-webpack-plugin,你可以通过该插件在编译时进行 TypeScript 的类型检查,值得注意的是因为 TypeScript 的类型检查通常十分耗时,这使得在较大的项目上类型检查的耗时可能远超过 Rspack 本身的构建耗时。在 dev 模式下,该插件并不会阻塞构建,但是在 build 模式下该插件会阻塞构建,请根据你的实际需求选择是否启用该插件。

license-webpack-plugin

一个广泛反馈的社区需求就是支持提取代码里的 license,Rspack 现在可以通过 license-webpack-plugin 实现提取代码里的 license 需求。

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 应用时,一个常见的需求就是打包一些包含 addon 的库,这些库里的 native 依赖无法直接被打包进 JS 里,因此需要特殊处理,Rspack 适配了 node-loader 所以你可以使用 Rspack 去构建 node 应用了。 Rspack 适配的 webpack 的 plugin 和 loader 远不仅此,我们在 loader-compatplugin-compat 对已经适配的 plugin 和 loader 进行了追踪,如果你发现你使用的社区 plugin 和 loader 也已经兼容,欢迎提交给我们。

框架生态更新

Modern.js 框架

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

在字节跳动内部,已有 80+ 个业务项目在使用 Modern.js Rspack 模式。其中一部分项目已经上线至生产环境,获得 10 倍左右的构建性能提升。

Modern.js Doc

除了 Modern.js 框架,Modern.js 体系下的文档站开发方案 —— Modern.js Doc 也将构建工具从 webpack 切换到了 Rspack,并将 MDX 编译流程基于 Rust 重写。

相较于早期使用 webpack 的版本,当前版本的文档构建速度可以缩短至秒级。以 Modern.js 官网文档为例,项目的启动和构建时间从 30s 缩短到 2s 以内。未来,我们计划将 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 支持的更多信息请参考 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

在 Rosa、Nx 和 Valor 的帮助下,Rspack 完成了对 NestJS 的编译支持,你可以使用 Rspack 打包 NestJS 应用,在实际项目中进行测试,Rspack 相比 Webpack 版本有 5-10 倍的构建性能提升。

Benchmark

添加与 esbuild 对比的 benchmark https://github.com/web-infra-dev/performance-compare

benchmark

开发指南

Rspack 团队非常重视开源社区做出的宝贵贡献。我们致力于保持开放的态度,努力在每一步都让开源社区参与进来。 这就是为什么我们目前正在制作一份全面的开发指南,为贡献者提供 Rspack 所有的开发文档。 当前版本的指南包含构建、测试、调试和分析 Rspack 的所有必要资料。此外,它还包括贡献流程,例如如何创建最小的可重现示例。 将来,该指南还会概述 Rspack 的整体架构,使贡献者能够深入了解该项目的内部工作原理。

测试架构

针对稳定发布,我们目前:

  • 在 Rspack 仓库中集成各种示例(目前有 38 个示例)
  • 正在从 Webpack 仓库移植所有的 Webpack 集成测试
  • 在 Node.js 版本 14、16 和 18 上运行所有测试
  • 搭建了独立的 ecosystem-ci 仓库用于集成社区的上层框架

Nightly Release

为了加速迭代,Rspack 每天发布一次带有“@nightly” 标签的 npm 包。

致谢

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

特别感谢

  • @TheLarkInn@alexander-akait ,回答和解决了很多 Rspack 团队关于 Webpack 的疑问。
  • @zackarychapple@valorkin@edusperoni 以及 @Coly101 ,帮助 Rspack 对 Angular 做了基本支持,特别是 @zackarychapple 帮助我们 review 这篇发布公告的英文版本。
  • @suxin2017,在 Rspack 里支持了 System.js format,optional-dependency 等功能,并在 Windows 兼容方面做了很多贡献。
  • @faga295,在 Rspack 里支持了解压代码注释功能和 rspack preview 功能。
  • @lippzhang,在对齐 Webpack 行为方面做了很多贡献。
  • @HerringtonDarkholme,允许 Rspack 使用 rspack.config.ts 作为配置文件
  • @dhruvkelawala, 在 Rspack 里实现了 builtins.provide 功能
  • @magic-akari,在 Rspack 里支持了 new URL("./foo", import.meta.url) 语法
  • @tuchg,在 Rspack 里支持了打包 .wasm 文件

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

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