Skip to content

开发指南

合理规划前端内部大仓,能够有效提升业务开发效率及体验,进而保障业务交付质量及效率。更重要的是能保证业务系统长期可维护易迭代。

背景与现状

目前B端体系交付项目较多,各系统相对独立,且存在较多通用能力,如认证方式,权限管理等,但是每一个业务系统都需要单独处理,长此以往极难保证未来的交付效率和质量,代码层面也不利于长期维护。

对于开发团队来说同样也难以保证技术收敛及协作共建。

所以需要梳理,并抽象通用能力,封装通用组件,有利于减轻业务系统开发难度,提升开发效率及体验,从而保证敏捷开发场景下的效率和质量,以及保证编码规范的限定,利于项目长期迭代不断扩展。

比如遇到如下问题或场景,我们应该如何思考:

  • 公司内部的设计规范,应该如何落地?业务交互场景如何保证统一?
  • 认证体系从uums改为sso业务系统是如何支持的?是否侵入业务?是否向后兼容,如果未来还有别的认证方式如何应对,比如要支持local认证?
  • 权限处理各异,但又大同小异,最终目的都是控制元素是否可见是否可操作,入口是权限code,出口是元素控制,这期间的不变能否封装?
  • 针对支持微前端场景,业务系统如何处理的?isMicroApp是否侵入业务?
  • 针对sentry上报的接入,各业务如何处理?
  • 针对耦合严重的部分,如何解耦?比如登录的相关处理,如何跟路由解耦,如何跟状态管理解耦?状态管理更适用于哪些场景?
  • 封装在各业务系统的通用代码,如何适用到其他业务,避免重复开发,如何抽象,如何封装,又如何管理,如何维护,如何渐进升级?
  • 高效的业务开发与交付,如何将精力都投入到业务逻辑的处理,而不用关注或尽量少的关注与业务无关的东西?

其实我们针对上述问题的思考,就是大仓梳理规划要解决的问题:

开发效率

虽然已有基础组件库SmartDesign脚手架的加持,很大程度上保证UI规范的落地,及高效率创建新项目,甚至一定程度解决了项目的一致性问题。

但是上述只是对基础组件的处理,目前各项目内部关于搜索,表格,表单等都需要基于基础组件重复开发(CRUD环节),这些高度一致的UI展现及交互行为,包含了大量重复的工作,效率难以保证,

同时也很难应对未来的变化,因为设计规范只有一套,但是代码实现确是在各个业务系统,但凡规范有一点变动,针对各个系统的支持工作量也将是N倍的放大。

简单截图示例如下:

  • 查询处理

    Search

  • 表格处理

    Table

  • 表单处理

    Form

开发体验

目前开发时既要关注页面布局,又要处理很多相似的交互逻辑,且可移植性较差,无法专注业务逻辑开发,开发体验难以保证。

由于各系统独立,很难保证每位同学遵循一致的开发规范(难以落地公司指定的开发规范,即便有周期性的CodeReview),甚至产生多套风格迥异的交付系统。

随着业务不断发展,各系统差异也会越大,维护难度也就不断上升。

比如在人力资源紧张的情况下,某个周期内可能会有团队成员需要参与多个项目的迭代,此时由于项目跨度较大,如果编码风格和处理方式各不相同,必然会导致心智负担重,进而导致开发体验急剧下滑,开发效率降低。

一旦有些许变动,将会产出极大的工作量,比如设计将搜索区域的120px,240px统一改为200px,将清空已选改为重置,每个项目都去改是否合适?

虽然很多业务场景的变动不可避免,且逐个项目逐个响应,也能实现需求,保证交付,但每个开发人员都会感觉的这过程不合理,不可持续,不能稳定迭代。

那对开发人员来说来说,面对需求场景变更如何尽量少改代码,甚至不改代码进行快速迭代,所以整个工程规划过程就在不断探索最佳实践,以保证团队开发效率和体验。

再比如以下问题如何解决会更友好?

  • 认证体系从uums,切换sso时,业务开发如何高效应对?如何快速响应,不侵入业务?假如未来有更多的认证系统,又该如何适配?
  • 针对sso集成平台微前端场景下,业务系统又如何快速迭代?如果不可避免改代码,那如何保证尽量少的改动?isMicroApp如何不侵入业务?

交付质量

开发中偶尔会遇到一些紧急需求,如果没有一些通用能力及高级组件支撑,在时间有限的情况下很难保证按期交付,又或者难以保证交付效率,交付质量。

长此以往,会逐渐产生厚重的历史包袱,质量不可控。

难以共建

公司内部一般会针对特定的领域或者场景,沉淀自己的专有组件或行为,这些应该如何沉淀和管理,
如已有的请求模块,hooks模块,选人组件,导入组件等,
再如A同学在之前的项目中已经针对性的封装过某组件,如何快速在B项目中完全复用,并可以不断迭代完善?

一个良好的共建协作环节类似下图,可以是业务开发时梳理封装的通用能力沉淀到大仓内统一管理,大仓能力的不断迭代和完善进而为后期其他项目提效,是一个可持续的良性循环过程。

construction

提效演进

早期我们会使用官方脚手架创建项目pnpm create vue@latest,后面为提升创建项目的效率,开发企业级脚手架fs-cli,但通用模块散落在各个业务系统内,如何统一管理,平稳升级?

工程演进

后续待后端相关平台级服务完善后,可进一步梳理相关应用,结合fs-cli能力扩展,从而再一步提升业务开发效率和开发体验。

大仓规划

整体采用最常见的分层架构进行拆分,以解决现存耦合问题。

基于fs-cli创建的wms为基准,将模板中的通用能力抽离,如http,passport,localstorage等模块。

另外梳理业务通用高级组件,如SearchForm,AdvancedTable,AdvancedForm,Page等,并基于业务考虑抽离RemoteSelect,UserSelect,FileInput等组件,以便更高效的进行业务开发。

组件是一种编程抽象,常以通用型组件和业务型组件划分。

针对常用逻辑,梳理有v-permission,v-loading,v-tooltip/tips指令,及通用hooks

分层示意图 分层示意图

版本管理

monorepo管理可参考一些流行的开源项目,如vue

monorepo管理的仓库下,版本管理常见固定版本独立版本两种版本管理策略,两种模式各有特点。

一些历史项目,或复杂项目会采取独立版本模式,如流行的babel,像vuelernaunocss等都采用固定版本

fs-web-library考虑项目简单,职责明晰,采用固定版本进行版本管理,

好处是简单易维护,便于溯源,如在publish时考虑溯源会针对此仓库打tag,如果采用独立版本会导致打tag的策略很难管理,
同样在后续迭代中可能会产生一定量的BreakChange,如果采用独立版本很难保证业务系统的稳定性,
当然,固定版本也会有一个缺陷,但是无关紧要,就是未改动的模块也会参与publish,但是基于简明易维护的原则考虑,此问题可以忽略。

参与共建

随着公司业务不断发展,必然会产生很多通用的场景,进而会封装通用组件或工具,初期或者时间紧张的情况下,可能会散落在某个业务系统内,
但是为了后续开发效率及开发体验考虑,需要团队中每一位成员及时甄别,参与共建,将通用模块沉淀在大仓内。

调试&发布

提示

强烈建议过一遍pnpm文档,如常用的pnpm i & pnpm add,及filter参数

整体流程,
先在大仓内编写相关模块,同时在playground内调试,之后publish,再业务系统中验证,且经历开发者验证和测试环境验证后,考虑发布正式版,禁止生产环境使用非正式版私有包。

bash
# 基于master检出开发分支feature/xxx,并在此分支开发验证,并发布beta版,在业务系统中验证

git checkout -b feature/xxx

git commit -m 'feat: xxx'

git push

pnpm run publish
# 参数收集 一般针对两次问询直接回车即可,即回车默认补丁版本+测试版。

# 业务系统验证通过后,可发起merge request至master

调试,

开发时可以直接调试无需构建,且独立在playground包中,不与任何包耦合。playground是一个完整的vue应用(包含认证模块,路由模块,多语言模块等,且可根据场景进一步完善),可以便捷且全面的调试大仓内的任何功能模块。

bash
pnpm install
pnpm run dev

文档,

上述如有文档的变更,也需及时补充docs,基于vitepress

为何不是vuepress?

特别注意📢

共建时更改现有代码,一定要考虑向下兼容,非必要,不要产生BreakChange

bash
pnpm run docs:dev

版本,

严格区分正式版测试版,以避免beta版影响到生产环境。

bash
# 明确npm规则即可,发包时已在scripts中处理
pnpm i @fs/utils
pnpm i @fs/utils@beta
pnpm i @fs/utils@0.1.0-beta.0

发布,

发布流程会校验是否有待提交信息,即考虑溯源需要针对publish的包做版本管理,所以需要将内容提交后才能进行发包,
beta包不限定发包分支,
正式版限定在master上发布,原因是正式版影响范围较大,需要慎重发包,可以利用MergeRequest时的人工审核环节来尽量降低风险。

bash
# 测试发包命令
pnpm run publish:dry

# 推荐发包命令
pnpm run publish

# 不推荐指定版本发布,除非处理breakchange 添加 version 参数
pnpm run publish --version=1.2.3

发包策略,

运行pnpm run publish时若无参数,会以命令行交互的形式收集参数,默认读取线上最新版本,以避免版本混乱,再进行semverInc

发包流程图,

Publish

未来,

可集成至fs-cli中,脚手架不仅仅是命令行工具,本质是软件,若cli中逻辑处理清晰,可以很方便的打包成GUI客户端软件,能够更好的提升开发体验及效率。
此外,基于研发需求分析,cli还可以做很多自动化相关提效的事情。

若未来大仓内组件稳定,可考虑编写适用于公司内的vscode插件以便进一步提升开发效率及体验。

为何不在smart-design中继续添加相关组件?

主要有以下几方面的考虑,

  1. 定位不同

@fs/smart-design是基于antdv(3.x)二次包装的通用基础组件,定位在基础而非业务,如果继续添加业务组件,随之产生的非组件模块难以管理。

常见组件规划有如下结构

Components

  1. 仓库设计

调试困难

@fs/smart-design仓库开发调试困难,如调试组件效果是将src视为App,在此应用内实现组件调试,而src本质其实只是组件库,不应该是App,职责不明,

当场景复杂时调试会更加困难,如添加路由管理,状态管理,多语言管理等常见业务场景,很难还原真实的业务场景开发。

另外编写文档时需要对组件库不断进行build,无法做到实时更新,耗时效率低,体验较差。

参与过smart-design组件库UI改造的同学应该能够感受到。

扩展困难

基于现有@fs/smart-design仓库设计,很难继续添加业务相关通用能力,如utils,directives,hooks,service,高级组件,启动器等常用功能模块。

发包策略

存在开发与生产不分离,npm版本管理混乱,无法溯源等细节问题,即npm i @fs/smart-design可能会安装到beta版本。

基于上述,如果继续基于smart-design来扩展,涉及较多改造,如仓库改造,脚手架改造等繁杂工作。

问题

目前仍然存在一些待解决的问题,在可预见的未来可能会带来一些影响。

认证体系的问题

没有平台级统一的鉴权体系,一些非业务相关的平台级服务,前端是否应该直接对接,如S3文件处理,虽然前端FileInput组件内部直接对接了,但是由于鉴权体系不通会有一定的安全隐患。如果前端不直接调用,交由各自业务后端做中间层转发,能相对保证鉴权体系一致,但会带来组件库要维护环境的问题。若如此,组件库维护环境,业务仓库维护环境,会很乱,也意味着潜在风险很大。

前端环境的问题

试想,前端如何不关注环境,即在每一种环境代码都是一致的?

前端不应该维护http请求相关的环境配置。

但是目前各项目内配置多套.env文件,且会将相关的信息打包到dist中,很难灵活应对如下常见场景,

  1. 微服务场景

后端有一些类似BaseService此类通用服务(如目前的ums,PlatformAuthApi),且需要前端直接调用,那业务开发时需要针对此类服务维护多套域名,封装业务组件时如果再处理环境信息就更不妥了,
如果域名要变,这么多系统,难道要逐个更改,逐个打包,逐个发布?
如果考虑安全,需要收回域名,不做域名解析,不开放公网,前端如何做,把IP端口这些敏感信息打到dist
如果要接网关,常见类似/gateway前缀,又要大批量的改项目?

上述会带来很大的工作量,也会导致上线风险巨大。其实每一次上线之所以那么重视,就是因为存在很大风险,而流程化就是要尽力降低风险。
如果严格按流程走,那便是dev->test->uat->生产,整个环节需要投入开发,测试,产品,UI等人力资源,成本大效率低;
如果不按流程走,那上线风险便不可控。

  1. UAT环境的意义

公司目前在推UAT环境,在保证高效与一致性的情况下,运维往往会将UAT产生的release镜像包存档,在需要上线时直接拷贝过去,而不是重新构建镜像,
一来可以保证发布效率,二来能够绝对保证生产上的包是经过uat验证过的。

目前前端将环境信息打包到dist中,上述场景便不可实现,即无法快速上线快速回滚。
因为前端每次镜像构建主要耗时阶段发生在install+build阶段。 同样也无法完全保证生产环境的代码是跟UAT完全一致,即经过UAT验证过的包,因为难保UAT->生产这段时间仓库代码会发生变动,也难保第三方依赖是否做了升级。

微前端的问题

微前端有个很重要的点,独立开发,独立部署,独立访问。

但是目前似乎做不到独立开发,独立访问,原因是layout模板未抽离,注意不是Menu+Nav组件。

同样也无法做到统一的菜单,头部,底部,404页面等统一共用的内容。

另外子应用管理是否有必要用此服务(GET https://micro-platform.fs.com/api/sdk/5e8438bb-5af9-4cf2-b059-17197dedc288)?毕竟会带来额外的维护成本,并且在基础建设不健全的情况下(如常见的认证体系,日志体系,监控告警体系等)将nodejsWebAPI用于商业应用,会带来较大安全隐患及风险。
利用公司现有统一权限平台能否依此解决子应用管理?

阅读推荐