Closed Tan90Qian closed 5 years ago
同时对于koa、egg这样的node框架,约定式的项目结构并自动装入ctx上下文属性中,我觉得其实会发生一种跟史前前端项目一样的问题:无法在项目编译/启动阶段就将“api不存在”的问题暴露出来,而是要到运行时,触发了对应的api后才会发生报错以致于阻塞后续流程。反而是express这种显式引入资源的模式更稳定一些。而且约定式框架在进行单元测试方面也会因为内部依赖难以mock而比参数依赖注入的模式更麻烦一些。 除了“专注于业务逻辑编写”外,约定式项目结构的核心优势是什么?
我写的 pri 也支持插件拓展约定数据流。这么做的原因是,业务相关数据流建议放到全局管理,此时利用框架自带的数据流即可;通用的组件可以用自己的局部数据流,如果用到 Hooks 配合 useContext 更方便。
v16.9发布前,不管是enzyme
还是test-library/react
的测试工具,都无法正确测试使用了useContext
钩子的组件。这里是当时提的issue。
因为发生了这个问题,导致state与context存在关联的SFC组件无法编写测试用例,因此就基本放弃了hooks的使用。转而采用了现在这种组件内状态外提至mobx,通过工厂函数注入SFC的模式,context仅用于面包屑
等纯UI的动态数据的展示与交互。至于与业务相关联的context则转为通过工厂函数的参数注入
的形式得以使用,而且这种context极为稀少。
在这种数据流模式下,一个组件将store、sfc与factory全部暴露出去,且factory可以选择性的只返回聚合后的实际组件,或者将该组件的store实例一起返回(通过对象的形式),达到更细粒度的且更自由的复用方式。但自由的代价就是,路由的处理会更加麻烦一些,因为factory函数会需要诸如全局store
、父级factory提供的api
等参数,很难以约定式的统一处理。
比如说一个查询列表(表格)页面,从结构上可以分为header的展示区和可能存在的tabs
、body的form
和body的table以及pagination
。
因为antd的通用组件提供了受控与非受控两种使用方式,但通常业务上都会使用受控的形式。那么可以针对tabs、form、table和pagination分别创建对应的通用store与presenter
(当然store与presenter也可以合并成一个),它们基本可以与antd组件的api相对应。然后针对单个页面编写一些业务关联的store与presenter
,比如data和options的loading state
与fetch action
,然后工厂函数中进行聚合,并创建页面对应组件并返回
那么对于多个类似查询列表页,只需要修改变化的部分(如columns的配置、form的配置)等,即可完成一个页面组件的创建。不需要像传统的模式那样,因为交互对数据的影响而把数据全部提升到子组件的公共父组件中。
@Tan90Qian 全局数据流的好处是模型的整体性,甚至可以不依靠 UI 单独完成数据业务逻辑的开发,这样的数据框架对业务代码起到一定约束作用。当然对于较为独立的业务模块,也可以利用 Context 管理自己的局部数据流嵌入到项目中,也能 work 良好,这两者可以配合使用。
@ascoders 传统数据流模式毕竟是经过实践考验的,肯定是有它的优势,这毋庸置疑。
我想表达的只是:我之前列举的这种基于工厂函数的局部数据流方案,与umi这样使用约定式路由
的一站式框架并不契合
。
因为这种模式是非常自由的,也就导致了它跟“约定”天然像违背。它有它自己的约定:组件由工厂函数factory、状态实例store和SFC组合而成,通过在工厂函数内进行逻辑聚合来实现业务组件的实际功能。但这种约定是与路由无关
的,甚至是相背离的。
换言之,一站式框架其实依然有它的局限性,可能它在数据流之外依然存在着其他领域的缺陷。
一站式框架至少有两个目的:
对于第二个目的千人一码
我是认可的,但第一点我觉得有一些问题:
好的开发模式
往往只能在某一类或者几类项目中达到非常好的开发体验,而在其他类型的项目则略显别扭。很难有银弹
级的数据流方案能完美契合所有类型的前端项目。对于通过大版本升级来支持新技术、新特性的方式,如果新特性和已有特性的分歧较大,在框架内部进行兼容处理的成本较大,是否会导致一定版本的迭代之后框架自身的难以维护?
@Tan90Qian 分歧过大就一刀切,不用兼容了,一般不会遇到这种情况。
这时候应该检讨为啥会有这么大的 break change:
在周刊第49篇
精读《Compilers are the New Frameworks》
中提到了UmiJs
等框架是一种自带了约定式路由、数据流的一站式框架,并且说明umi并不限制数据流的选型。 但我的觉得这其实只是针对于传统模式下的数据流设计方案来说,umi并没有进行限制。 假如采用类似于第5篇精读民工叔单页数据流方案
的MVI数据流方案,形成这种形式的组件设计,实现局部(作用范围)的全局(生命周期)数据流模式
,那umi这类框架所实现的约定式路由就无法满足了。 而这种数据流模式能够实现更细粒度的受控组件通用逻辑复用,并满足多组件相关的交互需求,非常适合用于管理后台这种组件复用率高的项目中。