Migrate webpack

This chapter introduces how to migrate projects using webpack to Rspack.

This document is primarily aimed at projects using webpack v5. Since Rspack's API and configuration align with webpack v5, migrating from webpack v5 to Rspack will be relatively easy.

For projects not using webpack v5, there are other migration guides that can be referenced:

Notes

  • The supported Node.js version for Rspack is >= 16. If you are still using an older version of Node.js, please upgrade first.
  • Rspack is designed to be as compatible as possible with common webpack APIs and configurations, but some differences are inevitable. You can read Rspack's documentation to understand the differences in each API and configuration.
  • Some functionalities in Rspack have more efficient implementations. If you adopt the recommended practices of Rspack, you will achieve more significant performance improvements.

Install Dependencies

First, you need to replace the webpack-related npm dependencies with those of Rspack.

  • Remove the webpack dependencies:
npm
yarn
pnpm
bun
npm remove webpack webpack-cli webpack-dev-server
  • Install the Rspack dependencies:
npm
yarn
pnpm
bun
npm add @rspack/core @rspack/cli -D

Here are the mapping relationships for some common npm packages:

  • webpack -> @rspack/core
  • webpack-cli -> @rspack/cli
  • webpack-dev-server -> @rspack/dev-server
  • @pmmmwh/react-refresh-webpack-plugin -> @rspack/plugin-react-refresh

Update npm scripts

Next, you need to update the npm scripts in the package.json file to Rspack's CLI commands.

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",
  }
}

Configuration File

Please rename the webpack.config.js file to rspack.config.js.

Rspack offers configurations similar to webpack. You can refer to Configure Rspack to see the configurations supported by Rspack.

Built-in Plugins

Rspack has implemented most of webpack's built-in plugins. They maintain the same naming and configuration parameters as closely as possible and provide the same features.

For example, replacing HotModuleReplacementPlugin with the original configuration would look like this:

webpack.config.js
const webpack = require('webpack');

const isDev = process.env.NODE_ENV === 'development';

module.exports = {
  plugins: [isDev && new webpack.HotModuleReplacementPlugin()].filter(Boolean),
};

In Rspack, it can be replaced with:

rspack.config.js
const rspack = require('@rspack/core');

const isDev = process.env.NODE_ENV === 'development';

module.exports = {
  plugins: [isDev && new rspack.HotModuleReplacementPlugin()].filter(Boolean),
};

You can refer to webpack aligned built-in plugins to understand which webpack built-in plugins are supported by Rspack.

Community Plugins

Rspack supports most of the webpack community plugins and also offers alternative solutions for some currently unsupported plugins.

You can refer to Plugin compat to understand the compatibility status of some commonly community plugins in Rspack.

Handle Loaders

Rspack supports most of the webpack loaders. Below are some examples of migrating loaders. By referring to these examples for replacement, you can achieve more significant performance improvements.

Removing babel-loader

Rspack already has built-in support for TypeScript and JSX as well as the latest ECMAScript syntaxes. If your configuration only uses babel-loader to support TypeScript, JSX, and modern ECMAScript, then you can remove babel-loader entirely.

Alternatively, if your configuration relies on babel-loader for custom conversion logic, it should be kept. However, we recommend to avoid babel-loader if possible because it can cause significant performance degradation for large projects.

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
+          },
+        },
+      },
     ],
   },
 };

Removing css-loader style-loader and mini-css-extract-plugin

Rspack's native CSS Module type has built-in support for CSS, CSS HMR, CSS Modules, and CSS extraction. This eliminates the need for css-loader, style-loader, and mini-css-extract-plugin for handling CSS files:

-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: [],
 };

Rspack's css-modules functionality is enabled by specifying `css/module`` as the module type:

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
+      },
     ],
   },
 };

CssExtractPlugin

If you need some specific configurations from css-loader, you can still use style-loader + css-loader, if you want to extract CSS files for production, you can use Rspack builtin plugin: CssExtractRspackPlugin.

CssExtractRspackPlugin is similar to mini-css-extract-plugin, be sure that you've already enabled experiments.rspackFuture.newTreeshaking, it's enabled by default after 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"
        ]
      }
    ]
  }
}

Using asset modules instead of file-loader and url-loader

Rspack is aligned with Webpack 5's "asset modules," which should be used instead of file-loader and 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"],
-      },
     ],
   },
 };