Reactant: 一个渐进式React框架

reactant.png

动机

React是一个用于构建UI的JavaScript库,但当我们要基于React开发应用时,往往要做很多的构建配置和很多其他库的选型(挑选和学习一个React状态库和路由器库等)。我们还需要考虑我们的业务逻辑应该如何抽象和结构化。每个React开发者都在实践着自己对React构建的认知,但这并不能让我们快速关注业务逻辑本身。随着应用业务规模的扩大,我们迫切需要一个易于理解和维护的框架。

而对于应用的业务逻辑结构化设计,关注点分离是个好主意。它要求明确责任边界,避免UI逻辑和业务逻辑混杂时可维护性低。我们在构建应用时,总是要关注业务逻辑。它是一个应用的业务核心价值之一。我们希望它易于维护、测试。Redux仍然是React中最流行的状态库。它完全符合React不可改变的原则。Redux只是一个状态容器,而我们往往不知道如何真正管理这些状态。我们需要一个可扩展、松散耦合、易维护的React应用框架。

React是一个优秀的UI库,但就算React有了hooks,它依然不足以解决我们在开发大型应用中的种种问题。我们依然没有模块依赖注入,我们没有很好的AOP实践模型,我们没有达到很好最小化模块系统抽象的可能,我们也无法更好的实践DDD,等等。这些问题都是React之外,我们需要思考和解决的。

当然,这里我并不是要讨论React是否需要加入这些特性,它已经足够优秀了。这里真正要讨论的是:我们是否需要一个React框架呢?

为了解决这些架构问题,Reactant应运而生 ——— 它是一个React框架。

Reactant简介

Reactant能高效地构建可扩展、可维护的React应用。Reactant基于TypeScript,但它同时支持TypeScript和JavaScript(为了更好的开发体验,推荐使用TypeScript)。Reactant提供了依赖注入、模块化模型、不可变状态管理、模块动态化等功能。它是可插件化、高度可测试的。它不仅能够快速构建React应用(Web和Native Mobile),还带来了一些新的React开发体验。Reactant也保持恰当的灵活性。使用了Reactant,你依然可以拥抱OOP,FP,FRP等编程范式,你依然能够拥抱整个React生态。

Reactant受到Angular不少优秀特性的启发,例如Reactant提供和Angular相类似的依赖注入的API。但Reactant并不是Angular编程思想在React框架上的一次复制,Reactant提供了更少更简洁的API,它足够应付各种开发应用的编程场景。

它是对React的一次完整架构。

解决了什么问题

Reactant是一个渐进式的框架。在开发应用从简单到复杂的过程中,它都能在每个阶段提供适合的feature,基于它的系统架构设计也能进行各种渐进式的平滑升级与演进。

更好的immutable状态管理

React更倡导的immutable状态类型管理,Redux显然符合它。但事实上,类似MobX这样简洁的突变的更新操作越来越符合当下流行的趋势。因此Reactant基于Redux和Immer提供了新的不可变状态管理模型,它融合了MobX相似的API元素,更重要的是它依然保持了状态的不可变性。

@injectable()
class TodoList {
  @state
  list: Todo[] = [];

  @action
  addTodo(text: string) {
    this.list.push({ text, completed: false });
  }
}

模块化

虽然React推出了Hooks后,似乎整个React社区都越来越推崇函数式编程,但是在复杂的企业级业务中,函数式编程未必上最佳的解决方法。当然,如果只在构建UI上,Hooks确实带来很好的渲染逻辑解耦的解决方案。但在业务逻辑领域,我们有更好的选择,尤其在一个企业级应用中的多人协作开发,事实上基于class的模块设计常常带来并行开发和易于维护与测试带来。类并不是有害的,错误的模块设计才是有害的。

因此在Reactant提倡使用class进行模块实现,更重要的是Reactant定义了Service Module, View Module,Plugin Module,使它们更明确职责与边界。任何一个模块都可以是Service Module,它是灵活的,许多不同应用的架构都可以基于它进行;View Module必须定义当前Module绑定的视图组件,它是视图模块的渲染入口,它依赖的模块状态都将通过useConnector进行直观地Props注入;Plugin Module是一个完整的Redux的中间件以及Context的再封装,它提供了一个设计插件的模型,它让插件API简洁无比变得可能。

此外,Reactant提供完整的依赖注入API。基于TypeScript装饰器的metadata来实现的DI,使得使用它变得特别简单。

@injectable()
class AppView extends ViewModule {
  constructor(public counter: Counter) {
    super();
  }

  component() {
    const count = useConnector(() => this.counter.count);
    return (
      <button
        type="button"
        onClick={() => this.counter.increase()}>
        {count}
      </button>
    );
  }
}

简洁和轻量化

Reactant的API不超过30个,核心API更是少于15个。无须过多的熟悉和适应,你就能快速上手Reactant,并用它来开发任何复杂的React应用。

在运行时,Reactant的核心代码gzip压缩小于50KB。Reactant不仅支持代码拆分,它也支持模块动态注入,这非常有利于许多大型应用程序最小化运行。

拥抱React生态

Reactant是开放的,它基于React和Redux的Reactant抽象了一些模型。这些API带给开发者便利的同时,它也支持了React和Redux的生态系统。很多优秀的第三方库能直接在Reactant上使用或者进行再封装,这给Reactant应用带来无限可能。

更好的开发体验

Reactant提供了更简洁的路由模块(reactant-router)和持久化模块(reactant-storage)。如果有必要,你可以基于Reactant插件模块开发出任何你需要更好的模块API。

在开发调试中, devOptions支持autoFreeze和reduxDevTools两个选项。当autoFreeze启用时,任何不在@action装饰过的函数中改变状态的操作都将报错;当reduxDevTools启用时,Reactant将激活对Redux的DevTools的支持。

Reactant还很新,更多的提升开发体验的特性还在进行中。

性能

Reactant和MobX+React的基准性能测试中,Reactant在启动时间和衍生计算上具有优势,而在值的更新上MobX+React更具有优势,总体而言,两者性能差别没有特别明显。因为Reactant基于Immer,因此当遇到极少数极端的性能瓶颈,Reactant也提供的性能优化的解决方案。

Reactant致力于保持良好性能的情况下,持续构建一个具有生产力的React框架。

结论

Reactant的初衷是希望能够帮助React开发者们能进行高效地构建和开发一个可维护、可测试的应用。Reactant的目标就是最小化系统的寿命成本并最大化开发者的生产力。

作为一个全新的框架,Reactant才开发了几个月,还有很多工作需要完成,包括构建工具集,开发工具集,SSR,以及React Native CLI,等等。

如果你已经熟悉React,那么你只需要快速阅读Reactant部分文档后并使用Reactant CLI快速构建Reactant应用,你就可以开启你全新的React应用开发体验。

Repo:

https://github.com/unadlib/reactant

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271