介绍
Rspack是一个基于 Rust 的高性能打包工具,由字节跳动 Web Infra 开源,可以被 Webpack 项目低成本集成,并提供 5~10 倍编译性能提升。
- GitHub 地址:web-infra-dev/rspack(欢迎 Star ⭐)
Rspack v0.6.0 版本现已发布!
- ⭐️ 新版 Tree Shaking 算法 -> 更小的产物体积
- ⭐️ 新增 CSS extract 插件,对齐 mini-css-extract-plugin
- ⭐️ 新增 CSS modules 选项,对齐 webpack
- ⭐️ 升级 SWC v0.90
主要功能更新
默认开启新版 Tree Shaking
Rspack 在早期支持了基本的 tree shaking 功能,由于最初的架构还未稳定, 我们使用了相对简单的方法,实现了基础版的 tree shaking(仅支持未使用导出删除)。
但是随着 Rspack 功能的完善,架构逐渐稳定,基础的 tree shaking 无法满足复杂的需求,比如:
-
无法处理循环引用,无法给其他构建阶段足够的优化信息,实现进一步的优化 (mangleExports, concatenateModules, barrel exports optimization)。
-
经常出现一些 interop 相关的 badcase,例如: worker-thread 模块,Common Js 模块,module federation 等。
为了解决以上问题,我们决定使用类似 webpack 的方案,自底向上重新实现整个优化流程,并在 0.4.2 引入 experiments.rspackFuture.newTreeshaking
配置,来实验性的开启新的优化算法。 经过 4 个月 bug 修复和优化,新的 tree shaking 算法已经相对稳定,我们决定在 v0.6 默认开启新的 tree shaking 算法。
新版算法支持了 reexports optimization(重导出优化),能够更精确地移除未使用的模块,这张图演示了重导出优化的过程:
以 import { Button } from 'antd'
为例,新版算法使产物体积从 159kB 下降到 129kB,提升约 20%。
更多细节请参考 Rspack - tree shaking 文档。
内置支持 mini-css-extract-plugin
你现在可以使用 rspack.CssExtractRspackPlugin
作为 mini-css-extract-plugin
的替代。
这在一些复杂场景很实用,例如当内置的 CSS 处理无法满足你的需求、需要更定制化的 CSS module 选项等,或者你想要使用一些依赖 css-loader 的 loaders,但仍然想要将 CSS 提取成单独文件时。
详细配置见 CssExtractRspackPlugin。
js
const rspack = require('@rspack/core');
module.exports = {
plugins: [new rspack.CssExtractRspackPlugin()],
module: {
rules: [
{
test: /\.css$/i,
use: [rspack.CssExtractRspackPlugin.loader, 'css-loader'],
},
],
},
};
你可以在这里找到一个基础的项目例子。
不兼容更新
移除 experiments.rspackFuture.disableApplyEntryLazily
experiments.rspackFuture.disableApplyEntryLazily
选项自 v0.5.0 已被默认开启,并在 v0.6.0 中被删除。
移除 compiler.build 和 compiler.rebuild
compiler.build
与 compiler.rebuild
不属于 Webpack 公开 API,目前已经被移除。
移除 builtins.css 并引入 CSS 相关 module.parser 和 module.generator 选项
移除 builtins.css
,请使用引入的 CSS 相关的 module.parser
和 module.generator
选项进行替代。
同时,从 v0.6.0 版本开始,Rspack 的 experiments css 将会以 webpack 的 experiments css 为目标进行对齐,这意味着和 webpack experiments css 一样在未来将不再支持不支持 CSS 变量的浏览器。因此,对于那些需要使用尚未得到 experiments css 支持的配置,或者需要兼容老版本浏览器的项目,我们推荐迁移至 rspack.CssExtractRspackPlugin
。
在 v0.6.0 中,我们引入了三种新的模块类型的 module.generator
和 module.parser
选项:css/auto
、css
和 css/module
,这些选项只有在启用 experiments.css 时才会生效,关于如何使用可查看这个例子。
在 module.parser
选项中,css
、css/auto
和 css/module
模块类型都包含了 namedExports
属性。它取代了 builtins.css.namedExports
配置。
对于 module.generator
选项,css/auto
和 css/module
模块类型提供了 exportsOnly
、exportsConvention
和 localIdentName
属性。css
类型只包含 exportsOnly
和 exportsConvention
属性。exportsOnly
、exportsConvention
和 localIdentName
分别取代了 builtins.css.modules.exportsOnly
、builtins.css.modules.localsConvention
和 builtins.css.modules.localIdentName
。
除此之外,还包括一些关于默认值的修改:
-
exportsConvention
的值从'asIs'
,'camelCaseOnly'
等变更为'as-is'
,'camel-case-only'
等,以保持与 webpack experiments css 的一致。 -
namedExports: false
支持同时使用默认导出(default export)、命名导出(named export)和命名空间导出(namespace export),在此之前它只支持使用默认导出:js// v0.6.0 之前只支持使用默认导出 import classes from './index.module.css'; // 现在除默认导出之外,也支持: // 命名空间导出 import * as classes from './index.module.css'; // 命名导出 import { class1, class2 } from './index.module.css'; // 默认导出和命名导出同时使用 import classes, { class1, class2 } from './index.module.css';
-
namedExports
的默认值从false
变更为true
,这意味着你需要默认使用命名空间导入(例如import * as classes from './style.css'
)或命名导入(例如import { class1 } from './style.css'
),这将提高与未来原生 CSS 模块的兼容性。而这并不意味着你需要一次性迁移所有的导入,你可以通过设置namedExports: false
来禁用此行为,并且由于现在namedExports: false
也支持命名导出和命名空间导出,因此你可以逐步迁移这些导入。 -
localIdentName
的默认值在从在开发模式下'[path][name][ext]__[local]'
和在生产模式下'[hash]'
变更为在开发和生产模式下都是'[uniqueName]-[id]-[local]'
,这将略微改善 CSS 产物的 gzip 压缩大小。 -
exportsOnly
的默认值在target: 'node'
下由原来的false
变更为true
。 -
CSS 默认规则的模块类型从
css
变更为css/auto
,css/auto
将自动解析以.module.
或.modules.
为中缀的 CSS 文件作为 CSS Modules 处理,这与css-loader
的modules.auto: true
行为一致,这将简化使用 less 或 sass 与 CSS Modules 的规则书写。
升级 SWC 到 0.90.x
升级 Rust crate swc_core
到 0.90.x
,这会对使用 SWC Wasm 插件的用户产生影响。
当 CSS 的顺序在多个 chunk 中不一致时发出警告
当多个 chunk 中 css 顺序不一致时会发出警告,假如你有两个 entry,entryA 和 entryB,entryA 中引入 a.css 然后引入 b.css,而 entryB 中引入 b.css 然后引入 a.css。 当满足 splitChunks 条件时,a.css 和 b.css 会成为单独 chunk,这个 chunk 中 a.css 和 b.css 的顺序无法保证,会产生如下的警告
txt
WARNING in ⚠ chunk src_a_css-src_b_-5c8c53 [css-extract-rspack-plugin]
│ Conflicting order. Following module has been added:
│ * css ./css-loader/dist/cjs.js??ruleSet[1].rules[2].use[1]!./src/a.css
│ despite it was not able to fulfill desired ordering with these modules:
│ * css ./css-loader/dist/cjs.js??ruleSet[1].rules[2].use[1]!./src/b.css
│ - couldn't fulfill desired order of chunk group(s) parent2
│ - while fulfilling desired order of chunk group(s) parent1
如果你确定他们的顺序不一致没有关系,可以通过配置 ignoreWarnings
来忽略这种错误。
js
module.exports = {
ignoreWarnings: [/Conflicting order/],
};
迁移指南
使用 rspack.CssExtractRspackPlugin
如果你曾经使用 Webpack 和 mini-css-extract-plugin
,只需要将 mini-css-extract-plugin
换成 rspack.CssExtractPlugin
即可。
diff
+ const CssExtract = require('@rspack/core').CssExtractRspackPlugin;
- const CssExtract = require('mini-css-extract-plugin');
module.exports = {
plugins: [new CssExtract()],
module: {
rules: [
{
test: /\.css$/i,
use: [CssExtract.loader, 'css-loader'],
},
],
},
};
迁移 builtins.css 配置
- 使用
module.parser["css/auto"].namedExports
替代builtins.css.namedExports
。 - 使用
module.generator["css/auto"].exportsOnly
替代builtins.css.modules.exportsOnly
。 - 使用
module.generator["css/auto"].exportsConvention
替代builtins.css.modules.localsConvention
。 - 使用
module.generator["css/auto"].localIdentName
替代builtins.css.modules.localIdentName
。
以上出现的 "css/auto"
为 CSS 默认的模块类型,可根据需要修改为 "css"
或 "css/module"
。
添加以下配置将保持原有 builtins.css
默认行为,可根据以下配置根据需要进行修改:
diff
module.exports = {
// ...
+ module: {
+ generator: {
+ "css/auto": {
+ exportsOnly: false,
+ exportsConvention: 'as-is',
+ localIdentName: isProduction ? '[hash]' : '[path][name][ext]__[local]',
+ },
+ "css": {
+ exportsOnly: false,
+ exportsConvention: 'as-is',
+ },
+ "css/module": {
+ exportsOnly: false,
+ exportsConvention: 'as-is',
+ localIdentName: isProduction ? '[hash]' : '[path][name][ext]__[local]',
+ },
+ },
+ parser: {
+ "css/auto": {
+ namedExport: false,
+ },
+ "css": {
+ namedExport: false,
+ },
+ "css/module": {
+ namedExport: false,
+ },
+ },
+ },
}
如需要对部分模块进行配置,可使用 module.rules
中的 rule.parser
和 rule.generator
选项进行配置。
调用 compiler.run 执行构建
compiler.build
或 compiler.rebuild
已经被废弃,请切换到 compiler.run
进行构建,与重新构建。
升级 SWC 插件
在 0.6.0
中,Rust crate swc_core
的版本升级到 0.90.x
,使用到的 swc wasm 插件需要确保其使用的 swc_core
的版本一致性,否则可能产生无法预知的问题。
详情请参考文档。