当前位置: 首页 > Web前端 > HTML

得物联C端项目重构实践

时间:2023-03-28 15:53:40 HTML

1.背景1.1重构问:什么是重构?重构是在不改变其可观察行为的情况下改进软件内部结构的过程。--《重构 - 改善既有代码的设计》问:为什么要重构?重构可以提高理解力并降低修改成本。--《重构 - 改善既有代码的设计》问:什么时候重构?(1)什么时候不应该重构?当没有价值、没有意义或投入产出比很低时。团队资源是有限的,有限的资源要尽可能用在有意义的事情上。从团队的角度考虑投入产出比,不要去碰那些只是处于维护状态的代码,比如不需要,不需要调整。代码中可能有很多坑。(2)什么时候应该重构?高昂的项目维护成本会影响项目调整。例如,性能优化时代码看起来很丑。如果不优雅,现有的设计和实现不利于扩展新功能时的重复工作。现有代码无法帮助您轻松添加新功能。打补丁遇到bug,很难排查逻辑。代码审查允许其他人审查代码以检查其是否可读。可理解性太强的代码没有注释,连我都无法快速理清代码逻辑。1.2如何重构(1)准备(基本功)建议多读多读经典书籍,重构圣经《重构 - 改善既有代码的设计》。从毕业第一年开始,几年时间已经读了4遍+,受益匪浅。每次复习,都能有所收获。我经常折腾和处理项目没有任何问题。(2)想清楚重构实践的要点(整体设计是设计出来的,不一定要文档化但需要想通)。协同规划(开发团队内部协作和重构分支与其他分支的整合,早期应用产品、测试、运维等外部资源),统筹规划。层层展开,抓大放小,由粗到细。用好“批处理”。一次只做一件事。不要重新发明轮子。当你觉得有什么难的时候,停下来想一想方法是不是错了,应该是什么样的。不断监控和审查你自己的思维方式。做好内外沟通,尤其是当项目不是一个人开发和维护的时候。注意提前与相关方(测试、运维)沟通(计划、主要时间节点、需要投入的资源、需要他们配合的事项)。2、社区C端的重构实践本次重构具有一定的复杂性。除了技术迁移和改造的成本外,涉及的几个仓库是不同的技术选型(框架&上层组件等),项目快速敏捷迭代,需要高并发和多人协同开发和维护的状态。2.1状态分析技术栈:仓库名称技术栈社区C端页码repoAReact+umi3目标仓库不需要统计repoBReact+umi35repoCvue2+vuex27项目端A/B/C三个仓库主动更新,各仓库涉及多个业务线开发,并行维护。按照2周1sprint、1周开发1周测试的迭代节奏进行,中间穿插hotfixes。V1主版本发布后,各仓库涉及的代码如下:repoA:A1+A1。+A2+A2.repoB:B1+B1。+B2+B2.repoC:C1+C1。+C2+C2..*表示hotfix2.2重构方案前端侧的总体思路:repoA比较新,是社区的主仓库。它集中了大部分C端页面,作为目标C端代码的目标仓库。RepoBtorepoA:RepoB和目标仓库的技术栈很接近,涉及5页,人肉迁移,过程中注意依赖的迁移。RepoCtorepoA:repoC与目标仓库差异较大,语言异构,上层框架和组件库差异较大,涉及页面较多。首先判断有效页面,将离线页面的死代码排除在迁移范围之外;具体细节下面会说到,取出要迁移的仓库中的前端路由配置,知道页面的总范围,在阿里云sls日志中查看最新的PV(通过两种查询方式查看),排除没有流量的页面。层层递进重构,前期抓大放小,费时费力容易出问题的框架语法转换(vuetoreact)应该使用脚本工具实现,维护整体文件级别和每个类转换中的结构和引用关系。详细的语法通过自定义脚本进行批处理(例如vue中使用的class的key和字符串形式的value转换为react中的className和变量形式的value)。为了保证迁移后的高效自测,需要保留对应的*.vue文件,将其作为一个doc文件,在整个迁移完成后将其删除,以提高迁移和测试的效率.请注意,修改后的lint规则会忽略对此类文件的检测。过程中将依赖文件一起搬入,“命名空间隔离”,注意维护整体目录结构的相对关系,整体迁移,不污染目标仓库已有文件,防止同名文件被覆盖姓名。通过以上三个步骤将各个仓库代码迁移到repoA后,同步三个仓库的最新更新。在从repoC到repoA的过程中(从V1切下来的分支),repoC还在更新代码,repoA也需要合并V1.、V2、V2。repoC中的代码(repoB也一样)。由于代码都在不同的存储库中,因此需要手动合并。Tips:V1.,V2,V2的多次提交。可以在repoC中合并为一个commit,所有更改的项目可以聚合到一个地方进行批量更新。repoA中SSR方案的研究和应用也是并行的。重构中新导入的页面要与SSR集成。2.3重构与集成实践2.3.1B仓库页面整理与迁移这部分迁移采用同构语言进行,涉及的页面数量较少,主要通过手工迁移。2.3.2仓库C页面整理及在线流量查询,剔除无用页面。确定三个代码仓库中路由声明的总范围。根据阿里云日志判断近3个月、2个月、1个月的PV。没有PV的页面被排除在要迁移的页面池之外。注1:阿里云SLS日志以上报数据为准,在上报统计过程中可能会丢失数据,所以结合两个查询条目进行判断排查。注2:对于1-2个PV的页面,可能是团队内部开发前期调研时产生的。访问者确定后,会释放产生PV的“测试”页面。确定最终的重构范围(27个过滤器中的13个)。从步骤1得到的totalscope中去掉步骤2中没有用户PV的页面。异构语言转换处理C仓库Vue2转换为A仓库React工具转换,这里主要使用vue-to-react。然而,这个工具有很多约束和限制。大约一半的代码转换成功,转换失败。情况需要自己写脚本实现。本来想把库的源码重新打包改造一下。看完实现,发现定制的成本比自己写脚本的成本还高,就放弃了(我接触Vue不到一个月),时间紧,没仔细研究。.提示:避免重新发明轮子。当执行繁琐和重复的动作时,可以考虑拥抱团队、社区和开源内部的轮子。如果您没有,请自己创建一个。ScriptconversionTransformation项目目录结构设计及文件映射过程//step1:保持整体目录结构的相对性不变。├──api│├──community.ts│├──h5community│├──...├──components├──pages│├──h5community││├──App││├──api││├──资产│├──组件│├──配置││├──过滤器││├──live.js││├──main.js││├──mixins.js││├──router││├──style││├──utils││└──views│├──community├──utils└──...//step2:foo.vue文件转换到foo/目录下,模板分别映射到jsx和less文件。├──api│├──community.ts│├──h5community│└──...├──组件│├──h5community│└──...├──配置│├──h5community.js│└──...├──pages│├──community...返回引用││├──index.scss││└──index.tsx//第一行自动插入对index.scss的引用│└──...└──工具├──h5community└──...分步转换1:文件级对于vue-to-react处理失败的页面,通过脚本生成页面模板文件。//转换前文件为foo.vue//转换后:.└──foo├──index.jsx├──index.local_js└──index.scss自定义脚本转换生成的文件内容结构为如下:stepbystep转换二:语法层面——htmllangVue文件的转换过程中有很多lang="pug"模板,可以通过工具https://pughtml转换成"jsx-like"模板。com/想想这个工具,如果找不到,请尝试在Google中使用不同的关键字,而不是手动执行)。//infoor.vue转换前article.modal-wrap(@touchmove.stop.prevent@click.stop='close')section.modalp.more更多精彩内容,就在这里德武Appp.sloganToxicSportsxTrendxGoodThings.enter-btn(@click.stop='enter')进入得物Appaside.close(@click.stop='close')//更多精彩内容,就在得物App

有毒运动x潮流x好物

进入得物App
分步转换三:语法级别——以上脚本生成的文件如className在文件级别进行转换,语法差异需要通过脚本来解决。比如类替换和解析。这里html属性的规则解析比较繁琐。在实施的时候,你会想到哪里会有。很自然地想到vue的源码中肯定有这个规则(框架需要解析原生映射)。修改一下即可,然后做一些定制(业务代码中的模板代码,比如导入样式,脚本自动生成,按需插入)。//foo.vue文件中的写法demo1
demo1
//foo/index中的写法。jsx(在反应中)从'./index.scss'导入样式从'classnames'导入类名...demo1
demo1逐页调试和校对仓库技术选择的区别umi路由规则和自定义第三方组件库如Swiper、postcss-px-to-viewport等,vue版本和react版本有些区别,文档不全,拥抱源码和社区。其中postcss-px-to-viewport在不同的仓库中使用了不同的viewportWidth设置。在转换过程中,针对不同的插件实例处理不同的路径范围,实现最基本的功能:灵敏度(这个跟经验有关)。什么是图书馆定位?成熟度如何?什么应该支持,什么不应该支持?如果自己设计,你会怎么设计(有时候即使文档不全,不看源码也能push出一大堆内容)?我在哪里可以找到解决方案?howtofind在迁移首页的配置过程中,缩小首页的路径范围,隐藏repoA中的访问路径,只显示要迁移的路径,提高搜索效率迁移过程记录(测试数据和路径等,以促进交叉测试和QA回归)覆盖率自测。在一个页面有多个业务逻辑的情况下,以后需要对每条路径进行充分的自测。迁移时设计修改路径和文件结构(重要)2.3.3整合repoA、repoB、repoC重构分支代码repo将B中的页面迁移到repoA,比如使用chore-repoB分支迁移repoC中的页面到repoA,比如使用chore-repoC分支将repoAmaster分支与chore-repoB和chore-repoC合并并解决冲突,合并后的分支记录为chore-repoA-repoB-repoC。此时分支只有V1的代码,各仓库当前版本的迭代功能和上一版本的hotfix还没有合并到分支中。2.3.4集成repoA、repoB、repoC中的迭代分支代码前天下午各仓库迭代功能主版本基本稳定,bug已经收敛。此时可以将各个仓库的本地开发分支feat-foo和feat-bar聚合成一个pre-release-temp分支(master上已经包含hotfix),即pre-release-temp分支为V1。,v2总结,分支的增量commit合并为一次commit,得到V1.,V2.影响的文件变更。人工将这些更改同步到repoAchore-repoA-repoB-repoC分支。2.3.5整合三个仓库业务代码和SSR代码社区C端SSR改造方案确定后,新开A-SSR仓库。用SSRPOC的框架内容初始化A-SSR仓库,然后将repoA中的chore-repoA-repoB-repoC中的代码迁移到这个仓库中。遇到的问题:POC中对原repoA中的部分模块做了SSR转换,将新代码迁移到仓库中。请注意,文件覆盖代码丢失了。使用cp然后gitdiff和手动检查提交具有多个源更改的文件。发布后近1天+各仓库产生的bugfix会同步到A-SSR仓库,保证代码不丢失。3.项目推进的外部协作3.1测试大规模重构,需要保证足够的测试。考虑占用测试资源,尽可能提前与测试负责人沟通资源需求。此外,在移动测试之前,尽量在前端内部进行全面自测。3.2运维提前规划页面重定向方案(重定向最终的跨仓库/应用迁移页面),关注变更对运维端的影响。一旦进行更改,相关的将无法在相应的测试环境中使用(QA回归需要时间,在此期间重定向将影响相应页面在该环境中的使用(如果启用)。3.3遇到的问题在计划和开始重构时,团队中没有人对涉及的所有三个C端存储库都足够熟悉。迁移到第二个页面时,发现有死码页面,没有在线流量,我们重新与客户和运维同事沟通,最后通过查询阿里云sls日志,缩小了迁移范围,减少工作量减少近一半。过程中遇到的各种技术问题还是需要平时多积累。4.总结复杂项目的改造对研发基础、经验、规范以及各方的配合都有一定的要求。一开始可以多看几遍《重构》打好基础,然后逐步开始重构代码模块、简单项目、复杂项目、跨团队复杂项目等,积累经验。提前做好规划(技术方面的总体规划、技术疑难病种的超前预测、整体推进方案、相关方的参与等),过程中综合考虑、周密考虑,不断回顾调整,做出过程后总结。提前设计、定期CodeReview、过程中和过程后持续重构,可以让项目代码更易于维护。团队在保持重构习惯的同时不断积累重构经验,可以提高项目的整体性能。健康和可维护性。重构可见提升是关键,在重构中成长,在重构中受益,在重构中受益。相关链接:https://pughtml.com/*文/石飞关注得物科技,做最时尚的科技人!