SPECIALIST

多様な専門性を持つNRIデジタル社員のコラム、インタビューやインサイトをご紹介します。

BACK

React で紐解くモダンフロントエンド開発の歴史と進歩

こんにちは、倉澤です。
2017年頃に初めて React に出会って以降、フロントエンド開発ではよく React を利用しています。ある程度の規模で開発するプロジェクトがあり、チームメンバーも多くいましたので React の標準化を行いました。この記事ではその内容を一部ご紹介します。
本記事は React に触れたことが無いエンジニア・PM の方、ITベンダーからの提案を受ける方向けに React を参考例としてモダンフロントエンド開発の歴史と進歩を紐解いていきます。

モダンフロントエンド開発とは

Web 技術の中でも、この5~6年の Web フロントエンド・Web アプリケーションの技術は React, Vue, Angular を中心にして目覚ましい進歩を遂げました。

そもそもなぜ  “モダン” – 現代の – フロントエンド開発と呼ばれるのでしょうか。Web のフロントエンド技術の中心は HTML / CSS / JavaScript であり基本的な構成は従来と変わりません。しかしスマートフォンを始めとするフロントエンド端末の性能が向上したことにより、サーバーサイドで行わなくてはいけなかった重たい処理をブラウザ側で完結させることが出来るようになりました。

1995年に登場した JavaScript は Webとともに急速に普及していきました。 しかし、当初はブラウザベンダーが独自に言語仕様を拡張していたため、ブラウザ間の互換性が低い状態でした。少しづつ標準仕様が定まり2009年5月に公開された ES5 では、言語仕様の解釈を明文化し各ブラウザの実装として標準化されました。そして、2015年6月にメジャーアップデートとなる ECMAScript 2015(ES2015 / ES6)がリリースされました。ES2015では新しい機能や文法が追加されただけではなく既存機能もアップデートされており、より安全で便利に、そして効率的にプログラムを書くことができるようになっています。これがモダンフロントエンドの大転機となります。

JavaScript の技術的進化とスマートフォンの性能向上によって、サーバーサイドで行うような処理をブラウザ上のフロントエンドで完結できるようになってきたことから JavaScript の役割が大きくなりました。JavaScript の技術の進化。これが – 昔の – フロントエンド開発と – 現代の – フロントエンド開発が呼び分けられている背景です。

モダンフロントエンド開発が解決する3つの課題

モダンフロントエンド開発が解決している課題は様々ありますが、私が考えている代表的なものはマルチチャネルでの UI/UX の向上、ビジネススピードを加速させるマイクロサービスとの親和性、フロントエンド開発品質の向上の3つです。

マルチチャネルでの UI/UX の向上

今やユーザー接点の主役はスマホです。Web サイトはチャネル共通的に価値訴求することが出来ます。iPhone、Pixel、Galaxyなどのデバイスに応じたレスポンシブデザイン、コンテンツの切替、アプリ内の Webview など様々な端末/描画先に対応した Web サイトを構築することが求められています。従来のモノリシックな構成ではサーバーでデータ処理を行ってHTMLを生成しブラウザに配信表示します。UI/UX 向上のトライ&エラーが求められるフロントの領域もシステム一体となって慎重に取り組む必要がありました。

React などのモダンフロントエンド技術では、ブラウザでデータ処理を行って HTML を生成表示することが可能になります。フロントとしてプレゼンテーション層を完結させられることがモダンフロントエンド開発のメリットです。フロントエンドとバックエンドでシステムを切り離すことが出来るためフロントエンドチームは UI/UX に集中し試行錯誤をしやすくなり、お客様にとってより良い体験を作ることが出来るようになります。

従来のデザイナー・フロントエンドエンジニア・バックエンドエンジニアの役割は大きく変わってきています。昨年のReact Conf 2021 keynoteでは「React は “design principles” (設計原則)に根差していて、デザインとプログラミングを統合する」という話が出たり、 AWS re:Invent の場でも、デザインツール Figma から React アプリを構築するAmplify Studio というサービスのリリースがありました。(※ 検証記事はこちら)。UI/UX は toC ビジネスの価値に直結しますので取り組む価値のある領域かと思います。

モノリシック・マルチチャネル・マイクロサービス

ビジネススピードを加速させるマイクロサービスとの親和性

従来のモノリシックなシステム構成では変化し続けるビジネスへの即座の対応は難しくなってきています。モノリシックなシステムは既存のビジネスを支えるシステムであることが多く、現行業務への影響が無いように守りの姿勢が求められます。市場の変化が早くなる中、守りながら攻めるというのはなかなか難しいことかと思います。

ビジネスロジックとデータを分割しサービス化することでビジネスの意思決定を迅速化することがマイクロサービスの特徴です。マイクロサービス化したシステムは Web API を介したチャネルフラットなバックエンドシステムになります。モダンフロントエンド開発は前述の通りフロントで完結するためマイクロサービスとも親和性が高いアーキテクチャでもあるのです。

フロントエンド開発品質の向上

役割分担が成り立つのは品質が確保されているからです。どのようにして開発品質が向上していったのか、2022年時点の業界標準的な構成を元にモダンフロントエンド開発を取り巻く技術要素と進歩の歴史をご説明します。
目次
モダンフロントエンド開発一連の流れ

JavaScript の進化

言語仕様の標準化(ECMAScript2015/ES6)

ECMAScript とは、Ecma インターナショナルという国際標準化団体が定めた JavaScript の言語仕様(言語標準)です。2015年から毎年 ECMAScript は新機能を追加しています。

JavaScript の実行環境は「ブラウザ」です。ブラウザごとに言語仕様が異なっていましたが標準化が進み言語としての安定感が増しました。ただし、標準化はされているもののブラウザが最新機能に追いついているかというとそうではありません。Can I use ?というサイトでブラウザの対応状況がわかります。2022年1月現在、ECMAScript 2015 (ES6) をサポートするブラウザは世界で96.34%です。

出典)“ES6” | Can I use

型の登場(TypeScript)

TypeScript は JavaScript に型を追加します。型があることはメリットでもありデメリットでもありますが、型があることで開発に関わる人数や規模が増えた際にも品質が安定するため TypeScript は是非導入を検討してください。特徴は次のとおりです。

  • JavaScriptの上位互換
  • 安全性が高い
  • 型推論がある
  • オープンソースである

サーバーサイド実行環境の獲得(Node.js)

Node.js は JavaScript のサーバーサイド実行環境です。従来はブラウザで動作する JavaScript でしたが、サーバーサイドでWebサーバーアプリを利用するために開発されました。

Node.js はフロントエンド開発にも大きな恩恵をもたらしました。Node.js は開発者のコンソール・コマンドラインで動かせるため、Babel, wepack, ESLint, Prettier などの開発ツールが生まれ、フロントエンド開発のモダン化が押し進められました。

サーバーサイド・クライアントサイドJS-1

本格的なアプリ構築

世界中のオープンソースライブラリ・モジュールが再利用可能に(npm)

npm (Node Package Manager) は JavaScript 向けのパッケージマネージャです。ライブラリをパッケージ管理することが出来るようになり、本格的なアプリケーションの構築が出来るようになりました。これがモダンフロントエンド開発のエポックメイキングの一つだったのでは無いでしょうか。

npm は世界規模のソフトウェアレジストリです。公開されているオープンソースを利用することが可能で package.json ファイルでライブラリのバージョンを指定するとインストール出来ます。

package-json

増えすぎたモジュールを統合・バンドル(webpack)

webpack はモジュールバンドラです。複数ファイル間の依存関係を解決して、ブラウザで実行可能な JavaScript ファイルを生成するツールです。まとめる処理をバンドルと呼びます。

出典)webpack 公式サイト

古いブラウザで動くように後方互換・トランスパイル(Babel)

Babel は新しい JavaScript 構文を古い JavaScript 構文に変換して、昔のブラウザにも後方互換対応させるためのトランスパイラです。また React で利用する JSX 構文を実行可能な JavaScript に変換するためにも使われます。TypeScript, Babel, webpack のトランスパイル・バンドルは同時に実行させることが多いです。

開発補助ツール

ソースコードのフォーマット(Prettier)

Prettier はコードフォーマッターです。コード整形を主目的としています。ESLint と併用します。

ソースコードの静的解析(ESLint)

ESLint はコードフォーマッターです。コードの構文解析、間違いを指摘してくれます。

タスクランナー(Husky)

Husky はタスクランナーです。Git の commit, push をする前に一連の作業を実施してくれます。

開発フレームワーク

JavaScript は2015年からの栄枯盛衰が激しく、比較的落ち着いてきたものの様々なフレームワークが登場しています。大きく分けるとクライアントサイド(CSR)とサーバーサイド(SSR)に分けられます。SPAはクライアントサイドと言われることが多いです。

クライアントサイド(CSR)

ブラウザ上で JavaScript を実行して DOM を生成、マウントし、コンテンツを表示させます。

  • メリット
    • ブラウザで完結するためサーバーが不要。(※S3 等でのホスティングは必要)
    • HTMLファイル、バンドルされたJSファイルの2つだけで動くので配信がかんたん
  • デメリット
    • JSファイルサイズが大きくなると初回ロードが遅くなる
    • 2015年当初は SEO に不利(クローラーが解析出来ない)と言われていた。現在は Google が対応済
  • 代表的なフレームワーク
    • React, Vue , Angular

サーバーサイド(SSR)

サーバー上で JavaScript を実行して、HTML ファイルを生成。ブラウザへ配信表示。

  • メリット
    • レンダリング後の HTML ファイルを配信するため高速
    • SEO で不利にならない
  • デメリット
    • サーバーが必要
  • 代表的なフレームワーク
    • Next, Hydrogen など

ユーザインターフェース構築のための JavaScript ライブラリ(React)

React とは

React はユーザインターフェイスを構築するための、宣言型で効率的で柔軟な JavaScript ライブラリです。複雑な UI を、「コンポーネント」と呼ばれる小さく独立した部品から組み立てることができます。代表的なものに React, Vue, Angular などがありますが React は安定して人気のあるライブラリです。ここからは React の技術的な特徴をご説明します。

出典)State of JS Front-end Frameworks

充実したデザインコンポーネント

Google が公開している Material UI や Ant Design など一度は目にしたことがあるデザインが React の UI コンポーネントとして公開されています。React を利用することで一定以上の使いやすい UI デザインを最初から獲得することが出来ます。画面を開発する際にはこの UI コンポーネントをパズルのように組み合わせていくだけで良いのです。

出典)Material UI

Flux という設計思想

React はデータ管理の考え方が従来とは異なります。 MVC モデルのように双方向ではなく、Flux というデータの流れを一方向にする考え方で設計されています。開発規模が大きくなったとしてもデータの流れが明確であることがメリットです。

  • Action:View での入力・操作イベント
  • Dispatcher:Action を受けて Store へイベント(データと呼び出す関数)を渡す
  • Store:アプリケーション全体のデータとビジネスロジック関数
  • View:画面に表示するUIコンポーネント

出典)facebook/flux

Redux による状態管理

Redux は Flux の概念を拡張して扱いやすく設計されています。Redux は React で状態管理を行うことに適したライブラリです。

Redux の3原則
  • Single source of truth(アプリケーション内でStoreは1つのみとし、Stateは単独のオブジェクトとしてStoreに保持される)
  • State is read-only(Stateを直接変更することはできず、actionをStoreへdispatchすることでしかStateは変更できない)
  • Mutations are written as pure functions(Stateを変更する関数(Reducer)は純粋な関数にする)

出典)Redux Application Data Flow

その他

開発を進める上では様々な設計考慮が必要になってきます。本記事ですべてを解説することは時間の関係で難しいのですが、今後 React に取り組まれる方は例えば以下の観点で整理されていくとよろしいかと思います。

関数コンポーネント、UIコンポーネント、ルーティング、API通信、フォーム・バリデーション、認証認可、非同期処理、エラーハンドリング・エラーログ、、、など

テスティングフレームワーク

モダンフロントエンド開発におけるテストの考え方(The Testing Trophy)

テスティングトロフィーは各種テストのコストの高さに加えて、各種テストの効果を示した図です。

React を用いたフロントエンド開発ではデザインされたUIコンポーネント部品(ボタンやフォームなど)を組み合わせて Web サイトを構築します。例えば「オレンジ色の決定ボタン」という部品をコンポーネントとして実装します。このコンポーネントの Unit Test を書こうとすると決定ボタンはオレンジ色であることを確認することになり、あまり意味のあるテストではありません。The Testing Trophy の考え方を示した Kent C. Dodds 氏は React コンポーネントの実装の詳細をテストするのではなく、 React アプリケーションの利用者としてテストをするという考え方で Integration Test に厚みをもたせるべきと言っています。

Static Test

お気づきかもしれませんが、前述の TypeScript, ESLint, Prettier 等を導入することで静的な観点での品質確保をしています。

Unit Test (Jest)

プログラム関数単位で IN/OUT をテストします。ユニットテストには Jest を使用します。Jest は JavaScript テスティングフレームワークです。細かい設定不要で、アサーション、モック、スナップショット、カバレッジなどのテスト機能を提供してくれます。

sum という足し算の関数をテストする Jest テストコードサンプル

Integration Test (React Testing Library)

インテグレーションテストには React Testing Library(以降 RTL) を使用します。実際のユーザーのアプリの使い方に基づいたテストをします。RTL で React コンポーネントの JSX をレンダリング(render)すると、テストコード内で React コンポーネントにアクセス出来るようになります。RTL の検索関数を用いて要素を取得します。そしてアサーションで DOM に要素が含まれているかどうかテストしましょう。

Learn React というリンクを表示する関数コンポーネントをテストする RTL テストコードサンプル
ビジュアルデザインの確認

RTL では振る舞いをテストしていましたが、UI コンポーネント自体の見た目を確認する際には Storybook を導入すると良いでしょう。

出典)Storybook

End to End Test (cypress)

E2E テストには cypress を使用します。ブラウザでのテスト作業を自動化してくれます。RTL と相性がよく書き方が似ています。百聞は一見に如かずなので公式サイトの動画を見てください。王道の正常系が一連動くかどうかの確認用に cypress で E2E を書いておくと安心感が増すと思います。

Web サイト公開

AWS Amplify hosting

開発・テストを行い品質確保したプログラムをビルドして Web サイトにデプロイします。実体としては index.html ファイルと数個の JavaScript ファイルになります。これらを S3 / Cloudfront などのホスティングサーバーに配置すると Web 公開されます。AWS の Amplify を利用してホスティングすると良いでしょう。

おわりに

モダンフロントエンド開発の一連の流れを振り返ると以下の図のようになります。モダンフロントエンド開発が銀の弾丸であるというわけではございませんが、次のようなユースケースの際には React での開発を検討されてみてはいかがでしょうか。

  • マルチチャネルでの UI/UX の向上
  • ビジネススピードを加速させるマイクロサービスとの親和性
  • フロントエンド開発品質の向上
モダンフロントエンド開発一連の流れ
<本記事に関するお問い合わせ>
NRIデジタル株式会社 倉澤
marketing-analytics-team@nri-digital.jp