回顾我这三年,都是泡沫

朋友圈

昨天,一个在掘金认识的小伙伴,进入了美团专门做 IDE 的基建组,心底真是替他高兴,这本来就是他应得的。

刚认识的时候还是一个工作一年的小毛孩,整天逮着我问各种问题,模板引擎、Babel、Electron、Jest、Rollup…

虽然没见过面,不知道他长什么样,在我脑海里,他就是两样放着光,对技术充满好奇心、自我驱动力很强小伙子。

我就知道他能成,因为我多少也是这样子的,尽管我现在有些倦怠。

后来,随着工作越来越忙,博客也停更了,我们便很少联系了。

不过,后面我招人,尤其是校招生或者初级开发,我都是按照他这个范本来的。我也时常跟别人提起,我认识北京这样一个小伙子。

也有可能我们这边庙太小了,这样的小伙伴屈指可数。

好奇心和平台一样重要

大部分人智商条件不会有太多的差距,尤其是程序员这个群体,而好奇心可以让你比别人多迈出一步,经过长时间的积累就会拉开很大的差距。

而平台可以让你保持专注,与优秀的人共事,获得更多专业的经验和知识、财富,建立自己的竞争壁垒。




回到正题。

我觉得是时候阶段性地总结和回望回顾我过去这三年,却发现大部分都是泡沫。

2020 年七月,口罩第二年。我选择了跳槽,加入了一家创业公司


跨端开发的泡沫

2020 年,微信小程序已经成为国内重要的流量入口,事实也证明,我们过去几年交付的 C 端项目几乎上都是小程序。更严谨的说,应该是微信小程序,尽管很多巨头都推出了自己的小程序平台,基本上都是陪跑的。


Taro 2.x

进来后接手的第一个项目是原生小程序迁移到 Taro。

那时候,我们的愿景是“一码多端”,期望一套程序能够跑在微信小程序、支付宝小程序等小程序平台、H5、甚至是原生 App。

那时候 Taro 还是 2.x 版本,即通过语法静态编译成各端小程序的源码。

我们迁移花了不少的时间,尽管 Taro 官方提供了自动转换的工具,但是输出的结果是不可靠的,我们仍需要进行全量的回归测试,工作量非常大。 期间我也写了一个自动化代码迁移 CLI 来处理和 Lint 各种自动迁移后的不规范代码。


重构迁移只是前戏。难的让开发者写好 Taro,更难的是写出跨端的 Taro 代码。


我总结过,为什么 Taro(2.x) 这么难用:

  • 很多初级开发者不熟悉 React。在此之前技术栈基本是 Vue
  • 熟悉 React 的却不熟悉 Taro 的各种约束。
  • 即使 Taro 宣称一码多端,你还是需要了解对应平台/端的知识。 即使是小程序端,不同平台的小程序能力和行为都有较大的区别。而 Taro 本身在跨端上并没有提供较好的约束,本身 Bug 也比较多。
  • 如果你有跨端需求,你需要熟知各端的短板,以进行权衡和取舍。强调多端的一致和统一会增加很多复杂度, 对代码的健壮性也是一个比较大的考验。
  • 我们还背着历史包袱。臃肿、不规范、难以维护、全靠猜的代码。


在跨端上,外行人眼里‘一码多端’就是写好一端,其他端不用改就可以直接运行起来,那有那么简单的事情?

每个端都有自己的长板和短板:

短板效应


我们从拆分两个维度来看各端的能力:

维度


放在一个基线上看:

对比

跨端代码写不好,我们不能把锅扔给框架,它仅仅提供了一种通用的解决方案,很多事情还是得我们自己去做。


实际上要开发跨平台的程序,最好的开发路径就是对齐最短的板,这样迁移到其他端就会从而很多,当然代价就是开发者负担会很重:

路径

为了让开发者更好的掌握 Taro, 我编写了详细的 Wiki, 阐述了 React 的各种 trickTaro 如何阉割了 ReactTaro 的原理、开发调试、跨端开发应该遵循的各种规范




Taro 3.0

我们的 Taro 项目在 2020 年底正式在生产使用,而 Taro 3.0 在 2020 年 / 7 月就正式发布了,在次年 5 月,我们决定进行升级。

技术的发展就是这么快,不到 5 个月时间,Taro 2.x 就成为了技术债。

Taro 2.x 官方基本停止了新功能的更新、bug 也不修了,最后我们不得不 Fork Taro 仓库,发布在私有 npm 镜像库中。


Taro 2.x 就是带着镣铐跳舞,实在是太痛苦,我写了一篇文档来历数了它的各种‘罪行’:

  • 2.x 太多条条框框,学习成本高
  • 这是一个假的 React
  • 编译慢
  • 调试也太反人类




Taro 3.x 使用的是动态化的架构,有很多优势:

3.x 架构 和数据流

3.x 架构 和数据流

  • 动态化的架构。给未来远程动态渲染、低代码渲染、使用不同的前端框架(支持 Vue 开发)带来了可能
  • 不同端视图渲染方式差异更小,更通用,跨端兼容性更好。
  • 2.x 有非常多的条条框框,需要遵循非常多的规范才能写出兼容多端的代码。3.x 使用标准 React 进行开发,有更好的开发体验、更低的学习成本、更灵活的代码组织。
  • 可以复用 Web 开发生态。


使用类似架构的还有 Remax、Alita、Kbone, 我之前写过一篇文章实现的细节 自己写个 React 渲染器: 以 Remax 为例(用 React 写小程序)


而 Taro 不过是新增了一个中间层:BOM/DOM,这使得 Taro 不再直接耦合 React, 可以使用任意一种视图框架开发,可以使用 Vue、preact、甚至是 jQuery, 让 Web 生态的复用成为可能。


升级 3.x 我同样通过编写自动化升级脚本的形式来进行,这里记录了整个迁移的过程。






重构了再重构

我在 2B or not 2B: 多业态下的前端大泥球 讲述过我们面临的困境。

21 年底,随着后端开启全面的 DDD 重构(推翻现有的业务,重新梳理,在 DDD 的指导下重新设计和开发),我们也对 C 端进行了大规模的重构,企图摆脱历史债务,提高后续项目的交付效率


C 端架构

上图是重构后的结果,具体过程限于篇幅就不展开了:


  • 基础库:我们将所有业务无关的代码重新进行了设计和包装。
    • 组件库:符合 UI 规范的组件库,我们在这里也进行了一些平台差异的抹平
    • api: Taro API 的二次封装,抹平一些平台差异
    • utils: 工具函数库
    • rich-html、echart:富文本、图表封装
    • router:路由导航库,类型安全、支持路由拦截、支持命名导航、简化导航方法…
  • 模块化:我们升级到 Taro 3.x 之后,代码的组织不再受限于分包和小程序的约束。我们将本来单体的小程序进行了模块的拆分,即 monorepo 化。按照业务的边界和职责拆分各种 SDK
  • 方案:一些长期积累开发痛点解决方案,比如解决分包问题的静态资源提取方案、解决页面分享的跳板页方案。
  • 规范和指导实现。指导如何开发 SDK、编写跨平台/易扩展的应用等等


巨头逐鹿的小程序平台,基本上是微信小程序一家独大

跨端框架,淘汰下来,站稳脚跟的也只有 taro 和 uniapp

时至今日,我们吹嘘许久的“一码多端”实际上并没有实现;






大而全 2B 业务的泡沫

其实比一码多端更离谱的事情是“一码多业态”。

所谓一码多业态指的是一套代码适配多个行业,我在 2B or not 2B: 多业态下的前端大泥球 中已经进行了深入的探讨。

这是我过去三年经历的最大的泡沫,又称屎山历险记。不要过度追求复用,永远不要企图做一个大而全的 2B 产品




低代码的泡沫

2021 年,低代码正火,受到的资本市场的热捧。

广义的低代码就是一个大箩筐,什么都可以往里装,比如商城装修、海报绘制、智能表格、AI 生成代码、可视化搭建、审核流程编排…

很多人都在蹭热点,只要能粘上一点边的,都会包装自己是低代码,包括我们。在对外宣称我们有低代码的时候,我们并没有实际的产品。现在 AI 热潮类似,多少声称自己有大模型的企业是在裸泳呢?


我们是 2B 赛道,前期项目交付是靠人去堆的,效率低、成本高,软件的复利几乎不存在。

低代码之风吹起,我们也期望它能破解我们面临的外包难题(我们自己都在质疑这种软件交付方式和外包到底有什么区别)。

也有可能是为了追逐资本热潮,我们也规划做自己的 PaaS、aPaaS、iPaaS… 各种 “aaS”。

但是我们都没做成,规划和折腾了几个月,后面不了了之,请来的大神也送回去了。


在我看来,我们那时候可能是钱多的慌。但并没有做低代码的相关条件,缺少必要的技术积累和资源。就算缩小范围,做垂直领域的低代码,我们对领域的认知和积累还是非常匮乏。


在这期间, 我做了很多调研,也单枪匹马撸了个 “前端可视化搭建平台”:

低代码平台

由于各种原因, 这个项目停止了开发。如今社区上也有若干个优秀的开源替代物,比如阿里的低代码引擎、网易云的 Tango、华为云的 TinyEngine。如果当年坚持开发下去,说不定今天也小有成就了。


不管经过这次的折腾,我越坚信,低代码目前还不具备取代专业编程的能力。我在《前端如何破解 CRUD 的循环》也阐述过相关的观点。

大型项目的规模之大、复杂度之深、迭代的周期之长,使用低代码无疑是搬石头砸自己的脚。简单预想一下后期的重构和升级就知道了。


低代码的位置

低代码是无代码和专业编码之间的中间形态,但这个中间点并不好把握。比如,如果倾向专业编码,抽象级别很低,虽然变得更加灵活,但是却丧失了易用性,最终还是会变成专业开发者的玩具。

找对场景,它就是一把利器。不要期望它能 100% 覆盖专业编码,降低预期,覆盖 10%?20%?再到 30%? 已经是一个不错的成就。

低代码真正可以提效不仅在于它的形式(可视化),更在于它的生态。以前端界面搭建为例,背后开箱即用的组件、素材、模板、应用,才是它的快捷之道。

在我看来,低代码实际上并不是一个新技术,近年来火爆,更像是为了迎合资本的炒作而稍微具象化的概念。

而今天,真正的’降本增效‘的大刀砍下来,又有多少’降本增效‘的低代码活下来了呢?






质量管理的泡沫

2021 年四月,我开始优化前端开发质量管理,设计的开发流程如下:

流程

开发环境:

  • 即时反馈:通过 IDE 或者构建程序即时对问题进行反馈。
  • 入库前检查:这里可以对变动的源代码进行统一格式化,代码规范检查、单元测试。如果检查失败则无法提交。

集成环境:

  • 服务端检查:聪明的开发者可能绕过开发环境本地检查,在集成环境我们可以利用 Gerrit + Jenkins 来执行检查。如果验证失败,该提交会被拒绝入库。
  • CodeReview:CodeReview 是最后一道防线,主要用于验证机器无法检验的设计问题。
  • 自动化部署:只有服务端检查和 CodeReview 都通过才能提交到仓库
    • 测试环境:即时部署,关闭安全检查、开启调试方便诊断问题
    • 生产环境:授权部署

生产环境:

前端应用在客户端中运行,我们通常需要通过各种手段来监控和上报应用的状态,以便更快地定位和解决客户问题。




原则一:我认为“自动化才是秩序”:

文档通常都会被束之高阁,因此单靠文档很难形成约束力。尤其在迭代频繁、人员构造不稳定的情况。规范自动化、配合有效的管理才是行之有效的解决办法。

  • 规范自动化。能够交给机器去执行的,都应该交给机器去处理, 最大程度降低开发者的心智负担、犯错率。可以分为以下几个方面:
    • 语言层面:类型检查,比如 Typescript。严格的 Typescript 可以让开发者少犯很多错误。智能提示对开发效率也有很大提升。
    • 风格层面:统一的代码格式化风格。例如 Prettier
    • 规范层面:一些代码规范、最佳实践、反模式。可以遵循社区的流行规范, 例如 JavaScript Standard
    • 架构层面:项目的组织、设计、关联、流程。可以通过脚手架、规范文档、自定义 ESLint 规则。
  • 管理和文化: 机器还是有局限性,更深层次的检查还是需要人工进行。比如单元测试、CodeReview。这往往需要管理来驱动、团队文化来支撑。这是我们后面需要走的路。




原则二:不要造轮子

我们不打算造轮子,建立自己的代码规范。社区上有很多流行的方案,它们是集体智慧的结晶,也最能体现行业的最佳实践:

社区规范

没必要自己去定义规则,因为最终它都会被废弃,我们根本没有那么多精力去维护。




实现

企业通知 Code Review

企业通知 Code Review




我们这套代码质量管理体系,主要基于以下技术来实现:

  • Jenkins: 运行代码检查、构建、通知等任务
  • Gerrit:以 Commit 为粒度的 CodeReview 工具
  • wkfe-standard: 我们自己实现渐进式代码检查 CLI




如果你想了解这方面的细节,可以查看以下文档:


我推崇的自动化就是秩序目的就是让机器来取代人对代码进行检查。然而它只是仅仅保证底线。

人工 CodeReview 的重要性不能被忽略,毕竟很多事情机器是做不了的。

为了推行 CodeReview,我们曾自上而下推行了 CCC(简洁代码认证) 运动,开发者可以提交代码让专家团队来 Code Review,一共三轮,全部通过可以获得证书,该证书可以成为绩效和晋升的加分项;除此之外还有代码规范考试…

然而,这场运动仅仅持续了几个月,随着公司组织架构的优化、这些事情就不再被重视。

不管是多么完善的规范、工作流,人才是最重要的一环,到最后其实是人的管理




DDD / 中台的泡沫

近年来,后端微服务、中台化等概念火热,DDD 也随之而起。

Untitled

上图的 DDD Google 趋势图,一定程度可以反映国内 DDD 热度的现实情况:

  • 在 14 年左右,微服务的概念开始被各方关注,我们可以看到这年 DDD 的搜索热度有明显的上升趋势
  • 2015 年,马某带领阿里巴巴集团的高管,去芬兰的赫尔辛基对一家名叫 supercell 的游戏公司进行商务拜访,中台之风随着而起,接下来的一两年里,DDD 的搜索热度达到了顶峰。
  • 2021 ~ 2022 年,口罩期间,很多公司业务几乎停摆,这是一个’内修‘的好时机。很多公司在这个阶段进行了业务的 DDD 重构,比较典型的代表是去哪儿业务瘦身 42%+效率提升 50% :去哪儿网业务重构 DDD 落地实践)。


上文提到,我们在 2021 年底也进行了一次轰轰烈烈的 DDD 重构战役,完全推翻现有的项目,重新梳理业务、重新设计、重新编码。

重构需要投入了大量的资源,基本公司 1 / 3 的研发资源都投入在里面了,这还不包括前期 DDD 的各种预研和培训成本。

在现在看来,这些举措都是非常激进的。而价值呢?现在还不’好说‘(很难量化)




DDD 落地难

其实既然开始了 DDD 重构, 就说明我们已经知道 ’怎么做 DDD‘ 了,在重构之前,我们已经有了接近一年的各种学习和铺垫,且在部分中台项目进行了实践。

但我至今还是觉得 DDD 很难落地,且不说它有较高的学习成本,就算是已落地的项目我们都很难保证它的连续性(坚持并贯彻初衷、规范、流程),烂尾的概率比较高。

为了降低开发者对 DDD 的上手门槛,我们也进行了一些探索。




低代码 + DDD?

可视化领域建模

可视化领域建模

2022 下半年,我们开始了 ’DDD 可视化建模‘ 的探索之路,如上图所示。

这个平台的核心理念和方法论来源于我们过去几年对 DDD 的实践经验,涵盖了需求资料的管理、产品愿景的说明、统一语言、业务流程图、领域模型/查询模型/领域服务的绘制(基于 CQRS),数据建模(ER)、对象结构映射(Mapper)等多种功能,覆盖了 DDD 的整个研发流程。

同时它也是一个知识管理平台,我们希望在这里聚合业务开发所需要的各种知识,包括原始需求资料、统一语言、领域知识、领域建模的结果。让项目的二开、新团队成员可以更快地入手。

最终,建模的结果通过“代码生成器”生成代码,真正实现领域驱动设计,而设计驱动编码。

很快我们会完全开源这套工具,可以关注我的后续文章。




DDD 泡沫

即使我们有’低代码‘工具 + 代码自动生成的加持,实现了领域驱动设计、设计驱动编码,结果依旧是虎头蛇尾,阻止不了 DDD 泡沫的破裂。


我也思考了很多原因,为什么我们没有’成功‘?


  • DDD 难?学习曲线高
  • 参与的人数少,DDD 受限在后端开发圈子里面,其他角色很少参与进来,违背了 DDD 的初衷
  • 重术而轻道。DDD 涵括了战略设计和战术设计,如果战略设计是’道‘、战术设计就是’术‘,大部分开发者仅仅着眼于术,具体来说他们更关注编码,思维并没有转变,传统数据建模思维根深蒂固
  • 中台的倒台,热潮的退去

扩展阅读:




一些零碎的事

过去三年还做了不少事情,限于篇幅,就不展开了:




过去三年经历时间轴:

  • 2020 年 7 月,换了公司,开始接手真正迁移中的 Taro 项目
  • 2020 年 10 月,Taro 2.x 小程序正式上线
  • 2020 年 10 月 ~ 11 月 优化代码质量管理体系,引入开发规范、Gerrit Code Review 流程
  • 2020 年 12 月 ~ 2021 年 4 月,业务开发
  • 2021 年 1 月 博客停更
  • 2021 年 5 月 Taro 3.x 升级
  • 2021 年 7 月 ~ 10 月 前端低代码平台开发
  • 2021 年 11 月 ~ 2022 年 5 月, DDD 大规模重构,C 端项目重构、国际化改造
  • 2022 年 6 月 ~ 2022 年 11 月,B 端技术升级,涉及容器化改造、微前端升级、组件库开发等
  • 2022 年 12 月~ 2023 年 4 月,可视化 DDD 开发平台开发
  • 2023 年 5 月 ~ 至今。业务开发,重新开始博客更新






总结

我们都有美好的愿望

重构了又重构,技术的债务还是高城不下

推翻了再推翻,我们竟然是为了‘复用’?

降本增效的大刀砍来

泡沫破碎,回归到了现实

潮水退去,剩下一些裸泳的人

我又走到了人生的十字路口,继续苟着,还是换个方向?