迁移 webpack
Rspack 的配置是基于 webpack 的设计实现的,以此你能够非常轻松地将项目从 webpack 迁移至 Rspack。
文档主要针对使用 webpack 5 的项目,因为目前 Rspack 的配置是基于 webpack 5 的设计实现的。如果你的项目使用的不是 webpack 5,可以参考以下迁移指南:
安装 Rspack
在你的项目目录下安装 Rspack:
npm add @rspack/core @rspack/cli @rspack/dev-server -D
yarn add @rspack/core @rspack/cli @rspack/dev-server -D
pnpm add @rspack/core @rspack/cli @rspack/dev-server -D
bun add @rspack/core @rspack/cli @rspack/dev-server -D
deno add npm:@rspack/core npm:@rspack/cli npm:@rspack/dev-server -D
其中 @rspack/cli 和 @rspack/dev-server 为可选依赖:
- 未使用
webpack-cli 时,不需要安装 @rspack/cli
- 未使用
webpack-dev-server 时,不需要安装 @rspack/dev-server
现在你可以移除项目中 webpack 相关的依赖了:
npm remove webpack webpack-cli webpack-dev-server
yarn remove webpack webpack-cli webpack-dev-server
pnpm remove webpack webpack-cli webpack-dev-server
bun remove webpack webpack-cli webpack-dev-server
deno remove npm:webpack npm:webpack-cli npm:webpack-dev-server
修改 package.json
更新构建脚本以使用 Rspack 代替 webpack,查看 CLI 了解更多。
package.json
{
"scripts": {
- "dev": "webpack serve",
- "build": "webpack build",
+ "dev": "rspack dev",
+ "build": "rspack build",
+ "preview": "rspack preview",
}
}
修改配置
将 webpack.config.js 文件重命名为 rspack.config.js。
提示
Rspack 命令与 webpack 命令相同,均可通过 -c 或 --config 指定配置文件。但与 webpack 不同的是,如果你未显式指定配置文件,Rspack 默认使用 rspack.config.js。
Rspack 兼容 webpack 的绝大部分配置项,查阅 配置 Rspack 来了解 Rspack 支持的所有配置。
缓存配置
webpack 和 Rspack 的缓存配置结构并不完全相同。迁移时不建议直接复制 webpack 的 cache 配置,而应根据 Rspack 的 cache 配置 做对应调整。
对于禁用缓存和内存缓存的场景,可以保留原有写法:cache: false、cache: true 和 cache: { type: 'memory' } 在 Rspack 中含义一致。
如果 webpack 使用文件系统缓存,应迁移为 Rspack 持久化缓存,并按下面的字段映射进行调整。
- 将 webpack 的
cache.type: 'filesystem' 改为 Rspack 的 cache.type: 'persistent'。
rspack.config.mjs
export default {
- cache: {
- type: 'filesystem',
- },
+ cache: {
+ type: 'persistent',
+ },
};
- 将 webpack 的
cache.buildDependencies 展平为 Rspack cache.buildDependencies 所需的文件路径数组。
rspack.config.mjs
export default {
- cache: {
- buildDependencies: {
- config: [__filename, path.join(__dirname, 'package.json')],
- ts: [path.join(__dirname, 'tsconfig.json')]
- }
- },
+ cache: {
+ type: 'persistent',
+ buildDependencies: [
+ __filename,
+ path.join(__dirname, 'package.json'),
+ path.join(__dirname, 'tsconfig.json')
+ ]
+ },
};
- 将 webpack 的
cache.name 和 cache.version 合并到 Rspack cache.version。
Rspack 没有单独的 cache.name 配置。缓存实例会通过 cache.version 和 cache.storage.directory 隔离。
rspack.config.mjs
export default {
- cache: {
- name: `${config.name}-${config.mode}-${otherFlags}`,
- version: appVersion
- },
+ cache: {
+ type: 'persistent',
+ version: `${config.name}-${config.mode}-${otherFlags}-${appVersion}`
+ },
};
- 将 webpack 顶层的
snapshot 配置移动到 Rspack cache.snapshot。
rspack.config.mjs
export default {
- snapshot: {
- immutablePaths: [path.join(__dirname, 'constant')],
- managedPaths: [path.join(__dirname, 'node_modules')],
- unmanagedPaths: []
- },
+ cache: {
+ type: 'persistent',
+ snapshot: {
+ immutablePaths: [path.join(__dirname, 'constant')],
+ managedPaths: [path.join(__dirname, 'node_modules')],
+ unmanagedPaths: []
+ }
+ },
};
- 将 webpack 的
cache.cacheDirectory 移动到 Rspack cache.storage.directory。
rspack.config.mjs
export default {
- cache: {
- cacheDirectory: path.join(__dirname, 'node_modules/.cache/test')
- },
+ cache: {
+ type: 'persistent',
+ storage: {
+ type: 'filesystem',
+ directory: path.join(__dirname, 'node_modules/.cache/test')
+ }
+ },
};
下面是自动转换配置时对应的完整映射示例:
function transform(webpackConfig, rspackConfig) {
if (webpackConfig.cache === undefined) {
webpackConfig.cache = webpackConfig.mode === 'development';
}
if (!webpackConfig.cache) {
rspackConfig.cache = false;
return;
}
if (webpackConfig.cache === true || webpackConfig.cache.type === 'memory') {
rspackConfig.cache = true;
return;
}
rspackConfig.cache = { type: 'persistent' };
rspackConfig.cache.buildDependencies = Object.values(
webpackConfig.cache.buildDependencies || {},
).flat();
const version = [webpackConfig.cache.name, webpackConfig.cache.version]
.filter(Boolean)
.join('-');
if (version) {
rspackConfig.cache.version = version;
}
rspackConfig.cache.snapshot = {
immutablePaths: webpackConfig.snapshot?.immutablePaths,
managedPaths: webpackConfig.snapshot?.managedPaths,
unmanagedPaths: webpackConfig.snapshot?.unmanagedPaths,
};
if (webpackConfig.cache.cacheDirectory) {
rspackConfig.cache.storage = {
type: 'filesystem',
directory: webpackConfig.cache.cacheDirectory,
};
}
}
webpack 内置插件
Rspack 实现了大部分 webpack 内置插件,其命名和参数配置与 webpack 保持一致,你可以非常轻松地替换它们。
例如替换 DefinePlugin:
rspack.config.js
const webpack = require('webpack');
const { rspack } = require('@rspack/core');
module.exports = {
//...
plugins: [
new webpack.DefinePlugin({
new rspack.DefinePlugin({
// ...
}),
],
}
查看 内置插件 以了解 Rspack 对 webpack 所有内置插件的支持情况。
社区插件
Rspack 支持大部分 webpack 社区插件,并为暂不支持的插件提供了替代方案。
查看 Plugin 兼容 以了解 Rspack 对 webpack 常见社区插件的兼容情况。
copy-webpack-plugin
使用 rspack.CopyRspackPlugin 代替 copy-webpack-plugin:
rspack.config.js
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { rspack } = require('@rspack/core');
module.exports = {
plugins: [
new CopyWebpackPlugin({
new rspack.CopyRspackPlugin({
// ...
}),
]
}
使用 rspack.CssExtractRspackPlugin 代替 mini-css-extract-plugin:
rspack.config.js
- const CssExtractWebpackPlugin = require('mini-css-extract-plugin');
+ const { rspack } = require('@rspack/core');
module.exports = {
plugins: [
- new CssExtractWebpackPlugin({
+ new rspack.CssExtractRspackPlugin({
// ...
}),
]
module: {
rules: [
{
test: /\.css$/i,
use: [
- CssExtractWebpackPlugin.loader,
+ rspack.CssExtractRspackPlugin.loader,
"css-loader"
],
}
]
}
}
tsconfig-paths-webpack-plugin
使用 resolve.tsConfig 选项代替 tsconfig-paths-webpack-plugin:
rspack.config.js
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
module.exports = {
resolve: {
plugins: [new TsconfigPathsPlugin({})],
tsConfig: {},
},
};
fork-ts-checker-webpack-plugin
使用 ts-checker-rspack-plugin 代替 fork-ts-checker-webpack-plugin:
rspack.config.js
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const { TsCheckerRspackPlugin } = require('ts-checker-rspack-plugin');
module.exports = {
plugins: [
new ForkTsCheckerWebpackPlugin(),
new TsCheckerRspackPlugin(),
],
};
terser-webpack-plugin
对于使用 terser-webpack-plugin 压缩 JavaScript 的项目,建议改用 rspack.SwcJsMinimizerRspackPlugin 以获得更好的构建性能:
rspack.config.js
const TerserPlugin = require('terser-webpack-plugin');
const { rspack } = require('@rspack/core');
module.exports = {
optimization: {
minimizer: [
new TerserPlugin(),
new rspack.SwcJsMinimizerRspackPlugin(),
new rspack.LightningCssMinimizerRspackPlugin(),
],
},
};
css-minimizer-webpack-plugin
对于使用 css-minimizer-webpack-plugin 压缩 CSS 的项目,建议改用 rspack.LightningCssMinimizerRspackPlugin 以获得更好的构建性能:
rspack.config.js
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const { rspack } = require('@rspack/core');
module.exports = {
optimization: {
minimizer: [
new rspack.SwcJsMinimizerRspackPlugin(),
new CssMinimizerPlugin(),
new rspack.LightningCssMinimizerRspackPlugin(),
],
},
};
Loaders
Rspack 与绝大多数 webpack loader 保持兼容,因此通常可以直接复用现有的 loader 生态,无需额外改造。
不过,为了获得更优的构建性能与更稳定的行为,我们仍然建议按照下面的方式进行适当迁移:
babel-loader
将 babel-loader 迁移为 builtin:swc-loader,以使用 Rspack 内置的 SWC 转换能力并获得更高性能。
如果你需要通过 babel 插件进行自定义转换逻辑,可以保留 babel-loader,但不建议对大量文件使用 babel-loader,因为这会导致显著的性能下降。
rspack.config.js
module.exports = {
module: {
rules: [
{
- test: /\.(j|t)sx?$/,
+ test: /\.(?:js|mjs|jsx|ts|tsx)$/,
exclude: [/[\\/]node_modules[\\/]/],
use: [
{
- loader: 'babel-loader',
+ loader: 'builtin:swc-loader',
+ options: {
+ detectSyntax: 'auto',
+ },
},
],
},
],
},
};
rspack.config.js
+const isDev = process.env.NODE_ENV === 'development';
module.exports = {
module: {
rules: [
{
test: /\.(?:js|mjs|jsx|ts|tsx)$/,
exclude: [/[\\/]node_modules[\\/]/],
use: [
{
- loader: 'babel-loader',
+ loader: 'builtin:swc-loader',
options: {
- presets: ['@babel/preset-typescript', '@babel/preset-react'],
+ jsc: {
+ transform: {
+ react: {
+ runtime: 'automatic',
+ development: isDev,
+ refresh: isDev,
+ },
+ },
+ },
+ detectSyntax: 'auto',
},
},
],
},
],
},
};
swc-loader
将外置 swc-loader 迁移为 builtin:swc-loader 时,除了 loader 名称改为 builtin:swc-loader 外,其余选项与原 swc-loader 完全一致。
rspack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(j|t)sx?$/,
use: [
{
loader: 'swc-loader',
loader: 'builtin:swc-loader',
},
],
},
],
},
};
file-loader
将 file-loader 迁移为 资源模块 的 asset/resource 类型。
rspack.config.js
module.exports = {
module: {
rules: [
- {
- test: /\.(png|jpe?g|gif)$/i,
- use: ["file-loader"],
- },
+ {
+ test: /\.(png|jpe?g|gif)$/i,
+ type: "asset/resource",
+ },
],
},
};
url-loader
将 url-loader 迁移为 资源模块 的 asset/inline 类型。
rspack.config.js
module.exports = {
module: {
rules: [
- {
- test: /\.(png|jpe?g|gif)$/i,
- use: ["url-loader"],
- },
+ {
+ test: /\.(png|jpe?g|gif)$/i,
+ type: "asset/inline",
+ },
],
},
};
raw-loader
将 raw-loader 迁移为 资源模块 的 asset/source 类型。
rspack.config.js
module.exports = {
module: {
rules: [
- {
- test: /^BUILD_ID$/,
- use: ["raw-loader",],
- },
+ {
+ test: /^BUILD_ID$/,
+ type: "asset/source",
+ },
],
},
};
常见 webpack 库替换
迁移 webpack 生态中的配套库时,下面这些非插件类包通常需要替换:
对于插件类包,请查看 Plugin 兼容。