简而言之:我们使用React.js、Flux以及一些其他的代码库重新打造了HipChat的Web客户端。我们感觉棒极了!你为什么不也试试看?
HipChat 加入Atlassian 时, 有四个客户端: Web、Adobe Air (Windows,OS X 和Linux)、iOS以及Androidapp。HipChat 团队起初的目标是以OS X、Windows以及Linux的原生桌面客户端替换Air客户端。这使我们当时很忙的小团队,因为专注于提供一流的应用体验,我们的web客户端没有在我们在其他地方所做的更新上获益。这很糟糕,我们正在解决这个问题。
我一直试图改善web客户端,甚至有可能重写它,这并不是一个容易的决定,但是HipChat web客户端急需全面改善。如果我们提供一个更好的web客户端,我们需要询问用户为什么下载原生桌面客户端。
快进
Bob Bergman、Clifton Hensley和我做了研究,拿出了一个合理的重写计划,以及要使用什么技术等。如果现有的app能够继续运行和维护,大多数产品或开发经理都更倾向于放弃重写app的计划。
不过,我们很幸运。我们最初的目标很简单——我们需要在web客户端上应用Atlassian设计指南( 又名ADG),在HipChat上应用ADG将其用户界面和其他Atlassian应用软件的用户界面相统一。
其本身的目的本应该很简单,但是实施过程中可能会涉及到很多错误(因为没有任何测试代码),而且会涉及繁复的jQuery编写。这不是好玩的事情。因为实际上这可能使现有的web客户端变得更糟,而不是更好,我们获得授权进行重写。我们考察了各种新的流行JS框架:Angular, Ember,以及尝试了一些其他的迷你框架……最后我们遇上了React 。剩下的就是历史了。
选择React.js
起初很难理解React的好处,因为它不擅长自我销售。它被标榜为视图库,而不是框架。一年前Ember和Angular的人气是不可忽略的。过去我构建了几个Angular 应用,包括几个Atlassian附加组件,例如REST API浏览器。Bob使用Angular开发了HipChat视频聊天功能。Clifton对Ember有一定经验。
我们都知道你使用这些框架(如2路数据绑定、MVC、测试等)的大益处。所有这些会让我们更加难以客观看待React 。 我们花了好几天用各种技术做出新的HipChat客户端原型。他们各自都有一些长处,但是我们接触其React 时,我们为什么要在写一个HipChat web客户端上使用它就会变得很清楚:
l 基于组件-这意味着我们可以构建可重用的组件,该可重用的组件可使我们与原生客户端分享代码。
l 描述性-就像其他基于组件的架构,React是描述性的。但是不像其他基于组建的框架那么雄心勃勃,React现在就可以开始实际应用到开发中了(我正盯着你的web组件呢)。
l 虚拟DOM –这可能就是为什么很多开发者都对React.这么感兴趣的原因。React管理自己内存中的DOM。大多数webapp上最昂贵的操作是使DOM产生突变。React的方法是维持DOM的视觉表现,通过该DOM的视觉表现可计算出DOM内的区别,这样就只需要更新正真需要更新的DOM部分。这真的很好!
l 很小,但它只是资源库,不是一个框架- 由于用JS框架工作过几年,我们都知道框架通常会软体臃肿,你必须加入一些你不需要的东西。这在服务器端是可以的,但是对于web app就很不好。
l 简单-作为工程师,我们都尽量遵循简单原则。但是很多时候,我们所使用的工具使我们不能遵循该原则。React非常简单。公共API可在一天内就记住,一旦你建立了你的第一个组件,就很容易建立下一个组件,在该组件能使用方面你会很有信心。
l 侧重于单向流- 双向数据绑定出现时真的很棒。早在Backbone的时代,我们很多人都习惯编写大量样板代码来更新我们app的数据。双向数据绑定就将这些都简化了。但是,双向数据绑定也有些缺点-主要是,你不知道你的数据是如何更新的,跟魔术一样。React的方法支持双向数据绑定,但是并不鼓励大家使用。Flux和React的应用软件侧重于单向数据流,有助于数据流动时的不变性。这样的好处就是你知道你的数据在哪里突变,这样更容易进行测试,维护你的app。
l 可测性- React组件大大简化了测试。由于它很简单,我们的新web客户端比起我们其他客户端有更多测试。
最后,React的最大好处归纳起来就是:
@H_404_64@描述性→预测性→信心*React有描述性本质是系统行为变得可预测,因此提高了我们队实现app的信心。React的创造者Pete Hunt在JSConf视频中对其做了精彩介绍,视频地址:https://www.youtube.com/embed/x7cQ3mrcKaY
Flux
Flux是React 应用程序的Facebook模式。该应用程序侧重于单项数据流。Flux的基本思路是一切都朝一个方向发生。操作结果就是数据会流入。该操作触发要跟新的存储器(数据模型),然后会触发更改事件,导致更新React视图,如有需要。这个周期在整个app中不断重复。
宣布Flux时,Flux只是一种模式。Facebook并没有发布资源库。我们为我们的新web客户端采用了该模式。但是,由于我们是从头开始构建Flux资源库,我们做了些设计上的权衡。例如,Facebook的Flux严格恪守调度程序有以下特征:
/** * Dispatcher is used to broadcast payloads to registered * callbacks. This is different from generic pub-sub systems in * two ways: * * 1) Callbacks are not subscribed to particular events. * Every payload is dispatched to every registered callback. * 2) Callbacks can be deferred in whole or part until other * callbacks have been executed. **/
然而,我们的调度程序在在实现中有些变动。我们将它视为通用的时间订阅发布器。例如,我们的调度程序会允许我们在回调过程中调度事件。这一问题在于,我们的调度程序会允许我们调度任何Flux流以外的事件,这很容易偏离Flux模式。我们希望通过强化调度程序的职责来修复这一问题。由于有所述的情况,我们剩下的新web客户端几乎都是使用标准的Flux组件,遵循操作,调度程序,存储的模式。
即使有这样小偏差,新web客户端的代码库已经非常平易近人。Atlassian其他团队的开发人员,在从来没有用过React/Flux的基础上,对HipChat web app贡献了不少带吗,这就是很好的证明。加入我们团队的新程序员通常可以在第二天就能完成并部署第一个新功能。
可重用组件和混合app
对于新web客户端,我们的一个侧目标就是构建我们其他客户端可以重用的组件——以及其他Atlassian产品可能重用的组件。使用React,就可能构建可在不同客户端、web或本机上运行的组件。例如,我们的原生桌面客户端已经使用web视图来渲染聊天版面。
目前,我们正在将基于React聊天界面应用到桌面客户端。这意味着所有管理信息渲染、获取记录、用户状态(如:输入信息等)、滚动动画、状态管理的复杂程序逻辑都会由React处理——这大大简化了我们原生客户端的代码。
未来,我们很乐意看到我们其他Atlassian app共享React组件。例如,如果我们能够把HipChat的@提醒或表情符号自动完成组件运用到JIRA、Confluence、Stash和Bitbucket上会怎样?
在React.js CONF2015上,Facebook的React团队经理TomOcchino在React.js Conf介绍了ReactNative。不久,我们就能用React构建真正的原生组件了!
我们才刚刚开始为HipChat构建和使用可重用组件。我可以看到未来,我们所有的新应用(web或原生)都是由不同Atlassian应用程序提供的新的和现有的组件组合。有太多的可能性值得我们期待!
目前的状况
新HipChat客户端还没有完全完成。有些功能还不完善,但是它会日益接近我们其他客户端的特征。展望未来,我们计划将新web客户端作为我们的参考客户端。
通过React+Flux(及其朋友:gulp、webpack、lodash和karma)获得的开发速度,我们可以自信地说,比起任何原生本地客户端,在这个平台上我们可以更快地发布新客户端功能。
这几个月Atlassian内部员工已经在使用新的web客户端,且陆续将其发布给新的现有客户。世界上其他地方不久也会有机会接触到它,但是如果你有兴趣尝试一下,去试试吧……
试用地址:http://mall.csdn.net/product/829
原文地址:https://developer.atlassian.com/blog/2015/02/rebuilding-hipchat-with-react/