AngularとReactのどちらを選びますか? JavaScriptのフレームワーク選びで多くの開発者が悩んでいます。始めたばかりの初心者も、次のプロジェクトで使うフレームワークを検討中のフリーランサーも、企業戦略を立てるITアーキテクトも。そこで、フレームワーク選びの知識を授けましょう。
最初にお伝えします。この記事では、どちらが優れているか明確な結論は出しません。しかし、何百とある似たようなタイトルの記事も同じです。自分の環境と使い方によって多くの要素が絡むため、一概に決まらないのです。
この記事は、Angular(バージョン2以上のこと。古いAngularJSのことではない)とReactを体系的に比較し、違いを理解した上で自身の環境に適したフレームワークを選ぶことを目的とします。「魚を与えず釣り方を教える」わけです。将来、別のフレームワークが登場しても、同じ考えで比較検討できるはずです。
決断のための2つの質問
「このツールは良いものか?」「自分がやりたい用途でちゃんと使えるか?」
ツールを決める前に、この2つの問いに答えてください。ツールを決めるときにも、常にこの2つの質問を意識します。単純に答えられる問いではないので、細かく分けて考えましょう。
ツールを決めるとき考えること:
- 熟成されているか、また開発に携わっている人は誰か?
- どんな機能を持っているか?
- どんな構造、開発パラダイム、設計パターンを採用しているか?
- ツールに関するエコシステムはどんなものか?
自身の環境への問い:
- 自身と自分の同僚が簡単に習得できそうか?
- プロジェクトに合うか?
- 開発者エクスペリエンスは良いか?
上記の質問はどんなツールの評価にも使えるので、ReactとAngularもこの視点で比較します。
ほかにも考えるべきことがあります。厳密に言えば、Angularは多彩な機能を備えた完全なフレームワークです。対してReactは、あくまでもUIのライブラリ―に過ぎません。したがって、AngularとReactを同列に比べるのは適当ではありません。条件を合わせるため、Reactは一緒に利用するライブラリーを含めて比較します。
未成熟なツールのリスク
評価が確立した定番の技術と、新しい技術のバランスをうまくとることが、腕の良い開発者には必要です。成熟していないツールの採用にはリスクがあります。
- バグだらけで不安定な可能性がある
- 提供元が開発を止める可能性がある
- ヘルプが必要なときに、信頼できる情報源やコミュニティが用意されていない可能性がある
React、Angularともに出自がいいので、上記の点は大丈夫だと言えるでしょう。
Reactについて
ReactはFacebookが開発およびメンテナンスをしています。InstagramやWhatsAppをはじめ、FacebookのサービスにもReactが使われています。すでに登場から約3年半が経過していて、新しいツールではないでしょう。またReactは一番活発なプロジェクトの1つで、執筆時点でGitHubには6万個のスターが付いています。これは良いですね。
Angularについて
Angular(バージョン2以上)はReactよりも歴史が浅いものの、以前のバージョンAngularJSを含めれば同じくらい歴史があります。AnglarはGoogleによってメンテナンスされ、AdWordsやGoogle Fiberに使われています。AdwordsはGoogleのキープロジェクトの1つで大きな投資をしているため、当面終了することはないでしょう。
機能と特徴
AngularはReactに比べ最初から多くの機能を備えています。これは長所にも短所にもなります。
両フレームワークにも、コンポーネント、データバインディング、プラットフォームにとらわれない描画の実現など共通した特徴があります。
Angularの機能と特徴
AngularはモダンなWebアプリのための機能を多く標準で備えています。いくつか紹介します。
- 依存性の注入
- 拡張版HTMLによるテンプレート
- @angular/routerによるルーティング
- @angular/httpによるAjaxリクエスト
- @angular/formsによるフォーム作成
- コンポーネントのCSSのカプセル化
- XSS(cross-site scripting)に対する防御
- 単体テストユーティリティ
ライブラリー選びに時間を費やしたくないときには「機能の全部入り」がとても助かります。ただし、不要な機能を排除できないデメリットがあります。代替品を使うと余計な手間がかかります。小規模なプロジェクトならインポートする方が効率的なのに、依存性の注入(DI)をすることで、得られる利点以上に負荷がかかってしまいます。
Reactの機能と特徴
Reactは最小限の状態から開始します。React単体の機能は以下の通りです。
- 依存性の注入は無し
- 典型的なテンプレートではなく、JSXというXML風の拡張版JavaScriptが用意されている
- XSS(cross-site scripting)に対する防御
- 単体テストユーティリティ
それほど多くはないですが、必要なものだけを選んでライブラリーを追加できるため、メリットになることもあります。一方で、自分で選ばなければいけないことが欠点にもなります。そのため、Reactともに使われる定番のライブラリーがいくつか存在します。
- ルーティングにはReact-router
- HTTPリクエストにはFetch(あるいはaxios)
- CSSのカプセル化にはいくつものテクニックがある
- 単体テストユーティリティの強化にはEnzyme
使いたいライブラリーを選ぶ自由は良いと思います。プロジェクトに応じて構成できますし、新しいライブラリーの学習コストもそれほど高いとは思いません。
言語、パラダイム、パターン
機能からはいったん離れて、両フレームワークを支えている高レベルのコンセプトを見てみましょう。
Reactのコンセプト
Reactで外せない重要な概念は、JSX、Flow、Reduxです。
JSXとは
JSXは多くの開発者の間で議論の的です。喜んで受け入れる人もいれば、大きく後退したとみなす人もいます。従来良いとされたマークアップで記述する部分とロジックの部分を分ける方法を捨て、ReactではXML風の言語でJavaScriptの中に直接マークアップを書きます。
マークアップとJavaScriptを混ぜることに議論がありますが、「静的解析」を否定できません。JSXの記述にエラーがあると、コンパイラは継続せずにエラーを発します。打ち間違えをはじめ簡単なミスを発見できるので便利です。
Flowとは
FlowはFacebookが開発したJavaScriptのデータ型チェックツールです。コードを解析し、暗黙のキャストやnullの参照先を取得するなど、型の典型的なエラーをチェックします。
同様の目的で登場したTypeScriptと違ってFlowは新しい言語に移行する必要がなく、静的に型を明示するアノテーションを付ける必要もありません。Flowの場合はアノテーションによる型の明示は必要なく、一方で分析のために付けてもかまいません。これがFlowの良いところで、コードの静的分析をしたいけれどそのために既存コードを書き直したくない、という場合にぴったりです。
[詳細はFlowによる型チェックでJavaScriptのつまらないミスを防ぐ方法を参照ください。]
Reduxとは
Reduxは分かりやすい仕組みで状態(ステート)の変化を管理できるライブラリーです。Fluxの影響で誕生し、より簡素化されています。Reduxのキモは、アプリケーション全体の状態を1つのオブジェクトで表示し、関数「Reducer」で変化させます。Reducerは純粋な関数で、コンポーネント群とは別に実装します。これにより優れた「関心の分離」と、テストのしやすさを実現しています。
単純なプロジェクトなら、Reduxを使うことで複雑になるかもしれませんが、中規模から大規模のプロジェクトには賢い選択です。とても人気があり、Angularに適用しているプロジェクトも多くあります。
これら3つの機能で開発エクスペリエンスが大きく向上するでしょう。JSXとFlowは潜在的エラー箇所を発見しやすく、Reduxはプロジェクトの構造を分かりやすくします。
Angularのコンセプト
Angularも、おもしろい特徴を秘めています。それがTypeScriptとRxJSです。
TypeScriptとは
TypeScriptはMicrosoftが開発した、JavaScriptを拡張した新しい言語です。JavaScript ES2015のスーパーセットで、新しいバージョンのJavaScriptの機能も取り込んでいます。TypeScriptを使えば、Babelを使わなくても最新鋭のJavaScriptが書けます。またTypeScriptは強力な型付けシステムを持ち、型アノテーションと型インターフェイスによりコードの静的分析が可能です。
細かい利点もあります。TypeScriptはJavaと.NETフレームワーク(C#やVB)から大きく影響を受けているため、開発者がこれらの言語を経験していれば、TypeScriptは純粋なJavaScriptよりも学びやすくなっています(かつて環境を移行したときのことを思い出してください)。主要なフレームワークではAngularが初めてTypeScriptを積極的に採用しました。今ではReactでTypeScriptを使用することも可能です。
[詳細はAn Introduction to TypeScript: Static Typing for the Webを参照ください。]
RxJSとは
RxJSは、非同期処理とイベントを柔軟に扱うための「リアクティブプログラミング」を実現するライブラリーです。オブザーバーパターン、イテレータパターン、関数型プログラミングの特徴を融合しています。RxJSイベントなどを連続的なデータストリームとして扱い、それに対してマッピング、フィルタリング、分割、結合などの処理をします。
このライブラリーはAngularのHTTPモジュールおよび一部の内部処理に使われています。HTTPリクエストを実行すると通常のプロミスではなくObservable(観察対象)が返されます。パワフルなライブラリーですが、少々複雑です。さまざまなタイプのObservables/Subjects(観察対象)に馴染む必要があり、さらに百個近いメソッドと演算子を習得する必要があります。HTTPリクエストのためにちょっとやりすぎだと思います。
RxJSはWebSocketをはじめ数多くの継続的なデータストリームを扱う場合に便利ですが、それ以外では複雑すぎるかもしれません。とはいえ、Angularで開発するなら基本的なことは知っておくとよいでしょう。
[詳細はIntroduction to Functional Reactive Programming with RxJSを参照ください。]
TypeScriptは、特にコードベースが大きい場合やドメイン/ビジネスロジックが複雑な場合にメンテナンス性が向上する優れたツールです。TypeScriptで書かれたコードはより明示的で可読性に優れています。TypeScriptはAngularでも採用されたことですし、さらに多くのプロジェクトで採用されるといいですね。RxJSは特定のケースでのみ威力を発揮します。プロジェクトが不必要に複雑になることもあり、採用は慎重にしてください。
エコシステム
オープンソースのフレームワークがすばらしいのは、周辺ツールが数多く揃うことです。ツールがフレームワーク本体よりも役に立つことさえあります。人気のツールと、フレームワークに関連したライブラリーを紹介します。
Angularのエコシステム
Angular CLIとは
フレームワークは、プロジェクトの立ち上げ時にビルドの設定を自力でやらなくて済むようにCLI(コマンドライン)ツールを備える傾向にあります。Angularにも、数行のコマンドからプロジェクトを生成・実行できるAngular CLIがあります。アプリのビルド、開発サーバーの開始、テストの実行などに関わるスクリプトはすべてnode_modulesに隠され、開発者が知る必要はありません。また開発中に新規のコードを生成するのにもCLIを使えます。おかげで新しいプロジェクトのセットアップも楽勝です。
[詳細はThe Ultimate Angular CLI Referenceを参照ください。]
Ionic 2とは
Ionic 2とは、ハイブリッドなモバイルアプリの開発で人気のフレームワークの新バージョンです。Ionic 2は、Angular 2や美しいマテリアルコンポーネントライブラリーに上手く調和したCordovaのコンテナを提供します。モバイルアプリの立ち上げと作成が簡単にできます。ネイティブアプリではなくハイブリッドアプリを作りたい場合には良い選択肢です。
マテリアルデザインコンポーネントとは
マテリアルデザインが好きなら、Angularのマテリアルコンポーネントライブラリーが使えます。現在、初期の段階なので若干のアラはあるものの、多くの貢献者を得て、近いうちにさらに改良が進むと思います。
Angular universalとは
Angular universalはサーバーサイドレンダリングを実現したアプリを作成できます。まだシードプロジェクトの段階です。
@ngrx/store
@ngrx/storeは、Angular用の状態管理ライブラリーで、reducerにより状態を変化させるというReduxの影響を受けています。RxJSとの統合を実現し、状態変化のプッシュ通知を活用すればパフォーマンスを向上できます。
[詳細はManaging State in Angular 2 Apps with ngrx/storeを参照ください。]
ほかにもthe Awesome Angular listには多くのライブラリーやツールが用意されています。
Reactのエコシステム
Create react appとは
Create-react-appはReactで新規プロジェクトを手早くセットアップできるCLIユーティリティです。Angular CLI同様、新規プロジェクトの生成、開発サーバーの開始、バンドルの作成ができます。このツールでは単体テストのために、Facebookが開発した比較的新しいテストランナーJestを採用しており、優れた特徴を備えています。さらに環境変数、ローカル開発環境用のバックエンドプロクシ、Flow、そのほかの機能のおかげで、柔軟なアプリプロファイルに対応しています。詳しくはcreate-react-app入門を参照してください。
React Nativeとは
React NativeはFacebookが開発した、Reactでネイティブモバイルアプリを作成するためのプラットフォームです。ハイブリッドアプリを作成するIonicとは異なり、ネイティブアプリを作成します。React Nativeでは、標準のReactコンポーネントをネイティブアプリのUIパーツとして利用できます。コンポーネントを作成して、Objective-C、Java、Swiftで書かれたネイティブコードにバインドもできます。
マテリアルUIとは
Reactでもマテリアルデザインコンポーネントのライブラリーが使えます。Angular版と比べてコンポーネントも多く、成熟しています。
Next.jsとは
Next.jsはReactアプリのサーバーサイドレンダリング用フレームワークです。アプリの全部あるいは一部分をサーバーで描画し、処理結果をクライアントに返してブラウザーで表示する仕組みを柔軟に作成できます。ユニバーサルアプリを作成する複雑な手順を可能な限り簡潔にしているため、セットアップでも新規プリミティブ値とプロジェクトへの要求が最小限になるよう設計されています。
MobXとは
MobXも、アプリの状態管理用ライブラリーです。Reduxと異なるのは、状態を変更不能なストレージに保管するのではなく、最小限必要な状態だけを保存して残りは派生させる考え方です。MobXはObservableとObserverを定義する修飾子を用意していて、状態管理のリアクティブロジックを備えています。
[詳細はReactでも使える!シンプルなJavaScriptステート管理ライブラリー Mobxを試すを参照ください。]
Storybookとは
StorybookはReactのためのコンポーネント開発環境です。コンポーネントを閲覧するための別アプリをさっと作成できます。加えて多数のアドオンでコンポーネントのドキュメントの制作、開発、テスト、デザインが可能です。アプリの本体と別にコンポーネントを開発できることはすばらしいと思います。前回の記事を見ればさらにStorybookについて学べます。
the Awesome React listに、ほかのライブラリーやツールがたくさん用意されています。
採用、学習、開発エクスペリエンス
新技術を選ぶときに大切な基準は「どれだけ習得しやすいか」です。経験や関係する技術とパターンの習熟度などによって左右されますが、フレームワークを始めるために新たに学ぶことを検討します。ES6以上、ビルドツールなどを知っている前提で、それ以外になにが必要か解説します。
React
Reactでは、まずJSXが挙げられます。やっかいに思う人もいますが、さほど複雑ではありません。特定のJavaScriptの式と、特殊なHTML風の構文があるだけです。ほかには、コンポーネントの書き方も覚える必要があります。設定用のプロパティで内部の状態を管理します。これは通常のJavaScriptなので、新しいロジックやループの組み方を覚えるわけではありません。
Reactの習得には公式チュートリアルが優れた教材です。チュートリアルが終わったらルーターを理解してください。Reactルーターのバージョン4は少し複雑で風変りかもしれませんが、心配はいりません。Reduxには、慣れたタスクにもライブラリーが推奨する方法を習得するパラダイムシフトが求められます。無料のビデオチュートリアルGetting Started with Reduxでは核となる概念を短時間で紹介しています。取り組んでいるプロジェクトの大きさと複雑さ次第ですが、追加のライブラリーの習得がつらいところかもしれません。これを乗り越えれば順調に進むはずです。
私たちはReactを使い始めてから、その簡単さに驚きました。バックエンドの開発がメインでフロントエンドの経験が浅い開発者でもすぐに慣れました。開発中に遭遇するエラーメッセージは分かりやすく、問題の解決方法を教えてくれます。一番苦労するのは要求事項を満たすライブラリーを見つけることかもしれませんが、アプリケーションの設計・開発は非常にシンプルです。
Angular
Angularは、新しい概念をReactよりも多く学ぶ必要があります。まずはTypeScriptに慣れましょう。Javaや.NETのような静的型付け言語の経験がある開発者にはJavaScriptよりも理解しやすいですが、JavaScript専門の開発者は苦労するでしょう。
Angularには学ぶことがたくさんあります。モジュール、依存性注入、修飾子、コンポーネント、サービス、パイプ、テンプレート、命令文といった基本的なことから、発展的なことでは状態変化の検知、ゾーン、AoT(ahead of time)コンパイル、Rx.jsなどです。詳細はドキュメントに掲載されています。Rx.jsは大きなテーマであり公式サイトで詳しく知ることができます。基本的な機能の利用は比較的やさしい反面、高度な機能ほど複雑になります。
新しい概念が多く、新参者には分かりにくいため、Angularを導入する壁はReactよりも高いと思います。導入後も、Rx.jsのサブスクリプションマネジメント、変更の監視のパフォーマンス、bananas in a box(本当に公式ドキュメントにこう書かれています)などを監視するのはつらいかもしれません。Google検索で見つかることを祈るしかない理解しづらいエラーメッセージにも遭遇しました。
Reactを推しているように感じるかもしれませんが、その通りです。以前、同等のサイズと複雑さのAngularとReactのプロジェクトを新人の開発者に取り組ませたところ、Reactのほうが常に順調に進みました。とはいえ最初に述べたように、さまざまな条件に左右されるので、みなさんのケースでは異なるかもしれません。
状況に応じて使い分ける
気づいていると思いますが、両フレームワークともそれぞれの持ち味があり、長所と短所があります。特定の背景や状況を加味せずに解説したので「どちらを選ぶのか」その答えはありません。自分のプロジェクトに合わせて決めてください。判断するための材料はこちらです。
プロジェクトについて以下の質問に答え、2つのフレームワークの特徴と照らし合わせます。単純ですが、取り掛かりとしては十分です。
- プロジェクトの大きさは?
- どれほどの期間でメンテナンスできるか?
- すべての機能をはじめに定義できるか、それとも柔軟性を持たせるよう要求されているか?
- すべての機能が定義されているなら、どんな機能・能力が必要か?
- ドメインモデルやビジネスロジックは複雑か?
- Webかモバイルかデスクトップか、どのようなプラットフォームがターゲットか?
- サーバーサイドレンダリングが必要か? SEOは重要か?
- リアルタイムイベントを多く扱うか?
- プロジェクトチームの人数は?
- チームの開発者たちの経験値は? どのような経歴なのか?
- そのまますぐに使えるコンポーネントライブラリーはないか?
大きなプロジェクトを開始する際、選択を間違えるリスクを最小限に抑えたいなら、試作品(Proof-of-Concept)を作るのも手です。フレームワークでいくつか鍵となる機能を作ってみるのです。試作品はそれほど時間をかけずに作成しますが、必要なフレームワークの貴重な知見が得られ、技術的な要求も検証できます。結果が満足できるなら本格的な開発に取りかかります。逆にダメでも小さく失敗したことによって長期間悩まずに済むのです。
いつも同じフレームワークを使うべき?
あるプロジェクトのためにフレームワークを選んだら、次のプロジェクトでも同じ技術を使いたい。気持ちはわかりますが、ちょっと待ってください。技術の一貫性を保つのは良いことですが、盲目的に毎回同じ方法を取るのはやめるべきです。プロジェクト開始前に、記事中で述べた質問について考える時間を取ってください。次回のプロジェクトでは別の答えになったり、状況が変化していたりするでしょう。もし小規模なプロジェクトで新技術を試せるならば、ぜひ挑戦してください。実験から得られる経験値は計り知れません。柔軟な心を持ち、失敗から学んでください。どこかでその技術がストンと腑に落ちるはずです。
本記事はJurgen Van de Moere、Joan Yinが査読を担当しています。最高のコンテンツに仕上げるために尽力してくれたSitePointの査読担当者のみなさんに感謝します。
(原文:React vs Angular: An In-depth Comparison)
[翻訳:西尾 健史/編集:Livit]