JavaScript: フレームワーク React/Vue/Angularについて

フロントエンドの開発に用いられる人気のフレームワーク(ライブラリ)に、[React](https://reactjs.org/)と[Vue.js](https://jp.vuejs.org/index.html)および[Angular](https://angular.io/)があります。これらフレームワークのフロントエンド開発における役割と、3つの違いについて簡単にご紹介します。

# データバインディングとコンポーネント化
フレームワークReactとVue.jsおよびAngularは、いずれもHTMLの要素(DOM)をデータと関連づけて(データバインディング)、データの変化に応じた動的なページ構成を行います。

DOMの操作には、かつてはjQueryが用いられました(今だに、使われていることは少なくはないでしょう)。けれど、モダンブラウザが対応するECMAScript 2015(ECMAScript 6)以降でしたら、標準JavaScriptでもDOMの操作は難しくありません。

動的にページを構成するコンテンツの典型は、シングルページアプリケーション(SPA)です。jQueryや標準JavaScriptで動的にDOMを組み立てようとすれば、新たなデータを処理したとき、変更すべきDOMの現状を調べたうえで、つぎの状態がどうなればよいか決め、DOM構成をそのとおりに変更するといった流れになるでしょう。データの数が多くなると、構成の組み合わせはさらに増えます。それに伴って高まるのがバグの可能性です。

3つのフレームワークは、DOMをテンプレートで定め、データとバインディングします。そして、データに応じてDOMの構成をどうするかは、テンプレートに書き加えるのです。つまり、DOMの構成がデータの処理から切り離されます。さらに、フレームワークが変更すべきDOMだけを探し、差分をレンダリングすることで、最適化します。

<!--Reactの採り入れた仮想DOM([virtual DOM](https://reactjs.org/docs/faq-internals.html))による構成とデータの処理が切り離されるようになると、アプリケーションの設計については「関心の分離」(separation of concerns)という考え方の議論が進みました。これは、「[プログラムを関心（何をしたいのか）毎に分離された構成要素で構築する](https://ja.wikipedia.org/wiki/関心の分離)」ことです(「[Separation of Concerns in React.](https://medium.com/@alialhaddad/separation-of-concerns-in-react-d4f74aaf3800)」参照)。たとえば、Eコマースサイトなら、ログインして、商品を一覧から選び、ショッピングカートに入れたら、注文の手続きに進むといった目的(関心)ごとにロジック分けします。-->

さらに、アプリケーションの機能は小分けして、それぞれのデータの処理とテンプレートをまとめたものがコンポーネントです。小さなコンポーネントをいくつも組み合わせて、ひとつのシステムがつくられます。コードはコンポーネントごとに確かめればよいので、読みやすく、メンテナンスもしやすくなるのです。


# 3つのフレームワークの特徴
前項では、3つのフレームワークに共通する役割と仕組みについてご説明しました。ここからは、3つの特徴や違いを確かめましょう。以下の表にまとめてみました。わかりやすく比べられるように、細かなことははしょって、大雑把に書いてあるところもありますので、ご了承ください。

|  | React | Vue | Angular |
|:--|:--|:--|:--|
| 開発元 | Facebook + コミュニティ | コミュニティ主体 | Google + コミュニティ |
| 初期リリース年 | [2013/07](https://github.com/facebook/react/releases?after=v0.5.0) | [2013/12](https://github.com/vuejs/vue/releases?after=v0.7.2) | [2010/10](https://github.com/angular/angular.js/releases?after=v0.9.1) (Angular.js) |
| 最新バージョン | [v16.6.3](https://github.com/facebook/react/releases) | [v2.5.21](https://github.com/vuejs/vue/releases) | [7.1.3](https://github.com/angular/angular/releases) |
| 機能 | ユーザーインタフェース | ユーザーインタフェース | フルスタック |
| ルーティング | [React Router](https://reacttraining.com/react-router/) | [Vue Router](https://router.vuejs.org/ja/) | 同梱 |
| 適切な開発規模 | 中〜やや大 | 小〜中 | 大 |
| エコシステム | 豊富 | 少ない + 日本語あり | 多い |
| 学習コスト | 中 | やや低～中 | 高 |
| 構文上の特徴 | [JSX](https://reactjs.org/docs/introducing-jsx.html) | [単一コンポーネントファイル](https://jp.vuejs.org/v2/guide/single-file-components.html#ad) | [TypeScript](https://www.typescriptlang.org/) |

### React
Reactはユーザーインタフェースをつくるためのライブラリです。ルーティングなど他の機能は、別のライブラリで補わなければなりません。そのためのエコシステムは、3つの中ではもっとも豊富です。控えめな規模の開発で採り入れて、あとから拡大していく進め方もできます。仮想DOMが活かされ、機能的にも高い水準です。[React Native](https://facebook.github.io/react-native/)など新たな技術への展開も積極的に進め、スタートが早いとはいえ、バージョンはもう少しでv17になろうとしています。

学習コストはそれほど高くありません。規模を抑えて始めれば、ハードルが下がるでしょう。学習を進めるにあたっても、豊富なエコシステムが大いに役立つはずです。設計やコードの作法はしっかりしつつ、柔軟さもかねそなえます。大規模の開発にも耐え得る堅牢さと厳密さを備え、チーム開発も進めやすいでしょう。少し毛色が変わっているのは、JSXというコードの書き方です。

JSXは、HTMLタグをJavaScriptコードの中にじかに書く構文です。つまり、テンプレートがJavaScriptコードで定められることになります。つぎのコードは、ひな形から引用しました。はじめは違和感があるかもしれません。これは、マークアップとViewのロジックは密であるべきという開発者の考えにもとづいているとのことです(「React.jsのComponentについて」「[Separation of concerns?](https://qiita.com/koba04/items/4f874e0da8ebd7329701#separation-of-concerns)」参照)。

```react
ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('root')
);
```

なお、JSXはVueでも使えます。けれど、Reactでは構文が原則JSXとされているのです。さらに、CSSについてもライブラリを用いてJavaScriptの中に書く「[CSS-in-JS](https://reactjs.org/docs/faq-styling.html#what-is-css-in-js)」というスタイルが提唱されています(「[React: CSS in JS](https://speakerdeck.com/vjeux/react-css-in-js)」参照)。


### Vue
Vueもユーザーインタフェースをつくるためのフレームワークです。Reactと同じく、ルーティングなど他の機能は、別のライブラリで補います。Vueを特徴づけるのは、小さく始められることです。あとから機能を加えながら、サイトを大きくしていけます。あるいは、jQueryが使われているサイトを、少しずつVueに移行するといったことも可能です。

エコシステムは、3つの中ではもっとも少ないでしょう。けれども、公式サイトに日本語版があります。更新も原文の英語サイトと時間差はほとんどありません。最新の日本語情報に絞ってみるなら、他のフレームワークにそれほど見劣りはしないでしょう。

学習コストは高くありません。小さく始めて、少しずつ進めることで、段階的に学べます。ただ、公式サイトは始めやすさを重視しているらしく、簡易な構文のサンプルもあり、本格的な開発のスタイルは改めて考える必要がありそうです。つぎのコードは、単一コンポーネントファイル(VUE)のひな形からの引用です。テンプレートとJavaScriptコードそれにスタイルシートが、ひとつのコンポーネントのファイルとしてまとめられています。

```vue
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'app',
  components: {
    HelloWorld
  }
}
</script>

<style>
/* ...[略]... */
</style>
```


### Angular
Angularの特徴は、何といってもフルスタック「全部入り」ということです。ルーティングを含め、webアプリケーションに必要な機能すべてが備わっています。開発の規模としては、大きなプロジェクト向きです。はじめからしっかりと設計して、Angular流で進めなければなりません。ちょっと試すという使い方は難しく、気合いを入れて取り組む必要があります。堅牢さと厳密さは3つの中でもっとも高いでしょう。

学習に費やす手間と時間は多くかかるものの、「全部」できるようになることを考えれば、コストパフォーマンスが悪いわけではないでしょう。「やはりやめた」というときの埋没費用が高いというだけです。関連ライブラリやツール、情報などのエコシステムは多いといえます。

コードはTypeScript(TS)で書き、テンプレート(HTML)とスタイルシート(CSS)はそれぞれ別ファイルです。分業はしやすいかもしれません。つぎのコードは、ひな形のTypeScriptファイルから引用しました。[デコレータ関数](http://www.fumiononaka.com/Business/html5/FN1611003.html)(`@`)以外は、ECMAScript 2015と差はありません。

```typescript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

なお、TypeScriptはReactやVueの開発でも、設定を加えて使うことができます。Angularでは、TypeScriptの使用が原則とされているということです。

### gumiはReactを採用
gumiでは3つのフレームワークのうち、Reactを採用しました。理由はつぎのとおりです。

1. 情報や関連ライブラリ、ツールなどがもっとも豊富です。
2. 開発の規模は小さめのものから大きいものまで柔軟に対応できます。
3. チームでルールを決めて開発を進めるのに適しています。

3つのフレームワークの特徴についてご紹介しました。それぞれに異なった長所があり、それが裏返すと短所に結びついたりもします。一般的に、これがもっとも優れたフレームワークだといえるものはありません。プロジェクトやチーム、あるいは会社における開発の進め方や重視する機能などから、適した技術を選ぶと考えるのがよいでしょう。

# 3つのフレームワークの評価を数字で比べる
3つのフレームワークの評価を数字で比べてみましょう。bestofjs.org「JavaScript ベスト・オブ・ザ・イヤー 2017」「[フロントエンドフレームワーク](https://risingstars.js.org/2017/ja/#section-framework)」では、Vueが第1位でした。

![qiita_12_004_002.png](https://qiita-image-store.s3.amazonaws.com/0/262045/9097dacb-78fb-8638-2234-f15e747f21f4.png)

[GitHubのStar数推移](https://www.timqian.com/star-history/#facebook/react&vuejs/vue&angular/angular)を見てみると、Vueの伸びが大きく、最近Reactを抜きました。

![qiita_12_004_003.png](https://qiita-image-store.s3.amazonaws.com/0/262045/21561d69-7137-aa0f-5e2a-855f572673b8.png)

bestofjs.org「[UI Framework](https://bestofjs.org/tags/framework)」でも、 Vueが一番人気です。けれど、トレンドではReactの方が注目されています。

![qiita_12_004_004.png](https://qiita-image-store.s3.amazonaws.com/0/262045/5b2946c0-d390-f5f2-f1c0-1ce85038fc63.png)

Stack Overflowには「Developer Survey Results」「[Frameworks, Libraries, and Tools](https://insights.stackoverflow.com/survey/2018#technology-frameworks-libraries-and-tools)」というカテゴリで、もっと幅広いライブラリやツールにおける調査がありました。AngularはNode.jsにつぐ第2位で、第3位にReactが入りました。なんと、Vueは圏外です。

| 順位 | 名前 | パーセンテージ |
|:-:|:--|--:|
| 1 | Node.js | 49.6% |
| 2 | Angular | 36.9% |
| 3 | React | 27.8% |

もうひとつ、パフォーマンスのテスト結果をご紹介します。「エンジニア向けのマイクロインタラクション入門」の「[パフォーマンス比較](https://speakerdeck.com/clockmaker/enziniaxiang-kefalsemaikurointarakusiyonru-men?slide=45)」では、メモリ使用量と描画性能ともにReactがもっとも優れていたそうです。

![1812002_001.png](https://qiita-image-store.s3.amazonaws.com/0/262045/a5ab76e9-7670-8ceb-6c86-8924c6c324bc.png)

なお、第69回 HTML5とか勉強会「UIフレームワーク最前線」でパネルディスカッション「[Angular, Vue.js, Reactのコントリビューターたちが語る、JavaScriptフレームワーク開発の最前線](https://logmi.jp/tech/articles/302650)」が行われました。また違った視点から、3つのフレームワークを評価することができるでしょう。