框架之外( Beyond Framework )
随着前端的快速发展,从原来的简单交互到jQuery
, 从 Kissy
, YUI
到 Angular
, React
, Vue
等等。
我也曾想,这些技术的发展,什么是真正的发展?什么只是外表的改变?
关于真正的发展的这个问题,我的答案是:从原始的农耕
-> 到模块化
-> 再到组件化
。组件化无疑是最近最大的进步与发展。
这篇文章,很大程度是 code-review
和理想中的组件化
的延伸。
- 组件化
- 组件化愿景
- 为什么是子集
- 子集不够用怎么办
- 要闹哪样
- 数据绑定
- 数据流的管理
- 技术之外
组件化
拿我熟悉的 Vue 说吧,Vue 的几大特点:
- 组件化
- 模板语法
- 数据流的管理及组件间通讯
- 双向绑定
- Virtual Dom 好,就做那个比较简单,大家也比较熟悉的实验。将他们几个特性写在纸上,然后,一个一个划去,直到剩下最后一个。 (当然,境界要是够高的话,可以做到心中无胜过外在有,开个小玩笑)。
在我看来划去的步骤是:模板语法 -> 数据流管理 -> 双向绑定 -> Virtual Dom,剩下一个组件化留到最后。
组件化愿景
我之前也一直在探索 WebComponents 在实际项目中的应用,曾尝试过私有的组件化标准, 之后又找到了类似的(主要是和我的私有组件化比较类似)、较为成熟的(相比我自己的组件化而言)解决方案: riot, 之后也尝试过 Polymer 方案,再之后,由于 Weex 的使用,不得不上 Vue 组件化。但对 WebComponents 念念不忘。
前几天,和阿里巴巴 赵振宇 老师简单交流了一下,我问了他前端框架的未来选型的这个问题,刚好他再近期也在解决这个问题,他给出了他的解决方案:
在 Vue,React 框架之外,再抽象一层DSL,设计一套基于 WebComponents 子集的技术规范,并在此基础之上,加上足够多的代码约束来满足业务的需要。
(只是原话的大概意思 )
听到他的这种想法之后,我感觉豁然开朗,思维打开了好多。我当初有好多的疑问,也问了赵老师。以下是基于他的想法加我理解的笔记(未必是赵振宇老师真实想法,仅供参考)。
为什么是子集
为什么是 WebComponents 的子集,而非它的超集?
这个,我先插另外一件事,两年前,我向 张鑫旭 老师请教了我关于想增强 alert 方法的想法。下面是他的回复。
alert 的处理我以前也折腾过,后来放弃了,JS的原始API最好不好动的好,也不要在 DOM 原型上扩展事件。
这话结合为什么是子集这个问题?我有了更深的体会。就像之前,我自己在 Date.prototype
去扩展 format
对象一样,但我看到有人评价这种方式很 stupid
的时候,我有点奇怪,郁闷,现在我又明白了些。
子集不够用怎么办
答案是语法约束。
WebComponents
的 Template
不够用怎么办?循环用 Vue 的 v-for
,还是 mustache 的
, 还是 Polymer 的 dom-repeat
?
我的理解是(当然赵振宇老师也有提到过),模板语法无约束,你可以随心所欲用你的模板,jade
, handlerbar
whatever,但是转换后的 AST
( Abstract Syntax Tree
, 抽象语法树) 需要统一。这颗 AST
是创建前端的核心。而这颗 AST
就是所谓的语法约束了,这可能对整个框架和架构的设计者提出了较大的挑战,但对于写业务代码的同学,可能会更灵活。
之后,构建好这颗 AST
后,怎么创建 View
呢?哈,这个就相对比较简单了,你想用 Vue
的解决思路的话,你可以去生成 Vue
可以 render
的函数就行了,你不想用 Vue
, 但想用 Virtual Dom
? 也行啊,你可以按照某个 Virtual Dom
的规范去生成对应的 Grnerator
, 比如: Matt-Esch/virtual-dom。什么?你连 Virtual Dom
都不想用?也行啊!创建 Real Dom
,用 morphdom
优化一下也是个不错的选项。
要闹哪样?
之前跟老师谈看源码的问题,说我看了 Vue
源码,也抽取了 双向绑定
, virtual-dom
等模块,谈到分模块细粒度的问题。确实,双向绑定从 Vue
中单独抽取出来没有多大的意义,必须和框架结合在一起才能发挥它的价值,像virtual-dom
这种粒度的提取可能更有意义,也更有价值,当然,也正因为如此,在 Github 上,virtual-dom
的单独库可能有更多的人愿意去尝试。
老师问了我抽取模块粒度的问题,之后我也问了老师同样的问题。
模板独立抽象之后,如果想双向绑定又该如何实现,数据流的绑定又怎么处理会比较恰当呢?
数据绑定
既然已经独立于框架之外了,那数据绑定该怎么办?老师提供了两种数据绑定方案:
- 页面层级的统一配置管理
- 代码编译期间的预编译处理,将需要绑定的数据在编译期间做特殊的约束处理
优劣简要分析:
- 页面层级的配置,可能会更直观,但配置的管理可能会随着项目的增大而变得困难
- 而编译期间的处理,会有更好的封装性,但在
运行时
的灵活性会有所降低
这块处理会有点麻烦,因为独立于框架之外,又只能是子集,所以,只能说约束,而这个约束的标准,需要兼顾各个前面提到的模板,很考验设计者的宏观统筹能力,该舍的要舍,该留的要留。谁舍谁留,保证满足业务需求的前提下,最好找到各个模板的共同子集,最小化子集。在此之上,各个模板可以有自己的编译期间能力,但运行时能力必须相同。当然,最好,还能让写代码的写得舒服。
数据流的管理
数据流的管理,之前,在我看来,任何框架,包括 React
和 Vue
,可能只需要用 Redux
这套标准就够了。但如果要抽离出来,在框架之外抽象,Redux
可能也会有所限制。怎么办?
老师给出的方案是:通过外部数据流管理器,来管理组件间的数据流。在用 Redux
前后,数据流大概是这样的,这里我借用一下知乎上dbody作者画的两幅图:
但,按老师的思路,数据流可能是这样的:
通过一个数据流管理器,将数据流从一个组件到另一个组件,上一个组件的输出就是下一组件的输入。这种模式,跟消息的订阅发布模式很很大不同,是简单的 Pipe
模式,这种的限制和订阅发布比起来,很大的不足当然是,数据流只能一个一个流下去,也没那么直观?如果把这两种模式结合在一起呢?
这样,有和 Redux
没多大区别了,这块,不是很能理解。有待进一步发掘。
技术之外
技术为业务服务,技术为应用而生。前端技术的快速发展固然是好事,但对于大企业来说,框架的快速变更,可能未必是好事。相反,在企业内部,需要有技术沉淀,业务沉淀。不能因为框架的火爆而选择,需要理性对待。那如何让技术人员聚焦在业务代码就成了大难题。所以,赵振宇老师目前正在攻克的就是这个难题。我也比较感兴趣,也觉得比较有意义。
当然,我依然有自己的疑惑。如何将这种脱离框架型架构,通用化后回馈给开源社区呢?如何给开源社区贡献自己的一份力量?
Comments
Leave a comment