Migrate webpack

While Rspack is aimed at maximizing compatibility with Webpack API contracts, some minor changes are necessary to accommodate differences in implementation, as well as enabling optimizations by replacing some plugins/loaders with Rspack's built-in equivalents.

Configuration Migration

You can refer to "Webpack configuration compatibility" for configuration migration.

Modify Loader

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: {
+          sourceMap: true,
+          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: {
+          sourceMap: true,
+          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"],
-      },
     ],
   },
 };