Migrating from Vite to Rspack

vite; rspack; migration; build
807 words

ViteRspack

Background

Yesterday (2024-08-28), Rspack released version 1.0. I was initially just observing, as I didn't see anything particularly attractive about it. But after reading A Complete Improvement in Development Experience: Migrating from Vite to Rspack, which mentioned the "slow page refresh during large project development in Vite dev mode" issue, I felt it resonated with my recent development experience in certain runtime environments. Although my project isn't large, the stuttering I experienced in that special environment also seemed to be caused by too many/heavy requests. By "too many/heavy requests", I mean relatively speaking, because in normal environments, Vite's development experience is excellent.

So I decided to try Rspack and see if it could bring a pleasant surprise: better development experience.

Why Migrate

Let me explain specifically why I wanted to migrate. The issue that's been bothering me with development experience in recent months: when embedding H5 web pages in WeChat mini programs, because I need to use WeChat's official SDK and use HTTPS addresses, I run vite dev locally when debugging.

If I was previously accessing directly via LAN IP, there wasn't much noticeable loading slowdown. But if I was accessing through domain forwarding, the loading speed would become very slow, sometimes getting stuck on a certain request, causing the page to keep loading or even show a blank screen. This is very unfriendly for both development and testing. So I've been looking for a solution, but haven't found one because I had no leads and no time to investigate deeply. But I roughly guessed it might be a build method issue, because Vite's dev mode and build mode are different, and I haven't encountered this issue in build mode.

So when I saw this issue in Moonvy's article, I became more determined to try if Rspack could solve this problem. Because its compilation configuration is consistent across any environment (by default). And it just happened to release version 1.0.

Migration Process

First, I followed the Vite Migration - Rsbuild guide for migration.

  1. Install core dependencies

    1.1 Remove Vite

    npm remove vite

    1.2 Install Rsbuild

    npm add @rsbuild/core -D

    Actually installed Rsbuild v1.0.1-rc.0.

  2. Update npm scripts

    {
      "scripts": {
        "dev": "rsbuild dev",
        "build": "rsbuild build"
      }
    }
  3. Create configuration file

    touch rsbuild.config.js
    // rsbuild.config.js
    import { defineConfig } from '@rsbuild/core'
    
    export default defineConfig({
      plugins: [],
    })

    The configuration file type can be rsbuild.config.js or rsbuild.config.ts. I chose .js for now.

  4. Build entry

    4.1 Remove the <script type="module" src="/src/main.ts"></script> tag from index.html

    4.2 Then add the following configuration to rsbuild.config.js.

    export default {
      html: {
        template: './index.html',
      },
      source: {
        entry: {
          index: './src/main.js',
        },
      },
    };

    Rsbuild will automatically inject the <script> tag into the generated HTML file during build.

    If you're using path aliases, you can add the following configuration to rsbuild.config.js.

    export default {
      source: {
        alias: {
          '@': './src',
        },
      },
    };

    See source.alias - Rsbuild for details.

  5. Install framework plugins

    Since my project uses Vue 3 and Sass, I need to install @rsbuild/plugin-vue and @rsbuild/plugin-sass. Although I also have some JSX code, after installing @rsbuild/plugin-vue-jsx, I found compilation errors, so I didn't install it for now and converted the JSX syntax to Vue syntax.

    npm add @rsbuild/plugin-vue @rsbuild/plugin-sass -D
    import { defineConfig } from '@rsbuild/core'
    
    import { pluginVue } from '@rsbuild/plugin-vue'
    import { pluginSass } from '@rsbuild/plugin-sass'
    
    export default defineConfig({
      plugins: [pluginVue(), pluginSass()],
    })
  6. Configure UI Framework

    I'm using Vant 4 and TDesign mobile, so I need to install the following plugins:

    1. unplugin-auto-import
    2. unplugin-vue-components
    3. @vant/auto-import-resolver
    npm add unplugin-auto-import unplugin-vue-components @vant/auto-import-resolver -D

    Then add the following configuration to rsbuild.config.js.

    import { defineConfig } from '@rsbuild/core'
    
    import { pluginVue } from '@rsbuild/plugin-vue'
    import { pluginSass } from '@rsbuild/plugin-sass'
    import AutoImport from 'unplugin-auto-import/rspack'
    import Components from 'unplugin-vue-components/rspack'
    import { VantResolver } from '@vant/auto-import-resolver'
    import { TDesignResolver } from 'unplugin-vue-components/resolvers'
    export default defineConfig({
      html: {
        template: './index.html',
      },
      source: {
        entry: {
          index: './src/main.js',
        },
        alias: {
          '@': './src',
        },
      },
      plugins: [pluginVue(), pluginSass()],
      tools: {
        rspack: {
          plugins: [
            AutoImport({
              resolvers: [VantResolver(), TDesignResolver({ library: 'mobile-vue' })],
            }),
            Components({
              resolvers: [VantResolver(), TDesignResolver({ library: 'mobile-vue' })],
            }),
          ],
        },
      },
    })
  7. Modify environment variable keys

Basically follow the official documentation Environment Variables - Rsbuild

Similar to Vite, you can access environment variables through import.meta.env. But if it's a variable accessible on the client side, you need to change the environment variable key from VITE_APP to PUBLIC. This way it can be accessed on the client side. Otherwise it will be undefined. If you don't add PUBLIC, when accessing import.meta.env on the client side, it will also be undefined.

console.log(import.meta.env.PUBLIC_NAME); // -> 'jack'
console.log(import.meta.env.PASSWORD); // -> undefined

console.log(process.env.PUBLIC_NAME); // -> 'jack'
console.log(process.env.PASSWORD); // -> undefined
  1. Other

I found that pluginSass has strict checking for Sass syntax. For example, some of my colleagues' code that compiles normally without warnings in Vite would error in Rsbuild. For example, this error Sass: Breaking Change: Mixed Declarations.

At this point, the migration is complete.

The project basically runs normally, and it also solved the issue I mentioned at the beginning: it loads in a flash, no longer getting stuck on certain requests or showing blank screens.

I can sleep well tonight! 🐶