Skip to content

本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com

原文地址:https://juejin.cn/post/7370197993679355954

作者:生姜拿铁

去年年初接手了一个 B 端项目,经历了几个月的开发之后,发现了一些问题,严重的影响了前端的开发效率和上线质量。当时业务迭代快,前端人力又少,因此,我们专门立了一个技术项目,来对现有的系统进行一个渐进式的工程化治理。

选择什么样的工程方案

社区内对于前端工程化方案已经有一些'一揽子式'的解决方案。比如 next,umi,我们公司其实也有一套方案。但是这些方案普遍存在的问题,

  1. 迁移成本高。因为是一揽子方案,要做很多适配工作。

  2. 定制化难度大。因为是黑盒,遇到问题几乎只能等官方支持。

  3. 臃肿。因为这些一揽子方案要适配各种场景,因此会有很多不需要的依赖和配置,比如我们公司的方案会有很多上报的服务。

综上,我们选择了针对自己项目的方案,一个点一个点的去解决问题。

规范

  1. 代码规范。这个较为常见,网上也有很多教程,没有什么干货,重要的是取舍一些规范。一个我认为较为重要的点,是目录结构和接口的命名规范,这在后期的维护上会节省很多成本。

  2. 前后接口规范。这个是与后端团队协商出来的规范,包含一些统一的错误码,数据结构,数据类型,通用的字段名称等。这个规范能保证接口的可联调性。

  3. 协作规范。这个是涉及到产品上线的全链路流程,比如需求的准入要求,转测的验收标准,上线的 SOP 等。这些是需要跨团队沟通和确定的。

  4. 交互规范。这个是与产品协商的,通用的交互规范,便于组件的沉淀和复用,降低开发的难度和成本。

基础建设升级

打包工具升级

项目的打包工具还是 webpack3.X。经过调研之后,没有使用 vite 和 webpack5, 而是直接选了当时发布不久的 rspack。
主要是基于以下几点考虑:

  1. vite 没有想象的快,启动很快,但是首页白屏时间还是要很久。并且,线上线下的底层打包工具不一致,不好发现问题。

  2. webpack5 很好,但毕竟还是基于 node,随着代码量的增多,打包时间还是会逐渐再次增长。相比之下,rspack 使用 rust 来实现,在这种计算密集的场景下,性能和 node 不是一个级别的,即使代码增多,打包时间所受的影响也较为轻微。

  3. rspack 已经经历了字节内部的检验,并且编译核心也是久经考验的 swc。打包工具的升级,带来了非常好的效果。我们的发布流水线,一下子从 20 分钟,缩短到了 8 分钟。平均每个月为开发者节约 80hour。

当然这个过程并不是一帆风顺的,当时的 rspack 还是有一些插件的兼容性问题,但还好官方回应快,自己也就很快解决了。

包管理器升级

原有的包管理器是 yarn2.X,我们升级到了 pnpm。
pnpm 的好处不用多讲,总之就是快,而且切换成本低。
同时,我们对项目中重复的包,无用的包进行清理。使得最终我们的 node_moudle 从 2 个 G,缩小到 700 多 M。但遗憾的是,我们公司的发布流水线不支持 pnpm。因此我们专门写了适配的插件,并加上了服务器缓存,在缓存命中的情况下,包的安装时间只有 3 秒。

改造完成后,我们的线上发布时间,在缓存不命中的情况下,也缩短到了 4 分钟。

堪称极速,开发体验也大大提升。

采用 monorepo

我们的业务有多个系统,由于是服务同一个业务,因此有很多数据类型,组件,接口都是可以复用的。
但我们现有的系统代码,是分散在不同的仓库中的。如果要想复用,往往就是从其他地方直接复制过来,改改就用了。
这一方面会有潜在的质量问题,一方面也违反 DRY 的工程原则,难以治理。
使用 monorepo,就可以很好的解决跨系统的组件复用问题。
我们采用了 lenra 方案,新增可以中间依赖的包,存放这些可服用的资源。一年下来,沉淀了有 70 多个组件,复用次数达 500 多次,开发提效约 20%。

物料建设

常用组件沉淀

由于我们公司并未采用 antd 这样的较为成熟的社区组件,因此许多业务组件,都需要自己建设。而 B 端业务,大部分都是增删改查,因此我们针对通用场景做了标准化组件建设。

一方面,我们针对自己的业务特性,对这些组件进行功能增强或者样式改善,比如给 Form 加上不同类型的布局。
另一方面,我们对于相似场景的组件,进行了配置上的统一。

比如 Form,Table,Description 这样的组件,都需要配置所显示的 label,对应的数据字段名,以及显示成什么样子。我们将这些组件的字段配置统一起来,这样提升了组件的可配置性,配置文件的可复用性等。

VScode 插件开发

由于组件配置上的一致性,很便于做一些模版填充。因此,我们又做了一个 VScode 的插件。
它内置了一些代码模版,比如复杂的 CRUD,编辑表单,编辑页面等。
当用户选中一些 TS 的类型时,它 可以读取这个类型中包含的字段,生成配置代码和 mock 数据,填充到内置的模版当中。
填充好的代码是直接可以运行的,只需要调整一下适配的字段,真实请求的接口即可。
普遍场景下,开发者在几分钟内就可以完成一个 CRUD 页面的开发。达到了低代码一样的效果,但又避免了低代码带来的种种问题。

技术治理

领域建模

DDD 是后端比较流行的概念,其涉及的内容较多。作为前端,我们借鉴了其中一部分的思想。

我们业务包含了一些常见的业务流程,比如采购,营销,财务等。

我们将这个完整的流程,作为一个领域,进行 TS 建模。这个建模尽量与后端的建模保持一致,便于进行数据交互。

在单一领域内,数据的类型的固定且通用的,就是我们所说的 Model 层。

而具体到页面,我们新建一个 ViewModal, 使用 ViewModal 来完成页面的交互。

Model 层和 ViewModel 层是紧密联系的,我们采用 AOP 的方式,来对这两种结构进行自动转换,降低开发成本。

这样的设计带来的好处是:

  1. 逻辑解耦,易于维护

  2. 领域内的重复建设会收敛,有助于提效

  3. 单一领域内的理解成本会降低,新人接手的成本也低

当然,其前期建设的成本是比较高的,而且要写一些冗余代码。但是考虑到收益,这是值得的。

低代码替换

由于历史问题,很多页面采用了 JSON Schema 进行低代码渲染的方式。低代码的页面,不仅性能差,小问题多,而且难以复用和维护。因此,在做新需求时,如果与产品确认,该页面后续需求很多,复杂度较高,那么就会考虑将该页面重构为原生 React。在物料和插件的加持下,这种改造成本很低,但是需要做规划和测试。

静态代码分析

日常的开发中,由于各种文件互相引用,在进行开发的时候,极易产生意料之外的影响。同时,由于我们会重构一些低代码页面,因此项目中也存在很多不被使用的无效文件。我们开发了一个工具,它可以根据路由配置,然后一层层的往下递归文件,便于我们分析出无效文件,保持项目的干净度。当有文件变动时,也能层层向上访问,分析出该文件会影响到哪些路由和页面,便于我们进行回归和测试。

总结

我们的治理之路,与社区中主流的方案有一部分是重合的,有一部分则是独创的。但他们的目标是一致的,事实上,经过一年的建设和使用,我们的开发效率和质量都有不小的提升。

  • 欢迎长按图片加 ssh 为好友,我会第一时间和你分享前端行业趋势,学习途径等等。2024 陪你一起度过!

关注公众号,发送消息:

指南,获取高级前端、算法学习路线,是我自己一路走来的实践。

简历,获取大厂简历编写指南,是我看了上百份简历后总结的心血。

面经,获取大厂面试题,集结社区优质面经,助你攀登高峰

因为微信公众号修改规则,如果不标星或点在看,你可能会收不到我公众号文章的推送,请大家将本公众号星标,看完文章后记得点下赞或者在看,谢谢各位!