背景

%%待补充企业微信文档%%

五月底,W 集中发版时碰到不少问题:

  • 下载依赖时报网络错误:![[下载依赖时报网络错误.png]]
  • Gitlab Runner 内存溢出导致进程被杀:![[Runner 内存溢出.png]]
  • 调试困难:没有服务器权限,再是改动模板的 Gitlab CI 需要发版

解决方法

CI 模板调试困难

一开时和宇哲讨论想在项目中增加一个 '.ignore-ci-template' 文件来禁用 CI 覆盖。但和成义简单沟通后,问题被推迟到了先做一个和项目绑定的发布平台来解决。

依赖下载出错问题

推测网络问题和 nexus 有关。以前出现过由于没有锁依赖导致安装的新包在 nexus 中找不到所以报错的问题,这次类似,因为 nexus 中缺失没有找到报错的包 @vue/comile-ssr@3.2.15。nexus 应该有类似代理一样的机制,但是不清楚为什么没用。

推荐解决方法是:迁移包管理工具到 pnpm + 换源(淘宝源 + @cybercloud 作用域包),见[[前端下载依赖报网络错误时处理方法]],不要从 nexus 下载那些”找不到“的包,自然就不会出现超时这种网络问题,换 pnpm 主要原因是因为 yarn 在安装作用域包时碰到了不少 bug,其次才是因为它更先进。

![[nexus 中丢失 @vue-compiler-ssr-3.2.15.png]]

进程被杀问题

推测被杀的直接原因是 Runner 内存溢出。

增加 NodeJS 进程内存

一开始怀疑打包时 NodeJS 老生代内存溢出导致被杀,因为在本地打包时观察发现内存占用能达到 4GB 以上。尝试使用 fix-memory-limit 插件和 export NODE_OPTIONS="--max-old-space-size=4096" 指令增加内存上限,但均以失败告终。如果是 NodeJS 异常,应该能在日志看到相关报错,而不是仅仅是一行 ”Killed“ 信息。

Webpack 优化

插件中的自定义弹窗依赖的包括 ElementPlus 和 @cybercloud/ui,打包方式是并行打包。当 Gitlab Runner CPU 算力不够时,任务会堆叠,打包的内存资源一直不能释放。见 #347,讨论后,尝试使用减少并行编译数量、external + CDN、再加 filesystem cache 的形式进行优化。但没能解决问题。

![[external + CDN + webpack cache.png]]

![[Webpack FS cache 似乎没有生效.png]]

filesystem cache 没有生效的原因可能如下错误:

![[ENOENT:no such file or directory 错误.png]]

理想的插件 CI 缓存应该在每一个版本号的任务中根据 package-lock 共享,包括 node_modules、node_modues/.cache 等。但打 tag 会清空缓存,碰到 W 这种集中发版,filesystem cache 反而会带来额外的压力;二是 webpack 的并行数不确定应该如何控制,如果开始打包任务时,服务器算力和内存资源本就不足,那使用增加 thread-loader 的 worker 数量和 parallelism: 3 只会加速进程被杀。

以往迁移构建工具的经验

为了一劳永逸地解决插件编译(主要是插件弹窗编译)问题,考虑使用新的工具。新的工具需要内存占用少、编译速度快、可扩展。

  • esbuild-loader:可以配合 Webpack 使用,作为 vue-loader、ts-loader、js-loader 和 TypeScript 的替代
  • swc-loader:可以配合 Webpack 使用,作为 Babel 工具链的替代
  • Vite:@cybercloud/ui 正在使用,Rollup 生态链,v4 版本后生产模式也启用了 esbuild
  • Rspack:v0.2.0 新版默认支持 vue,swc + esbuild 但比 Webpack 性能好非常多,且可以从 Webpack 迁移

Setup 和 App 项目使用到了 esbuild-loader,见 #824 编译加速,效果不错,再加上缓存能把编译时间(去除 install 和 sonar-check 时间)从最好需要 120s 时间减少到均值 60s

![[Setup 未优化编译时的流水线(2023-02-14).png]]

![[Setup 编译优化后流水线(2023-02-24).png]]

Main 项目和 CybercloudUI 用到了 Vite@4。CyberCloudUI 是从 Webpack 迁移到 Vite,Main 项目做过 Vite@3 迁移到 Vite@4,速度都有所提升。 ![[Main Vite@3 2023-02-09.png]]

![[Main Vite@3 2023-03-09.png]]

![[UI 流水线 2023-02-03.png]]

![[UI 流水线 2023-02-20.png]]

迁移到 Rspack 的结果

就插件模板而言,插件模板项目(和弹窗)几乎没有 TS 代码,文件体量也不大,所以推测使用 ESBuild 不能大幅减小内存占用,也不能带来甚至超过 10% 以上的构建速度提升。之后便是考虑使用 swc-loader 还是 Rspack。使用自带的 SWC 的 Rspack 而不是继续优化 Webpack 配置的理由是,组内没有精力和水平对 Webpack 进行分析和极致调优。

迁移过程较顺利。结果:迁移到 Rspack 后,编译内存占用高峰从 4.7GB 降低到 1.3GB,降低到原先的 27%;编译速度从 132s 降低到 16s,几乎降低了一个数量级(12%)。

Hostname:  Lionad-GS76
Platform:  win32 x64
Release:   10.0.22623
Uptime:    84:48
Total RAM: 63.71 GB
CPU Model: 11th Gen Intel(R) Core(TM) i9-11900H @ 2.50GHz
CPU Clock: 2496 MHZ
CPU Cores: 16 cores

在测试的时候发现使用 Webpack 进行第二次编译,内存占用高峰仍位于 4.2GB,编译速度只减小到 120s 左右。可能是仍有配置项没有调整到最佳状态导致的优化幅度过小问题。目前 Rspack 不支持 filesystem 缓存,未来等这块加上,Rspack 和 Webpack 在插件项目的表现会更大。

本文最后更新于: June 12 2023 22:07