要約 : 私たちは、React.jsFlux、それに他のいくつかのライブラリを用いて HipChat の Web クライアントを根本的に再構築し、素晴らしい結果を得ました! 是非試してみませんか

HipChat がアトラシアンに加わったときのクライアントは、Web、Adobe Air (Windows、OS X、Linux)、iOS、そして Android アプリの 4 つでした。HipChat チームが最初に掲げた目標のひとつが、Air クライアントを OS X、Windows、Linux のネイティブデスクトップクライアントに置き換えることでした。私たちは (その当時は) 小さいチームだったためしばらくはこの仕事で手一杯でした。このように最高のアプリケーションを提供することに集中した影響で、Web クライアントに対しては私たちが行った様々な開発の成果を反映させることができませんでした。これは残念なことであり、私たちはそれを是正しようとしています。

私はこれまでずっと、Web クライアントを改良するべきであり、可能ならば書き直しをするべきだと主張してきました。書き直しするべきだと説得することやそれを意思決定まで進めることは何事でも難しいものですが、特に HipChat の Web クライアントに限って言えば全面的な改良が必要な状況でした。ネイティブデスクトップクライアントと同等以上の性能を持つ Web クライアントを提供できれば、ユーザーにネイティブデスクトップクライアントをダウンロードしてもらう必要もほぼなくなります。

概要

Bob BergmanClifton Hensley、それに私の三人は適切な書き直し計画を立てるために、採用するべき技術などに関して検討を行いました。プロダクトマネージャーや開発マネージャーの多くは、一応動作しておりかつメンテナンスが可能であれば、そのアプリケーションを書き直す計画は拒否しがちです。

ただ、私たちは運に恵まれていました。最初の目標は極めて分かりやすいものだったのです — 即ち私たちはAtlassian Design Guidelines(ADG とも呼ばれます) を Web クライアントに適用する必要があったのです。ADG を HipChat に適用することでそのルック・アンド・フィールをアトラシアンの他のアプリケーションと揃えることができます。これを古い Web クライアントに単に適用することも可能でしたが、(テストがないので) バグだらけになる可能性があり、また jQuery の面倒なプログラミングが大量に必要で、これは誰にとっても厄介な仕事と思われました。このように既存の Web クライアントを改良するどころかかえってそれを拙劣なものにしてしまうリスクがあったために、書き直しを行うという私たちの方針が認められたのです。私たちは、AngularEmber に加えて当社の小規模なライブラリも含めて、新しいものから広く普及しているものまで様々な JS フレームワークを調査した結果、最後に React に注目しました。それは皆様もご存知の通りです。

React.js の選定

React の良さを説明する資料が発行されなかったため、最初はその利点がなかなか分かりませんでした。それはフレームワークではなく、View ライブラリだと説明されていました。1 年前までは Ember や Angular の高い浸透度は無視できませんでした。私自身も過去には、REST API Browserなどアトラシアンで用意しているアドオンをはじめとして、Angular を用いたアプリケーションをいくつも開発してきましたし、Bob は Angular を用いて HipChat の動画を作っており、また Clifton も Ember を使った経験があります。

従って私たちは全員、これらのフレームワークには大きな利点 (双方向データバインディング、MVC、テスティングなど) があることを理解していました。そのため、React に関して客観的に調べることは簡単ではありませんでした。私たちはそれぞれの技術を用いた HipChat クライアントのプロトタイプを数日かけて作ってみました。それらにはすべて何らかの利点がありましたが、React を評価したときに、HipChat の次の Web クライアントにはまさにこれを用いるべきだということが完璧に認識できたのです。その理由は次の通りです :

  • コンポーネントベース- 即ち再利用可能なコンポーネントを開発することができるため、ネイティブクライアントともコードの共有が可能になります。
  • 宣言型- 他のコンポーネントアーキテクチャーと同様に React は宣言型です。ただし、他のコンポーネントベースのライブラリに比べると無駄なところがなく、今すぐ使うことができます (私はまさにWeb Componentsに注目しているところです)。
  • 仮想 DOM- 多くの開発者が React を気に入っている理由がおそらくこの点にあります。React ではメモリーにそれ自身で DOM を持って管理しているのです。多くの Web アプリケーションに対して最も悪影響を与える動作が DOM の変更です。React のアプローチでは、仮想的な DOM を保持することによって DOM の差分の算出が可能となり、その結果、本当に更新が必要な DOM の一部分のみ変更することが可能になります。これは極めて大きな利点なのです!
  • 規模が小さく、フレームワークではない単なるライブラリであること- 私たちは、JS フレームワークを使って何年も仕事をしてきた経験から、フレームワークというものには無駄があり時に不必要なものが入り込む場合があることが分っています。このことはサーバーサイドでは問題にならないかも知れませんが、Web アプリケーションにおいては重大な欠点になると思われます。
  • 簡明さ- 私たちはエンジニアとして、KISS の原則を可能な限り追い求めます。しかし、使用するツールのためにそれが不可能になることがしばしばあります。React は非常に簡明です。公開されている API は一日で覚えることが可能で、最初のコンポーネントを作成できればその次には正しく動作するものを高い信頼度で作ることが簡単にできます。
  • 一方向フローの重視- 双方向データバインディングのアイデアが生まれたときは、素晴らしいものだとの評価でした。Backbone が使われた頃を振り返ると、私たちの多くは、アプリケーションにおけるデータの更新を行うために大量のボイラープレートコードを書き下すことに慣れていました。そして双方向データバインディングによってそれらがすべて単純化されていました。しかし、それには問題点もありました ? 例えばデータがどのように更新されたのか全く認識できないことが大きな問題でした。React では双方向データバインディングもサポートされていますが、しかしそれは非推奨となっています。React のアプリケーションアーキテクチャーである Flux においては、データフローは一方向となっていて、フロー中におけるデータの不変性が重視されています。この方式の利点は、データがどこで変化するかを正確に認識することができるためテストやアプリケーションのメンテナンスが容易になることにあります。
  • テスタビリティー-React のコンポーネントはテストを大幅に簡単化します。その証拠に、私たちが開発した新しい Web クライアントでは、当社の他のどのクライアントよりも多くのテストが行われています。

まとめると、React の最大の利点は次のように表現できます :

宣言型 → 予測可能性 → 信頼性 *

宣言型であるという React の特性によって動作の予測可能性が向上し、開発したアプリケーションの信頼性が高まります。下の JS コンファレンスの動画では React の創始者である Pete Hunt による素晴らしいイントロダクションを視聴することができます :

Flux

Flux は、React アプリケーション向けに Facebook が提供している一方向データフローを重視したパターンです。Flux の基本的アイデアは、すべての事象の発生が一方向であるという点にあります。データのフローはアクションの結果として発生します。アクションはデータストア (データモデル) 更新のトリガーとなり、それが次にチェンジイベント発生のトリガーとなり、必要な場合 React のビューを更新します。アプリケーション全域のどこかでデータの変化が起こるたびにこのサイクルが繰り返されます。

Flux が発表されたとき、それは単なるパターンと説明されていました。Facebook はライブラリのリリースは行っていないのです。私たちはこのパターンを新しい Web クライアントに採用しました。 しかしながら、私たちが Flux ライブラリ開発をゼロから行ったことにより、その仕組みにおいてあるトレードオフを導入せざるを得ませんでした。例えば、Facebook の Flux ではディスパッチャーが以下の性質を有するという考え方が厳密に守られています :

訳 1 /**
2 * ディスパッチャーはペイロードを登録済みコールバックにブロードキャスト
3 * するために使われます。これは二つの点で一般的な pub-sub システム
4 * とは異なります :
5 *
6 * 1) コールバックが特定のイベントを subscribe することはありません。
7 * 各々のペイロードは登録されているすべてのコールバックにディスパッチされます。
8 * 2) コールバックは、他のコールバックが実行されるまで全部またはその一部を
9 * 遅延させることができます。
10 **/

しかし、私たちが開発したディスパッチャーはこれとは少し異なり、一般的な pub ? sub 型 Event Emitter として扱うことができます。そのためこのディスパッチャーでは、例えばコールバック中にもイベントをディスパッチすることも可能です。一方このことによる問題としては、このディスパッチャーでは Flux フロー以外のどんなイベントもディスパッチできるため、Flux のパターンを簡単に逸脱できてしまうことが挙げられます。この点は、できるだけ早くこのディスパッチャーの動作範囲を限定するように修正したいと考えています。そのため、新しい Web クライアントのそれ以外の部分では標準の Flux コンポーネントを使い、Action から Dispatcher そして Store へ遷移するパターンを守るようにしています。

このように違いが少しあるものの、新しい Web クライアントのコードベースは非常に親しみやすいものになっています。その証拠に、私たちはアトラシアンにおける様々な部署から、React/Flux の経験のない開発者によるコード作成支援を受けることができました。未経験の開発者であっても、ほとんどは作業を開始してから二日目には担当した最初の新機能開発に関する作業予定を確約し、それを本番にデプロイすることができていました。

再利用可能なコンポーネントと、アプリケーションのハイブリッド化

新しい Web クライアント開発における私たちの二次的な目標のひとつは、他のクライアントでも、そして望むらくはアトラシアンの他の製品でも再利用可能なコンポーネントの拡充にありました。React を利用すると、Web であるかネイティブであるかを問わず、様々なクライアントで動作するコンポーネントを作ることが可能です。例えば、当社のネイティブなデスクトップクライアントでは、チャットパネルをレンダリングするために WebView を既に利用しています。

私たちは現在、React ベースのチャットパネルをそのネイティブなデスクトップクライアントに適用することを進めています。これは即ち、メッセージレンダリング、履歴取得、ユーザーの状態 (例えばタイピング中など)、アニメーションのスクロール、状態管理などの複雑なロジックをすべて React で扱うことを意味し、これによりネイティブクライアントのコードを大幅に簡略化することができます。

将来的には、React のコンポーネントをアトラシアンの他のアプリケーションと共有できるようになると期待しています。例えば、HipChat の @mention コンポーネントや絵文字用のオートコンプリートコンポーネントを取り出してそれを JIRA、Confluence、Stash、Bitbucket などに適用できるようになると良いと思っています。

React.js コンファレンス 2015 では、Facebook における React チームのマネージャーである Tom Occhinoが React Native の紹介をしています。間もなく React を真にネイティブなコンポーネントの開発に使えるようになることでしょう!

私たちは、HipChat において再利用可能なコンポーネントの開発と利用をまさに始めたばかりです。将来的には、私たちが開発するすべての新たなアプリケーション (Web でもネイティブでも) が、アトラシアンの他のアプリケーション開発時に作られた既存コンポーネントと新規コンポーネントの組み合わせで作られるようになると予測しています。そこには大きな可能性が期待できます!

現状のまとめ

HipChat の新しい Web クライアントはまだ最終的に完成しているわけではありません。まだ実現できていない機能が少しありますが、他のクライアントアプリと同等な機能の実現に向けて日々活動しています。次の段階として、他のクライアントアプリがこの新しい Web クライアントの実装を再利用できるようなものにする予定です。

React+Flux (およびそのファミリー : gulpwebpacklodashkarma) によって迅速な開発ができるようになったおかげで、私たちはこのプラットフォームにおいてはどのネイティブクライアントよりも早くしかも確実にクライアントの新機能をリリースできるようになりました。

私たちは今まで新しい Web クライアントを数か月間アトラシアン内部のみにリリースし、その後、新規および既存ユーザーの一部に対して少しずつリリースしてきました。間もなくすべてのお客様が利用できるようになる予定ですが、試してみたい方は是非下のボタンからどうぞ・・・

本稿は、Atlassian Blogs 日本語版の転載です。本文中の日時などはAtlassian Blogs 英語版での投稿当時のものですのでご了承ください。