迁移 Webpack
本章节介绍如何将使用 webpack 的项目迁移到 Rspack。
当前文档主要面向使用 webpack v5 的项目。因为 Rspack 的 API 和配置是对齐 webpack v5 实现的,从 webpack v5 迁移到 Rspack 会相对容易。
对于非 webpack v5 的项目,有一些其他迁移指南可以参考:
注意事项
- Rspack 支持的 Node.js 版本为 >= 16,如果你还在使用旧版本的 Node.js,请先升级版本。
- Rspack 尽可能地兼容了 webpack 的常用 API 和配置,但是不可避免地存在一些不同,你可以阅读 Rspack 的文档来了解每个 API 和配置的差异。
- 一部分功能在 Rspack 中有性能更好的实现方式,如果你采用 Rspack 推荐的方式,会获得更显著的性能提升。
安装依赖
首先你需要把 webpack 相关的 npm 依赖替换为 Rspack 的依赖。
npm remove webpack webpack-cli webpack-dev-server
npm add @rspack/core @rspack/cli -D
以下是一些常见 npm 包的映射关系:
webpack
-> @rspack/core
webpack-cli
-> @rspack/cli
webpack-dev-server
-> @rspack/dev-server
@pmmmwh/react-refresh-webpack-plugin
-> @rspack/plugin-react-refresh
更新 npm scripts
下一步,你需要把 package.json 中的 npm scripts 更新为 Rspack 的 CLI 命令。
package.json
{
"scripts": {
- "serve": "webpack serve -c webpack.config.js",
- "build": "webpack build -c webpack.config.js",
+ "serve": "rspack serve -c rspack.config.js",
+ "build": "rspack build -c rspack.config.js",
}
}
配置文件
请将 webpack.config.js
文件重命名为 rspack.config.js
。
Rspack 提供了与 webpack 相似的配置项,你可以参考 配置 Rspack 了解 Rspack 支持的配置。
内置插件
Rspack 实现了大部分 webpack 内置插件,它们尽可能地保持了相同的命名和参数配置,并提供相同的功能。
比如替换 HotModuleReplacementPlugin,原有配置如下:
webpack.config.js
const webpack = require('webpack');
const isDev = process.env.NODE_ENV === 'development';
module.exports = {
plugins: [isDev && new webpack.HotModuleReplacementPlugin()].filter(Boolean),
};
在 Rspack 中可以替换为:
rspack.config.js
const rspack = require('@rspack/core');
const isDev = process.env.NODE_ENV === 'development';
module.exports = {
plugins: [isDev && new rspack.HotModuleReplacementPlugin()].filter(Boolean),
};
你可以参考 同步自 webpack 的内置插件 来了解 Rspack 支持哪些 webpack 内置插件。
社区插件
Rspack 支持大部分的 webpack 社区插件,同时也对一部分暂不支持的插件提供了替代方案。
你可以参考 Plugin 兼容 来了解 Rspack 对一些常见的社区插件的兼容状态。
处理 Loader
Rspack 支持大部分的 webpack loaders。下面列出了几个迁移 loader 的例子,参考这些例子进行替换,你可以获得更显著的性能提升。
使用 builtin:swc-loader 替代 babel-loader
Rspack 使用 builtin:swc-loader 对 TypeScript、JSX 以及最新的 JavaScript 语法进行转换,这意味着,如果你的 babel-loader 只是为了支持 TypeScript、JSX 以及更新的 JavaScript 语法,那么完全可以使用 builtin:swc-loader 替代 babel-loader。
如果你的 babel-loader 是为了支持自定义的转换逻辑,那么这部分的 babel-loader 可以保留,但是我们不鼓励用户对大量的文件使用 babel-loader,因为这会导致严重的性能劣化。
module.exports = {
module: {
rules: [
- {
- test: /\.tsx?$/i,
- use: [
- {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-typescript'],
- },
- },
- ],
- test: /\.jsx?$/i,
- use: [
- {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-react'],
- },
- },
- ],
- },
+ {
+ test: /\.(j|t)s$/,
+ exclude: [/[\\/]node_modules[\\/]/],
+ loader: 'builtin:swc-loader',
+ options: {
+ jsc: {
+ parser: {
+ syntax: 'typescript',
+ },
+ externalHelpers: true,
+ transform: {
+ react: {
+ runtime: 'automatic',
+ development: !prod,
+ refresh: !prod,
+ },
+ },
+ },
+ env: {
+ targets: 'Chrome >= 48',
+ },
+ },
+ },
+ {
+ test: /\.(j|t)sx$/,
+ loader: 'builtin:swc-loader',
+ exclude: [/[\\/]node_modules[\\/]/],
+ options: {
+ jsc: {
+ parser: {
+ syntax: 'typescript',
+ tsx: true,
+ },
+ transform: {
+ react: {
+ runtime: 'automatic',
+ development: !prod,
+ refresh: !prod,
+ },
+ },
+ externalHelpers: true,
+ },
+ env: {
+ targets: 'Chrome >= 48', // browser compatibility
+ },
+ },
+ },
],
},
};
Rspack 内置支持了 CSS 模块类型 ,原生 CSS 模块类型内置了对 CSS、CSS HMR、CSS Modules 以及 CSS 提取功能的支持,这意味着你不需要再为 CSS 文件单独配置 css-loader、style-loader 和 mini-css-extract-plugin。
-const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
module: {
rules: [
- {
- test: /\.css$/i,
- use: [
- isDev ? "style-loader" : MiniCssExtractPlugin.loader,
- "css-loader",
- ],
- },
+ {
+ test: /\.css$/i,
+ type: "css", // this is enabled by default for .css, so you don't need to specify it
+ },
],
},
plugins: [],
};
对于 css-modules 的功能,通过指明 css/module 作为模块类型即可开启。
module.exports = {
module: {
rules: [
+ {
+ test: /\.module\.css$/i,
+ type: "css/module", // this is enabled by default for module.css, so you don't need to specify it
+ },
],
},
};
如果依赖 css-loader,例如 css-loader 提供的一些更加定制化的配置项,仍然可以使用 style-loader + css-loader 方案,如果你想要在生产环境将 CSS 提取成单独的文件,可以使用 Rspack 内置的 CssExtractRspackPlugin 插件。
CssExtractRspackPlugin 插件功能和配置与 mini-css-extract-plugin 类似,使用前请确保开启了 experiments.rspackFuture.newTreeshaking
,v0.6 之后的版本默认开启。
+ const { CssExtractRspackPlugin } = require("@rspack/core");
- const CssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
+ new CssExtractRspackPlugin(),
- new CssExtractPlugin(),
]
module: {
rules: [
{
test: /\.css$/i,
use: [
+ CssExtractRspackPlugin.loader,
- CssExtractPlugin.loader,
"css-loader"
]
}
]
}
}
使用 Asset Modules 来代替 file-loader、url-loader 和 raw-loader
Rspack 对齐 webpack 5 的 Asset Modules,这意味着你可以使用 Asset Modules 来代替 file-loader 和 url-loader。
module.exports = {
module: {
rules: [
+ {
+ test: /\.(png|jpe?g|gif)$/i,
+ type: "asset/resource",
+ },
+ {
+ test: /^BUILD_ID$/,
+ type: "asset/source",
+ },
- {
- test: /\.(png|jpe?g|gif)$/i,
- use: ["file-loader"],
- },
- {
- test: /^BUILD_ID$/,
- use: ["raw-loader",],
- },
],
},
};