前端架构存在吗?
作为前端开发人员,您是否曾被问过:“前端开发是否有架构?”
询问你的人可能是你的老板或上级,后端同事或另一个前端开发人员;他们的目的可能是挑战你,嘲笑你或寻求建议。
前端开发
众所周知,前端开发所依赖的核心技术是HTML,CSS和JavaScript,它们就像好朋友一样密不可分,我们亲切地称它们为“三剑客”。
近二十年来,尤其是 V8 引擎、Node.js 的出现,基于“三剑客”衍生的技术如雨后春笋般涌现,让前端及其相关社区、前端工程师这个职业得到了前所未有的发展,甚至让很多人认为,前端工程师不仅可以开发 Web 前端,还可以编写后端代码,取代客户端工程师,前端技术将一统天下!
工作内容
除了网页,前端技术还可以应用到命令行工具、客户端应用、服务端应用、聊天机器人、网络爬虫、物联网等场景,只要想象力够丰富,场景是无限的。
然而广大前端工程师在工作中是否都遇到过这些情况呢?
想象一下你自己的职业生涯——它会是这样的吗?
在一个少于 150 人的创业公司,业务可能还在探索阶段,需要不断快速试错,找到一个可以全力以赴的点。这时候前端团队可能只有几个人,可能是三五个人,leader 可能不是顶尖高手,也没有一套方法论来指导团队建设。也许你就是这个团队里最强的。
这个时期需要的是快速迭代、产出成果、验证效果的能力,根本没有时间去思考、规划前端团队的发展方向、基础设施建设,如果你刻意花时间在这些事情上,公司可能会认为你“不专心做主”,KPI 也有可能不及格。
经过一段时间的紧张工作,工程目录和代码提交很可能非常随意,也没有进行代码review,等到有空再回头看,代码乱七八糟的,远谈不上“优雅”。
随着业务的快速发展,项目和应用越来越多,团队规模也越来越大,但规范和基础设施仍然几乎没有,业务线的前端开发者很少会考虑整个团队的工具统一,自己觉得舒服就用,最终导致一个团队使用多个视图层库和组件库,技术栈的衔接非常困难。
最后,当公司业务开始稳定,前端团队发展到二三十人的时候,雄心勃勃、渴望帮助别人的你觉得继续这样野蛮无节制地发展下去肯定行不通。靠增加人力来满足快速发展变化的业务需求,是非常低效和低水平的。必须有技术基础设施来支撑!即使公司不允许你在工作时间做这种对长期有益的事情,你也必须做,哪怕是在业余时间!
在所有的基础架构中,最基础、最直接体现开发效率提升成果的就是高度抽象的UI框架。经过无数个“下班时间”和“周末”的打拼,终于打造出一个能够满足一定业务场景,并在自己负责的几个应用中初见成效的UI框架。
就在你为自己所做的事情取得了预期的收益而欣慰之时,突然有人质疑你所做的事情,而这个人可能是前端团队的某个人。幸运的是,还有其他人认可你所做的事情的价值,并鼓励你继续朝这个方向努力。也许他们是愿意使用它或帮助在部门内推广它的后端开发人员。
你不断为 UI 框架添加新功能,想尽一切办法改造旧系统。在公司业务扩展所需的新应用开发和旧应用的维护中,你所做的确实节省了大量的人力和物力。当新一批后端开发人员加入时,你甚至被邀请去给他们讲课,讲解如何使用你开发的 UI 框架来协助他们的工作。这有力地驳斥了那些怀疑你的人。
后端系统页面常见的模式有列表页、表单页、数据增删改查的详情页,当支撑这些场景的交互和数据处理的核心逻辑被抽象出来之后,你会发现无论你如何完善UI框架,都不会有像以前那么明显的效率提升,最多也就是优化一下交互和开发体验,让功能更加稳定而已。
您在思考:“还能做些什么来继续提高开发效率?”
你之前开发的UI框架对交互逻辑和数据逻辑进行了高度封装,并且提供了大量的CSS类和实用方法,虽然这让你在制作页面时可以少写一些CSS和JavaScript代码,但是却并没有减少HTML代码。
看上去是找到了突破点,但是该怎么做呢?
想来想去,你突然灵光一闪,想起了自己曾经用过的博客系统,用“世界上最好的语言”WordPress 开发的。既然后端系统页面如此模式化,何不学学 WordPress,把不变的部分当成“主题”,变化的部分当成“帖子”呢?
这样做还会带来另外一个好处,就是将页面代码数据化,任何纯前端的问题都可以通过数据修改来解决,而不需要经过漫长而复杂的运维发布流程。未来如果公司有自己的设计语言,并且加入了可视化构建功能,业务后端系统的开发和维护就不需要前端开发人员太多的参与了!
理想情况下,产品经理可以通过拖拽已有素材生成一个“原型”,也就是最终的界面;业务功能确定后,后端开发人员再定义模型、编写界面,然后配置界面的数据展示。这样,整个业务系统迭代过程基本可以忽略前端开发人员的作用。
那么前端开发人员要做什么呢?在这种协作模式下,前端开发人员的主要工作就是完善素材库,让产品经理和后端开发人员使用起来更加方便。这种效率提升方式带来的好处是开发一个 UI 框架无法比拟的,想想就让人兴奋不已!
但理想的丰满并不能掩盖现实的薄弱,听到你想法的人要么带着疑问质问你,要么口头支持你,背地里却嘲讽你——你不去想该如何发展事业,而是满脑子都是一些混乱浮华的东西!
你感到很沮丧,觉得他们目光短浅,看不到本质。但是对于你认为和坚持的“正确”的事情,哪怕没有任何思想和行动上的支持,你也要继续朝着那个方向努力,努力去做!
挣扎了一段时间后,你开始感觉坚持不下去了。一方面,虽然 Node.js 的出现让前端开发人员也能开发后端,但是对数据库等后端开发领域的知识和思维模式还不够了解,导致设计不合理,程序质量很差;另一方面,公司并不指望你花很多时间在短期内不会对业务发展产生重大影响的事情上,而且 KPI 指标也很业务化,考核 KPI 的时候分数肯定会很低。
你也是这家公司的“老员工”,对公司的本质有着深刻的理解。你对自己所相信和坚持的“正确”的东西在这里不被重视,至少在很长一段时间内如此,这令你感到失望甚至绝望。其实你早就有这种感觉,但你不愿面对,总希望自己的信念能或多或少影响组织的认知,但却徒劳无功。
从UI框架到页面数据化,你一直孤军奋战在做这些事情,突然觉得有些难过,最后怀着忐忑的心情离开了,想去大公司看看能不能实现自己的技术理想。
当你真正进入一家大公司,而且是业务部门的时候,你会发现你做的事情和以前没有太大区别,还是以业务为中心。不同的是你身边的领导和同事真诚地认可你的想法,会尽力支持你想做的事情,提供帮助。
你突然意识到,不管是小公司、中型公司、大公司,只要是业务部门,UI 框架、命令行工具基本就是技术所能做到的极限了,要想更进一步,就必须往平台部门走。
提高效率的方法
提高效率这个词之前已经提过很多次了,那到底是什么呢?简单来说就是减少业务需求的开发时间,这是所有开发人员追求的,如果可能的话,应该让需求方自己通过简单的操作就能完成。
那么如何提高效率呢?我能想到的大致有:
这每一个点,如果扩展开来深入研究,都是非常有价值的,需要付出很多的努力,甚至足以变成一个产品或者创办一家公司!
前端架构
在继续之前,我们先简单探讨一下“前端有架构吗?”这个问题。
它有建筑吗?
什么是“架构”?架构是一组抽象的概念,像“人”一样,像“宠物”一样,让你不用关心他是谁,是什么动物;架构是一幅图,让你清晰的了解到不同的东西是如何分类的,它们之间是如何联系的,它们之间是如何协作的;架构是一种指导思想,告诉你什么该做,什么不该做,指导你把代码放到正确的地方;架构是一种方法论,让你知道在什么场景下,应该如何解决什么问题……
引用维基百科——
软件架构是指软件系统的基本结构以及创建此类结构和系统的规则。每个结构都包含软件元素、它们之间的关系以及元素和关系的属性。软件系统的架构是一个比喻,类似于建筑物的结构。它充当系统和开发项目的蓝图,列出了设计团队需要执行的任务。
软件架构基于上述描述,如果前端开发只是一个静态页面,也就是只有 HTML 和 CSS,或者 JS 只是用来添加效果而不操作数据,不进行通信,那么就可以说“前端无架构”。 可是,现在从事前端开发的人,又有多少是做这种工作的呢?
我想,你作为前端开发者的工作不是做页面,而是开发应用吧?那么架构就必不可少了。你可能会想:“我都不知道这个冠冕堂皇的词具体指什么,怎么会有架构?”
你没有意识到,是因为你没有有意识地去思考和进行架构设计。想想看,你不符合以下几种情况:
这两种情况都可以说是用到了分层架构模式,前者是你无意中做的,后者是别人帮你做的。
什么是好的架构?
既然“前端有架构吗?”这个问题的答案是肯定的,那么“什么样的架构才是好的架构?”就成为下一个问题。
在说“什么样的架构才是好的架构”之前,我们先插入另一个问题,有兴趣的话可以思考一下:一个足够复杂的前端框架和浏览器、操作系统有哪些相似之处?
回到正题。我认为一个好的架构应该是这样的——
帮助公司更轻松地赚钱。这是最重要的一点。对于一个公司来说,如果软件不能为自己赚钱,那用它干什么?帮助公司赚钱无非两个方法:“增加收入”和“降低成本”。“增加收入”比较难,需要了解行业、洞察商机,对人本身的素质要求太高;“降低成本”比较简单,减少研发投入,也就是前面说的“提高效率”。
第二重要的就是“稳定性”。一个像样的架构至少应该能够支撑业务发展三五年吧?虽然公司可能活不了那么久。这就要求架构设计要面向未来:一个是业务的未来,一个是技术的未来。面向未来的架构必须具有良好的扩展性,足够灵活,能够应对各种业务场景和突发的业务变化。
以上就是我认为一个好的架构应该具备的两个核心标准,而每个点都会涉及到很多东西,这里就不再多说了。
在设计一个系统的架构时,会用到多种架构模式,比如:分层模式、管道和过滤模式、微内核模式、微服务模式、MVC/MVVM模式等等。在实现时,也会用到各种设计模式、数据结构和算法。
因此需要学习并掌握它们,然后根据(潜在的)业务目标、(潜在的)应用场景选择最合适的进行架构设计和框架实现。
核心原则
做前端架构我觉得应该遵循几个基本原则—
第一是“以不变为本”。
软件开发的本质就是操作数据,在Web开发场景中,后端是存储和获取数据,前端是收集和展示数据。
数据在前后端之间流动的时候,数据的基本形态不会变:基本类型、对象、列表;数据传输协议不会变:HTTP、WebSocket。在前端开发中,越是靠近它们,离GUI越远,就越不容易发生改变。
所以,首先要做的就是理清哪些是不容易改变的,哪些是容易改变的。
第二是“各层均可替换”。
根据可变性,对模块进行梳理,并按照职责进行分层,定义层与层之间的接口协议(接口)。除了自身演进需要外,接口协议基本不会变,也不应该变。在此前提下,当业务需要或者技术升级时,可以替换各层的实现。
第三是“View层尽量薄”。
视图层的职责是展示数据,应该只有交互逻辑,但大多数前端开发者在编写 UI 组件时会混入很多业务逻辑,使得视图层非常厚重臃肿。这样一来,业务逻辑不利于复用,也会增加视图层技术的迁移成本。应该将业务逻辑抽象出来,抽离到领域层,让视图层保持纯粹。
因为视图层多变且多样,而你又希望它尽量的薄,那么最好有办法增加它访问逻辑层的成本,就像前端只能通过网络请求来访问后端一样。
突然想到做业务开发的时候有这种架构,大家有印象吗?没错,就是微信小程序的架构!微信小程序的架构就是将逻辑层和视图层运行在不同的线程中,从而做到了天然的隔离,而它们之间沟通的媒介只有“数据”:

微信小程序是建立在客户端应用提供的一些原生能力基础上的,那么在浏览器端能不能实现相同或类似的效果呢?当然可以!浏览器提供的是原生能力,视图层运行在 iframe 中,逻辑层在 web worker 中:

是不是觉得这跟“微前端”架构很相似——按照我的理解,它简单来说就是一种架构模式,可以让不同技术栈的模块在浏览器中同时运行,它们可以是组件也可以是应用程序,相互之间可以进行通信和协作。
基于这个架构,可以开发类似浏览器或者操作系统的“超级应用”,成为平台级的应用。
如果你在平台部门,以上可能就是你必须面对的。
开源项目
前几天,某厂的前端团队开源了一套组件库,当时我就在想:如果不能比 Ant Design 好,那开源一个组件库还有什么意义呢?
来自蚂蚁金服的 Ant Design,从设计(视觉设计、代码设计、各类设计)到实现,已经非常优秀了,API 设计得很周到,在国内很难找到比它更好的作品。
如果某项视图层技术或者某个端没有对应的实现,那么最好针对该视图层技术或者该端实现一个版本的 Ant Design,而不是从零开始。
我曾经以为,经过几十年的发展,GUI交互的形式已经比较固定,不会有太大的突破,如果已经有了非常优秀的交互模式库,后来者如果没有任何可以与之抗衡的亮点,那么无疑会在竞争中处于劣势。
直到听到叔叔说:
开放的意义不在于代码,而在于你自己对交互的理解,如果你做不到这一点,那么开源一个组件库就没有任何意义。
一开始我不太理解这句话的内涵,后来的日子里时不时地想起来。后来我突然明白了——这就像写文章,对吧?!写文章是为了让别人看你的文字吗?当然不是!是用文字记录和表达你对世界、人、事、物的理解。如果有人写过一篇观点相同或相似的文章,而且写得很好,你就不能写吗?当然不是!
这是正确的。
其实任何创作行为都是一样的,通过一定的渠道表达自己的想法,写作是,编码是,画画是,做饭也是。正如荒木先生在书中所说——

最近,我准备开始一个“大”项目。其实,我已经想了好几年了,只是当时没想清楚具体做什么,但核心思路是一致的——反混沌!我甚至想好了项目名,就叫“反混沌”。
为什么要做这个项目?不就是因为前端圈子太乱了吗?虽然比以前稍微好一点,但是比起 Java 圈子还是乱多了。希望《反乱》能成为盘古之斧,劈开混沌,清则为天,浊则为地。
那么“Anti-chaos”到底要做什么呢?正如前面所说,这是一个“大”项目,因为它基本涵盖了当前前端开发的方方面面。
我并不想开发一个庞大而全面的框架,而是遵循“反混乱”的思路,将其拆分成多个小项目,每个项目解决一个特定的场景问题,它们可以组合、扩展成适合某个团队或企业的解决方案,让前端开发乃至前端圈子更加有序。
我之前也有过类似的想法,想把“前端工程师”这个职业相关的一些事情做得更加规范有序,但是这个东西确实很难操作,比默默写代码难多了,所以目前暂时搁置了。等“反乱象”有了些成果再看要不要重启那个项目。
思考总结
作为一名前端工程师,在业务部你能接触到的技术和视野是有限的,一方面你做业务时不需要用到太前沿的技术;另一方面业务部门的性质不会允许也没有资源让你做太多深入的思考和尝试。
如果你想真正提升自己的技术能力和眼界,最好去平台部!刚开始你可能会觉得很吃力,因为你在改变思维方式去适应环境。等你适应了,你会发现自己思考问题的方式越来越贴近后端,也会觉得做前端也好,做后端也好,需要的知识和能力都差不多,只是要解决的问题不一样而已。
一个人的水平,不是用年龄、岁月来衡量的,而是用他有多少经历、经历了什么来衡量的。
本文主要阐述我近期对前端开发、前端架构、以及开源项目的一些想法和目前的理解,可能并不正确,但却是我现在的看法。
俗话说——
初入禅堂,看山是山,看水是水;悟了禅心,看山不是山,看水不是水;悟透禅心,看山还是山,看水还是水。
就这样。