重构 webpack 打包

2023-01-11

背景

项目将近有四十万行,打包时间大约 120s,项目里代码风格多样

-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
TypeScript                    1667          12662           7539         202771
JSX                            741           6224            833          95437
JSON                            70            100              0          35926
JavaScript                     557           3160            446          35574
Sass                           278           2680             89          15237
SVG                             58              3              0            533
CSS                              2              4              1             69
Markdown                         3              8              0             24
HTML                             1              4              4             16
-------------------------------------------------------------------------------
SUM:                          3377          24845           8912         385587
-------------------------------------------------------------------------------

重构

分支使用 dev_federation

  1. 消除所有循环依赖。总计有 600 多个循环依赖。呈现出几个特点,一是在普通函数接入 react 生态的状态机,导致的循环依赖,这里的例子是 i18n 以及 auth 登录态等。二是目录里面的成员函数接入 index,而 index 又收录目录里面的成员函数。
  2. 将所有 js 转化为 ts, 将所有 jsx 转化为 tsx。 这里需要排除使用 styleName 语法的 jsx 情况单独处理。
  3. 对 src 文件进行 eslint 修复处理,但不进行 styleName 修复的处理。
  4. 处理代码文件中,import 语句中带有显性后缀的处理 如 .js .jsx 去除。
  5. 剩余 271 个文件需要处理 styleName 问题。 已完成。特别的案例: 原来的 import 就叫做 styles,这时候要把底下的引用一起变更。 或者函数里面的参数就是 style, 这个时候相关的重名都需要一起变更。
  6. 集成 esbuild 加速处理 ts 文件,但需要注意能否支持 css module 特性,或者说能否替换掉 ts-loader. webpack 5.74.0 compiled successfully in 151333 ms 成果:从 120000ms 减少至 56245 ms,构建时间加速了 53%.
  7. 去除 babel 转译。 已全部去除。
  8. 加入 mfsu, https://umijs.org/blog/mfsu-independent-usage 成果: 热启动时间 25513 ms (终端命令到最终显示时间大概是 35s),构建时间减少了 78%

剩余步骤

-- 考虑其 ROI 呢

  1. 开建 npm workspace 目录结构。
  2. 将 merchant store entity onboarding 抽离 处理成 federation。且双方共享的目录应该放置在独立目录,对应配置 eslint 以及 tsconfig。
  3. 设置原项目为 host 配置结构。
  4. 考虑完成并行启动 dev 命令。
  5. 将 federation 以及 host 构建结果放置在一起并测试部署情况。
  6. 修复因为重构改动引起的问题

备注

attribute 模块已经交接出其他团队 sale order management 都是 attribute 的,都不要了 如 xxx/en/sale/order/list 没有 attribute 了,前端是不是可以把入口关了?

统计

构建性能加速了多少?

加速了 53%.(使用 esbuild, 未使用 mfsu) 带着 mfsu 构建时间减少了 78%

代码优化做了什么事, 涉及代码数量是多少? 有什么益处?
2403 files changed, 135239 insertions(+), 115359 deletions(-)

600 多个循环依赖, 全部解除 styleName 语法, 全部转成 className 将全部 jsx, js 转入 tsx, ts 文件

涉及文件变动

后续想做的 mfsu 的 https://github.dev/umijs/umi/tree/master/examples/mfsu-independent

loader 性能对比

speedy web compiler

webpack 5.75.0 compiled successfully in 39155 ms

esbuild

webpack 5.75.0 compiled successfully in 45260 ms

ts-loader

webpack 5.75.0 compiled successfully in 69440 ms

  System:
    OS: Windows 10 10.0.22621
    CPU: (16) x64 AMD Ryzen 7 3700X 8-Core Processor
    Memory: 8.18 GB / 23.95 GB
  Binaries:
    Node: 18.12.1 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.19 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 8.19.2 - C:\Program Files\nodejs\npm.CMD

加入 mfsu 以后的效果

对于同一个文件 ./src/screens/MerchantManagement/ISVMerchantOnboarding/Detail/components/ActionButtons.tsx

mfsu

热更新速度是 1334ms (1210+1483+1214+1455+1308)/5 热启动速度是 25513 ms (终端命令到最终显示时间大概是 35s)

从感受上来说,热更新构建的速度比以往快很多,时间上大概是从 4 秒优化至 1.5 秒以内,主要的思路是通过模块联邦不再打包各个依赖项,dev-server 加载一个依赖目录。剩余的优化空间是对于本地代码文件的打包了。

没有 mfsu 的热更新速度

很久

项目优化后代码统计

-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
TypeScript                    3104          22097           8831         334308
JSON                            70            100              0          35946
Sass                           278           2680             89          15237
SVG                             58              3              0            533
CSS                              2              4              1             69
Markdown                         3              8              0             24
HTML                             1              4              4             16
-------------------------------------------------------------------------------
SUM:                          3516          24896           8925         386133
-------------------------------------------------------------------------------

mfsu 原理

https://juejin.cn/post/7172109203526385694 基本讲的非常清晰了。

本地应用

首先加载缓存依赖树 注入 babel 插件 注入中间件 注入模块联邦插件(本地) 分析依赖(替换资源、收集依赖) 生成新的依赖树

远程应用

监听构建完成 判断是否命中缓存,可以跳过依赖构建 注入模块联邦插件(远程),根据依赖生成 exposes。 写入缓存 MFSU_CACHE.json, 打包生成 mf-va_remoteEntry.js

使用新的包管理

https://github.com/yarnpkg/berry

copyright ©2019-2024 shenzhen
粤ICP备20041170号-1