尝试项目将Vite迁移到Rsbuild平滑过渡,结果如何?

1,681 阅读4分钟

拿公司其中的一个项目来入手(偷偷说~~~官网),本地新建了rsbuild分支专门用于迁移,暂时还没打算更新到项目的gitlab分支😊 过程中遇到了好多问题 在官网文档、csdn还是Issues中摸爬滚打终于全部迁移完成了,本人front-end一枚,分享一下😣踩坑过程😣

1、项目架构

官网之前我开发的 居然当时都给他们上了vue3 ts vite ele-plus,项目包含模块还挺多的,其中还涉及公司另一个项目的联接,零零散散的功能太多了..... 一直在迭代更新

2、Rsbuild介绍

Rsbuild 是由 Rspack 驱动的高性能构建工具,它默认包含了一套精心设计的构建配置,提供开箱即用的开发体验,并能够充分发挥出 Rspack 的性能优势。

Rsbuild 提供 丰富的构建功能,包括编译 TypeScript、JSX、Sass、Less、CSS Modules、Wasm,以及其他资源,也支持模块联邦、图片压缩、类型检查、PostCSS、Lightning CSS 等功能。

官网也是给出了性能指标:

image.png

rsbuild官网

它包含了很多迁移文档介绍:

Vite迁移--》 https://rsbuild.dev/zh/guide/migration/vite

Weback迁移--》 https://rsbuild.dev/zh/guide/migration/webpack

Vue Cli--》 https://rsbuild.dev/zh/guide/migration/vue-cli

3、基础配置更改

我用的pnpm命令 (node版本一定要注意哦‼️ 》=16) 我的版本是18.19.0

安利一个node版本切换工具nvm-desktop

image.png

移除vite依赖:pnpm remove vite 安装Rsbuild pnpm add @rsbuild/core -D

1)本地package.json依赖文件替换命令:

image.png

2)创建rsbuild.config.ts 删除原有的vite.config.ts

我是在最后才删除vite.config.ts这个文件的 因为我发现之前引入的很多自己都忘记了,有用没有全部重新检查了一下 我把它们分成两部分vite的包和unplugin部分

3)创建基础配置文件
import { defineConfig } from '@rsbuild/core'; 
export default defineConfig({ 
   plugins: [], 
});
4)html路径更改

index.html中移除

image.png

rsbuild.config.ts中更改:

  // 配置html 模版
  html: {
    template: './index.html',
  },
  // 配置路径别名
  source: {
    entry: {
      index: './src/main.ts',
    },
  },
5)环境变量配置
import { defineConfig, loadEnv } from '@rsbuild/core'; 

const { publicVars } = loadEnv({ prefixes: ['VITE_'] }); 

export default defineConfig({ 
  source: { define: publicVars, }, 
});

后续想要使用全局变量可以直接使用 process.env

贴上我的代码(部分马赛卡是 懂得都懂😂😂😂😂)

image.png

6)删除console打印

removeConsole设置为true image.png

3、踩坑的来了

(主要我还是第一次迁移这个有些头痛 但是rsbuild还是特别有好的 在本地编译过程中提示特别到位,精准到每一个文件的每行代码)

import.meta不兼容:

import是module模块中独有的语法,比如Vite 提供了 import.meta.glob() 来批量导入模块,rsbuild官方文档提供了使用 Rspack 的 import.meta.webpackContext 函数代替。

const modulesFiles = import.meta.webpackContext('./modules', { 
  // 是否搜索子目录 
  recursive: false, 
  regExp: /\.ts$/
});

const modules = modulesFiles.keys().reduce((modules: any, modulePath: string) => {
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1');
  const value: any = modulesFiles(modulePath);
  modules[moduleName] = value.default;
  return modules;
}, {});
import引入资源的方式替换import.meta.url:
~~  const iconImg = new URL(
    '../../static/logistics-tracking/positioning.png',
    import.meta.url,
  ).toString();~~
  
  ==>
 import iconImg from '../../static/logistics-tracking/positioning.png';

css中v-bind绑定:
// 改之前:
.innter {
  height: v-bind(title ? '20px' : '60px');
}
// 改之后:
const innerHeight = title ? '20px' : '60px'; // ts中写
.inner {
  height: v-bind(innerHeight);
}
解决样式$sideBarWidth等...警告:

sass文件默认注入全局的变量文件

export default defineConfig({ 
  plugins: [
    pluginSass({
      sassLoaderOptions: {
        additionalData: `@use './src/styles/variables.scss' as *;`,
      },
    }),
  ], 
});

4、完整的rsbuild.config.ts

部分特殊代码可能没有在下面展示,可以进行参考:

import { defineConfig, loadEnv } from '@rsbuild/core';
import path from 'path';
import { pluginVue } from '@rsbuild/plugin-vue';
import { pluginVueJsx } from '@rsbuild/plugin-vue-jsx';
import { pluginBabel } from '@rsbuild/plugin-babel';
import { pluginSass } from '@rsbuild/plugin-sass';
import AutoImport from 'unplugin-auto-import/rspack';
import Components from 'unplugin-vue-components/rspack';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
import IconsResolver from 'unplugin-icons/resolver';
import { pluginImageCompress } from '@rsbuild/plugin-image-compress';

const { publicVars } = loadEnv({ prefixes: ['VITE_'] });

export default defineConfig({
  plugins: [
    pluginVue(),
    pluginVueJsx(),
    pluginBabel({
      include: /.(?:jsx|tsx)$/,
    }),
    pluginSass({
      // sass文件默认注入全局的变量文件
      sassLoaderOptions: {
        additionalData: `@use './src/styles/variables.scss' as *;`,
      },
    }),
    // 启动图片压缩
    pluginImageCompress({
      use: 'png',
    }),
  ],
  // 配置html 模版
  html: {
    template: './index.html',
  },
  // 配置路径别名
  source: {
    entry: {
      index: './src/main.ts',
    },
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
    define: publicVars,
  },
  tools: {
    htmlPlugin: {
      template: './index.html',
    },
    rspack: {
      plugins: [
        AutoImport({
          resolvers: [ElementPlusResolver(), IconsResolver({})],
          eslintrc: {
            enabled: false,
            filepath: './.eslintrc-auto-import.json',
            globalsPropValue: true,
          },
          vueTemplate: true,
        }),
        Components({
          dts: 'types/components.d.ts',
          resolvers: [
            // 自动注册图标组件
            IconsResolver({
              enabledCollections: ['ep'],
            }),
            // 自动导入 Element Plus 组件
            ElementPlusResolver(),
          ],
        }),
      ],
    },
  },
  dev: {
    // 按需编译
    lazyCompilation: true,
  },
  // 构建产物相关配置
  output: {},
  // 构建优化相关
  performance: {
    chunkSplit: {
      strategy: 'split-by-experience',
    },
    removeConsole: true,
  },
  // 服务相关
  server: {
    port: 3003,
    open: false,
    proxy: {
      '/api': {
        target: process.env.VITE_BASE_API,
        changeOrigin: true,
        ws: true,
        // rewrite: (path) => path.replace(new RegExp('^/api'), '')
        secure: true,
      },
    },
  },
});

5、最终结果

冷启动和热更新自我感觉变化不大;打包速度还是变化挺大比之前快了好多,之前Vite的效果图我就不附上了(vite打包没留截图 懒得切分支😁😁)

image.png

image.png image.png

更多的Rsbuild插件

Rsbuild常见问题

当前文章只针对我个人的,如果你发现有不同的地方,欢迎补充和交流 🤝。