React从webpack迁移到rsbuild 纪实

Why

随着团队项目规模越来越大之后,继从babel-loader迁移到esbuild之后发现打包、热重载性能随着时间迭代之后又慢慢开始成为性能瓶颈,所以决定用新的打包工具去解决这个问题。esbuild 自然成为了不二之选。

What esbuild 是什么

esbuild 是基于espack 的一款打包工具,借助于rust的性能加成在前端应用打包领域取得了非比寻常的进步,以下是他相较于其他打包工具的对比:

Benchmark results from build-tools-performance.

相较于webpack, espack 有以下几个特性:

  • rust的性能加持: Webpack的性能经常被其竞争对手挑战,特别是在大型项目中。Rspack使用Rust语言解决了这个问题,Rust语言专门设计来优先考虑性能,在速度和内存管理方面都在benchmarks的前列。Rust还提供了许多编译器保护措施,以避免其他原生语言(如c++)的常见陷阱。
  • 高度并行的架构: webpack 受限于 JavaScript 对多线程的羸弱支持,导致其很难进行高度的并行化计算,而得益于 Rust 语言的并行化的良好支持, Rspack 采用了高度并行化的架构,如模块图生成,代码生成等阶段,都是采用多线程并行执行,这使得其编译性能随着 CPU 核心数的增长而增长,充分挖掘 CPU 的多核优势。
  • 内置大部分的功能: 事实上 webpack 本身的性能足够高效,但是因为 webpack 本身内置了较少的功能,这使得我们在使用 webpack 做现代 Web App 开发时,通常需要配合很多的 plugin 和 loader 进行使用,而这些 loader 和 plugin 往往是性能的瓶颈,而 Rspack 虽然支持 loader 和 plugin,但是保证绝大部分常用功能都内置在 Rspack 内,从而减小 JS plugin | loader 导致的低性能和通信开销问题。
  • 增量编译: 尽管 Rspack 的全量编译足够高效,但是当项目庞大时,全量的编译仍然难以满足 HMR 的性能要求,因此在 HMR 阶段,我们采用的是更为高效的增量编译策略,从而保证,无论你的项目多大,其 HMR 的开销总是控制在合理范围内。

How 我们怎么做的

webpack项目迁移到rsbuild并不难, 甚至非常简单,我们是存量项目迁移 typescript less 是基础语言,因此通过以下几步我们就完成了关键迁移:

  • 如果直接一步步集成各种plugin跟构建工具,踩的坑肯定很多,所以我们是这么做的 先用npm create rsbuild@latest 创建了一个全新的项目
  • 然后把对应依赖的包跟rsbuild config 从上一个新项目复制到自己项目中
    • 一般是 rsbuild.config.ts
    • @rsbuild/core @rsbuild/plugin-react 这两核心包
  • 下载依赖,这一步要把自己项目内的css预处理语言对应的插件添加上我们项目是less因此添加了@rsbuild/plugin-less
  • 配置html
  • 配置代理
  • 兼容其他webpac配置
    • alias
    • define
    • entry等等

然后分享一个坑是某个文件less引用了一个图片 使用的是相对路径地址,结果导致打包工具解析不到正确的路径,从而在整个打包进程一直卡在某个地方卡着,也没错误提示,最后解决方法就是使用别名路径配置了地址,就解决了。

定位问题的时候,这个地方我们是用排除法去定位的,就是首先把引用的文件全注释掉,然后一一放开 发现哪个文件放开的时候 打包有问题就去排查这个文件,不断重复此过程就能定位到最终问题发生的文件。

最后放个大体配置文件, 注意不要直接复制:

typescript 复制代码
export default defineConfig({
  html: {
    template: './src/index.html',
    inject: 'body',
    templateParameters: {
      removeConsole: true,
    }
  },
  source: {
    entry: {
      index: './src/index.tsx',
    },
    define: {
      
    },
  },
  resolve: {
    alias: {
      '@': '/src',
    },
  },
  output: {
    copy: [{}],
    cssModules: {},
  },
  dev: {
    progressBar: true,
  },
  plugins: [
    pluginReact({
      fastRefresh: true,
    }),
    pluginLess({
      lessLoaderOptions: {
        lessOptions: {
          javascriptEnabled: true,
        },
      },
    }),
  ],
  server: {
    port: 3000,
    proxy: {
      [PROXY_URL]: {
        target: `https://${headers.Host}`,
        secure: false,
        changeOrigin: true,
        pathRewrite: {[`^${PROXY_URL}`]: ''},
        headers,
      }
    },
  },
  tools: {

  },
});

嗯 大体就是这样了。完结。

相关推荐
鸿蒙开发9 小时前
Three.js 首帧卡顿排查:compileAsync 之后,为什么还会停一下?
react.js·three.js
小李科技18 小时前
【性能优化】事件委托:目标定位与 React/Vue 实战
前端·vue.js·react.js·面试·性能优化·前端框架
csj5018 小时前
前端基础之《React(16)—Modal组件封装》
前端·react.js
ZoeLandia3 天前
React11:数据请求与 TanStack Query
前端·react.js·typescript·react
瓦瓦gogo3 天前
实习中接触前端开发后,我开始了解 React
前端·react.js·前端框架
ZoeLandia4 天前
React08:自定义 Hook
开发语言·前端·react.js·typescript
空中湖5 天前
用 React 写数据大屏:为什么我不建议用图表库
前端·react.js·前端框架
来一首_We_go7 天前
React Flow Pro 高级交互实现
前端·react.js
weedsfly7 天前
React 不可变数据:为什么页面“明明数据变了却不更新
前端·javascript·react.js
随风一样自由7 天前
【React+TS71007】Next.js “use client” 误用导致 TS71007:客户端/服务端引入问题的完整排查与修复
前端·javascript·react.js