【架构】2273- 前端工程化架构设计

科技   2024-12-17 08:00   福建  

本文转载于稀土掘金技术社区,作者:厚礼蟹man

https://juejin.cn/post/7442531525924061210


最近在忙公司前端基础建设的架构设计,头发快掉光了。说是基础建设组,实际就我一个人,我哭。。。虽然还在陆续招人中,招不到人我就“噶”给公司看👻

背景

公司有五条业务线,每条业务线技术栈都比较封闭。做工程化之前,我对每条业务线做了一次技术摸底,发现问题不少:

  1. 项目框架类型复杂多样,老旧(cra, umi, vite, uniapp, taro, react, vue
  2. 工具类型繁多(mobx,redux,dva,pinia,taro-ui,nutui,antd-mobile
  3. TS应用较少
  4. hook使用意识淡薄
  5. 基础建设薄弱,目前只有各自的组件库
  6. 提效手段稀少
  7. 文档稀缺
  8. node服务开发经验稀缺(BFF,SSR
  9. 工程数量繁多(5条业务线总共近200个,高频维护的也有60个左右),无持续优化手段
  10. 无横向技术共建手段

不能说不太行,只能说惨不忍睹。。。

今年公司在布局AI,新项目层出不穷,对基础建设的述求越来越强烈,看来是时候出手整顿下基建了

目标

  1. 统一技术栈:React,TypeScript,Vite
  2. 统一规范:工程规范、构建规范、lint规范、代码规范
  3. 提高开发效率:cli自动化、mock数据、代码片段、页面模板等
  4. 渐进式可持续优化

分析

分析之前我想先引用《前端架构设计》中的一句话:

前端架构是一系列工具和流程的集合,旨在提升前端代码的质量,并实现高效、可持续的工作流。

然后我们在网上搜下“前端工程化”:

提取关键信息:模块化、组件化、自动化、规范化

我个人认为:

  • 架构设计是一种设计模式,可以根据不同应用场景而变化,设计范围可大可小,比如:BFF的架构设计、CLI的架构设计
  • 工程化是一种应用场景,每个公司的工程化实现都各不相同,原因在于架构设计的不同

总结来说就是,基于某一种架构设计来实现工程化

回顾工程化提取出来的几个关键词,可以发现工程化解决了架构设计里的代码质量和高效两个点,那第三点的可持续应该怎么去理解呢?

我个人觉得可持续可以调整成渐进式优化会更合适一点,在工程化场景我把它分成两个方面:

  1. 旧工程如何逐步接入工程化能力,优化开发流程和体验
  2. 工程化能力如何持续优化

结合公司现状,我调整了一下关键字:规范化、模块化、自动化、渐进式,下面就来拆解下这几个关键字

分而治之

架构图

先对上面的12字真眼(箴言)进行简单说明

  • 规范化(基础):不仅仅是lint规则、代码规范,而是每个项目的同一环节使用同一套解决方案
  • 模块化(设计):将每个环节的解决方案以npm包的形式提供,可以将npm理解成模块
  • 自动化(应用):CI/CDCLI不仅提供项目模板的功能,还能对npm包的进行升级以及配置调整
  • 渐进式(核心):功能模块化持续更新、间歇性重构更新

规范化

规范的重要性我在这边就不过多阐述了,大家都懂得。外加两个公司特性:经常会有跨业务线支援的场景,可能会有做Taro的去其他业务线支援uniapp项目的;基于上个特性,就大概率会出现屎山代码、一个项目有两种状态管理工具。

那究竟是因为有屎山导致人力不够要支援呢?还是因为支援了导致屎山变大了?这是个哲学问题(沉思~、~)

所以规范化要做的几件事:

  1. 统一技术栈,React、TypeScript、Vite(umi,taro编译器选择vite)
  2. 根据项目类型统一应用框架,后台:umi;多端:taro;微前端:qiankunSSRnextBFFkoanpmvite
  3. 代码规范:前端规范可以这样做[1]

模块化

目前规划了以下几个模块:

  1. pack:基于应用框架构建配置进行二次封装,能力范围只做基础配置和构建优化
  2. lintalloy+公共规则+业务团队规则,husky考虑到开发水平参差不齐,决定权交给业务团队
  3. micro:提供微前端配置和通讯方案
  4. aegis:因为公司使用的是coding,所以并未使用其他商业监控方案或自己搭建,使用的是coding提供的监控方案

为什么没有组件库?因为我们五条业务线行业跨度较大,UI风格目前达不到统一,组件库由各个业务线自行封装,基建组提供组件库工程模板,包含构建、SSG文档、单元测试等基础功能

自动化

CI/CD采用的是coding的云原生构建部署,docker容器、k8s镜像啥的有专业的运维团队在维护,前端只是写写配置脚本,这里就不展开说了

重点说下CLI,我把CLI和插件规划在提效体系下,这里的插件包含浏览器插件、vscode插件等外部工具的插件,不包含pack插件、lint插件等内部工具的插件

CLI

cli采用的是插件架构设计(看,这边也出现了架构设计),插件架构得益于它的高稳定性和高拓展性,在保证核心程序功能稳定的前提下,丰富了CLI的能力,目前规划的能力有:

  1. 针对各个npm模块提供快速升级和调整配置的能力,省去使用方介入成本近99.999%
  2. 快速生成各种项目类型的工程模板
  3. 自动生成api接口的TS类型和mock数据,注意,这两个是关联关系。我调研了umimock能力,它的弊端在于未打通TS类型和mock数据,TS类型可以通过一些库根据接口文档自动生成,但mock数据还需要开发自己根据类型手动定义,十分麻烦。另外也调研了apifoxapifox能力很强大,弊端在于需要一定的人工成本,无法深度集成进工程体系中。所以规划实现一个根据接口文档自动生成TS类型,再根据接口类型自动生成mock数据,mock能力使用的是umi提供的mock能力,这样就做到了自动化和深度集成。

vscode插件

想必大家都听过这两个词,”代码片段“、”页面模板“

代码片段其实运用到的是vscodesnippets能力:


代码片段好处在于提效和规范,提效容易理解,规范怎么说呢?前端在做代码规范的时候常常会定义一些命名规范,这时候靠人为去记或者CR的时候去纠正是很费时间精力的,这时候通过预定义好的一些代码片段,就能够很好的达到命名规范的要求了

页面模板其实就是通过node脚本去生成预定义好的一个页面文件(夹),实现方式可以有多种

可以通过cli生成,比如nestjscli


umi的微生成器,实际上也是通过cli生成

又或者可以在项目中自定义页面模板,然后写个node脚本去生成

方法很多,但有个通病,对目录结构要求很严格,且模板类型有局限性,比如我对components、hook、page都想生成一份各自对应的模板出来,阁下要如何应对?


这时候引出vscode插件就很妙(妙啊~,~),取长补短

取长:插件内置通用性模板,也支持项目中定义业务性模板,同理snippets也可以做成内部和外部的片段

补短:利用vscode的右键菜单能力,精准定位目标目录

但,vscode插件就目前的人力情况是没办法重新写一个了,只能先用之前写的vscode 插件 --- xy-quick 介绍[2]垫垫了,设计上有些欠缺(目前已不在这个公司了)

浏览器插件

目前没有需要用到浏览器插件的功能,只是预留了这个口子

渐进式

架构设计的三大原则:合适原则、简单原则、演化原则,其中演化原则就是渐进式设计的指导思想

只有变化是永恒不变的,没有一个框架可以一直使用下去而不升级迭代,如何降低版本升级的摩擦成本是每个框架必须要考虑的问题,也就是渐进式,所以我把它标记为核心

我个人认为将功能拆分成模块/插件进行管理在工程化方面是最优选择(有其他见解的欢迎在评论区讨论噢~)

渐进式在这个架构中有两个方面的实现:

模块化

思考一个问题:你是怎么拆解你的项目的,怎么做项目优化的,如果有多个同类型的项目,是怎么做持续优化的

我的方案是将每个独立且可复用的功能提取出来以npm的形式进行管理,也就是上面提到的pack、lint、micro、aegis,这样只需要升级版本和略微调整配置就可以实现持续优化。重点在于我们的npm包要做到什么程度上的配置收敛,是做成umi的开放式还是cra的封闭式?举个例子:基于umiumi-pack包,我们是使用scss还是less、是否打开mock、允不允许打开webpack构建(因为我们设计底层构建工具使用的是vite),这个就是基建和业务的碰撞,需要权衡清楚

CLI

CLI采用的是插件架构,利用其核心稳定性和高拓展性,很好的满足了能力上的拓展,模块搭配cli升级,直接将版本升级的摩擦成本降低至0.001%,完美~

渐进式在工程接入也有两个方面的表现:

老旧项目:单个模块逐个接入,逐步改造

工程化项目:单个模块逐个升级,逐步优化

不足

  1. AI能力的集成,会持续关注可集成场景
  2. coding平台的运用还不够深入,会持续关注可集成场景

做基础建设需要考虑的一些点

  1. 技术选型自不必说,关系到之后技术路线的发展
  2. 做基建的根本目的是为了服务于业务,在设计之初是否做了充分的技术摸底和业务思考,比如是否启用huskynode版本控制
  3. 核心仓库应该如何设计
  4. 新规则与现有规则的取舍/融合

后话

如果你有耐心看到这里,可能会有一些疑问,你这工程化里没有低代码、跨端方案吗?

首先,我想称赞你很有想法(川普肯定了你表情包)

其次,我个人认为低代码、跨端是属于系统级别的工程化,我目前所设计的是应用级工程化,工程化亦有差距

最后,个人水平有限,此文旨在抛砖引玉,引发大家对工程化的思考,欢迎大家在评论区讨论


前端自习课
每日清晨,享受一篇前端优秀文章。
 最新文章