前端框架工程化之路
人类的发展动力源于一个“懒”字,就如现在的大前端正是史前那群“懒”而聪明的“切图仔”进了软件工程的施工现场,怀揣着更少代码、更少沟通、更少错误、更少维护的梦想奔袭而来。从框架齐放闹革命到三大框架三足鼎立,从构建工具争鸣到Webpack一统江湖,从Javascript 遵循ES5长达7年统治到向ES6的自我进化。前端的发展与它们的成功都离不开一个“术”,工程化。
模块的进化
在没有框架的史前
我们面临的问题:
1.全局变量污染:各个文件的变量都是挂载到window对象上,污染全局变量。
2.变量重名:不同文件中的变量如果重名,后面的会覆盖前面的,造成程序运行错误。
3.文件依赖顺序:多个文件之间存在依赖关系,需要保证一定加载顺序问题严重。
于是老王想出使用自执行函数的方法去解决问题
前端最初始的模块诞生了,这个模块有问题吗!虽然模块内部的变量对全局不可见了,但暴露出来的foo是一个全局变量,这样的模块多了全局变量也会很多。
老李在老王的办法基础上添加命名空间去解决问题:
除了写法丑陋外,这样的模块约束力极低,很容易遭到不遵守的开发者破坏,需要开发者有一定的划分不同模块的能力,更大的问题是需要人为的解决模块加载、初始化等管理问题。
框架加冕时代
2009年横空出世的前端框架Angularjs的模块机制
Angularjs的模块机制相比老王、老李的解决方案上增强了模块的约束性,和帮助开发者划分模块外,最重要的是解决了模块的运行时管理问题(模块的初始化顺序问题和依赖的模块自动初始化问题。再被多个模块依赖的情况,模块仅且只加载一次的问题,统一的输入输出api问题)。看似完美的方案,但仍有问题。
构建工具辅政
不得不改源码的Jquery组件
我们先来看看Jquery的年代组件长什么样以前的代码一般是用自执行函数作为一个类,这里为方便理解,我用TS展示一下。
组件使用者拿到这个组件并初始化,根据组件上层的一些交互,调用组件方法,改动组件内部。 我们可以看到组件上层依赖这个组件,且依赖的是highlight()的具体实现。根据OCP原则,对扩展开放,对修改关闭。当我们需求变化时,比如我们的highlight需要把背景色改一下,只能对组件内部逻辑做修改。很显然这样的组件不是一个好设计。
数据驱动让组件高可用性
进入有前端框架的时代,Angular使用数据驱动改变视图的状态,这是很大的一个进步,数据驱动解耦了组件外层对组件的依赖关系,将真正的依赖抛向外层的传给组件的数据(有点类似依赖倒置的意思),组件内部负责根据数据的变化改变UI状态。(React Virtual DOM 驱动视图实际也是一种数据驱动,只是一个是找到数据最小粒度的变化直接改动对应的视图,一个是数据生成Virtual DOM找到最小粒度的Virtual DOM变化,改动对应的视图。本质上都是数据驱动视图)。
数据驱动视图解耦了组件与组件的依赖问题。但同时引入了一个问题,状态混乱问题。写过Angularjs的同学应该知道状态混乱之痛,当我们在Angularjs的多个组件依赖同一份数据时,当一个组件树中某一个组件将该数据更改时,整颗组件树中使用该数据的组件都会跟着共振。但实际情况是,树当中有一部分组件不需要跟着某一次的数据变化而变化。
这个发展过程实际也是为了解耦合,让组件更加独立,就好似以前一个人的每一个日常活动都推送出去让全人类知道,由于日常太过苦逼影起 会负面情绪暴增,影响太大了(无单向数据流的情况)。于是乎改为在推送前,大家先订阅建立关系,建立关系则推送,大家发现这套太麻烦了,需要个体知道别人关心我哪个日常活动,家人想知道我吃的什么我建立一个晒图发布方式,领导想知道工作情况,我建立一个写周 发布方式,于是乎我不停的改变自己适应 会(这就是一种耦合,单向数据流方式)。当个体丧失人性后,终于想到了一个更好的办法,做自己该做的事,把这种拔内裤的事情交给 会,我在办公室就给我采集认真工作的照片,系统让领导看还是让其它同事看作为个体的我不需关心。我在吃大餐的时候你采集照片,系统要给哪些联系人,这由我此刻处的环境下 会关系决定。这个系统就是状态管理器,这个 会就是组件所处的环境。
框架的出现让组件拥有了其应该有的特性,让开发者无需再重复造轮子解决这些问题。但也引入了新的问题,组件的独立性。
前面提到组件应当是一个独立运行的软件单元。而实际的情况是,组件只是在某框架体系下独立运行的软件单元。而工程化也是一个去底层服务的趋势,我们可以看看近年的Docker技术、云服务的Serverless概念,都强调其无需关注底层执行环境,想象一下如果某天我们开发一个页面无论采用任何技术架构与框架,都只需引入一个个Custom Element,把DOM Attribute作为API(或者拿着各团队发布的在线运行的一个组件地址),去组装页面即可。这就是近几年前端的一个研究课题微前端技术。目前的微前端技术也有不错的发展,利用Custom Element的实现方案,解决了一些基本的问题,如前面提到的:隔离性、状态管理、通讯问题、生命周期问题、不依赖前端架构体系问题。但作为能独立服务端部署提供使用的一个component还有很多问题待解决,但这是一个组件化发展的方向。
这是一个不错的微前端实现方案 https://micro-frontends.org/
那是不是有了规范文档,就好了赶着上线的高压、高疲劳下状态,可能出现这样的同事。
我们前面已经提到过一些古老“法典”,如Jquery时代模块定义的规则、css规范的规则,还有前面没提到的项目结构划分、代码书写规范。 大家有没有发现它们都在历史的舞台中消失或者说们不必在为规范的实现耗费精力。为什么一个“法典”的受管控者和执法者都是自身的时候,那法典也就成了空谈。所以我们需要一个公正的执法者——机器(自动化)。
终会让项目wiki消失的自动化
看似是个大小写问题,但完全是可以避免,如果这个组件是个强类型,IDE(支持ts的)会推断this类型,该字段是否声明过给予校验提示。这个是书写上的带来的好处。强类型还给我们带来很多好处与方便,比如可以很快的了解一个模块提供的API。可以在多模块引用同一个数据时,某个时期对该数据结构进行一定调整后,能立刻知道那些陈旧的代码哪些需要随着这次改动一起调整等等。
除此之外TS还能在自动化文档上起到辅助作用。我们可以看一下Angular的文档自动生成工具有多棒~
https://compodoc.github.io/co…
demo: https://compodoc.github.io/co…
未完待续…
当我们站在巨人的肩膀上时,从未觉得向前走一步是如此轻松…愿,未来的前端走得更轻松。
相关资源:maestro:面向懒惰软件开发人员的智能部署系统-其它代码类资源…
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!