この記事は『CRESCO Advent Calendar 2021』 19日目の記事です。
こんにちは、エクスペリエンスデザインセンターのsgi-changです。

つい最近、アドベントカレンダーを執筆したと思ったら、もう一年が過ぎていて時の流れの早さに驚愕している毎日です。

元々はWebサービスのバックエンドエンジニアでしたが、最近はありがたいことにフロントエンドのお仕事も多くなりReactなどのSingle Page Application(以降、SPA)のフレームワークを使って開発する機会が増えました。

そこで「SPAのフレームワークはコンポーネント指向である。」

とよく聞くけど

「そもそもコンポーネントって何?コンポーネント設計って?コンポーネント指向との違いは?」

とモヤモヤしたことがあったので、コンポーネント設計についてAtomic Designと絡めて記事にしてみました。

ここではコンポーネント設計にAtomic Designをベースに紹介していますが、あくまで設計手法のひとつとして参考になれば嬉しいです。

以下の流れで進めていきたいと思います。

目次

アイキャッチ画像(引用元: bradfrost.com, Brad Frost, CC BY 4.0)

コンポーネントとは?

コンポーネントとは「構成要素」「部品」などと表現される。

クレスコのホームーページのキャプチャ画像を例に説明します。

このページはいくつかの部品で構成されています。

そこで分かりやすく色をつけてみました。

この色がついた部分がコンポーネントになります。

オレンジ色…ページ全体を表します。

水色…一番上のグローバルナビゲーション全体を表します。

緑色…スライドでピックアップ情報を流しています。

青色…カード型のデザインに情報を表示していて各種リンクがはってあります。

赤色…グローバルナビゲーションに記載している各リンク情報です。

ほかにはスライドの矢印や各カードもそれぞれコンポーネントだったり、上の画像からさらに細かくコンポーネントに分けることができます。

コンポーネント設計とは?

実際に画面などの構成要素を部品ごとに分けて設計すること。

先ほどのクレスコのホームページのキャプチャ画像を例とすれば、色のついたコンポーネントごとに設計していくということです。

コンポーネント指向開発とは?

コンポーネント指向とは、コンポーネントを組み合わせて使うという考え方、またはアプリケーションを開発するスタイル。

つまり、

コンポーネント指向開発は、画面などの構成要素、部品ごとに分けるコンポーネント設計を用いて開発すること。

しかし…

ここまででなんとなくコンポーネントにわけて開発する、ということが分かったのですが、じゃあ、どういう基準で分ければいいの?分ける基準が個人的主観にならない?とまた違う疑問が出てきました。
そこでコンポーネント設計をするにあたり、Atomic Designという設計手法があることを知りました。

Atomic Designとは?

アメリカのWebデザイナーBrad Frostブラッド・フロスト氏が考案・提唱したUIデザインの設計手法。
昨今のコンポーネント指向開発において、採用されることが多い。UIは小さな構成要素の入れ子の組み合わせという考えを元に、化学のメタファーを用いて階層と粒度を定義

もっとわかりやすく説明すると…

画面を構成する要素を、

原子(Atom)
分子(molecule)
有機体(organism)
テンプレート(Templates)
ページ(Pages)

の5つの階層に分け設計していく。

下の図は、画面の構成を5つの階層に分けて設計していく順番を表しています。

(引用元: atomic design, Brad Frost, CC BY 4.0)

下の図はinstagramのUIを上記の構成に適応したもの

(引用元: Atomic Design Chapter2, Brad Frost, CC BY 4.0)

よく目にするサービスも、この画像のように5つの階層に分けて設計できることが分かると思います。

この設計手法を活用すると、

  • コンポーネントに分割しやすい、分割単位が明確になってわかりやすい。
  • コンポーネントの再利用ができる。
  • 画面のUIデザインが統一される。
  • UIデザインが統一されると、見栄えが良くなり、高品質な印象を与える。
  • 直感的に使いやすく、ユーザーの学習コストが下がる。

と私が思いつくだけでも、UX/ユーザービリティに良い影響を与えそうだと思いました。

その他コンポーネント設計について

Reactの公式ページに「Reactの流儀」というページがあり、そこでもコンポーネント設計について言及されているので、以下に抜粋します。

単一責任の原則 (single responsibility principle)

ひとつのコンポーネントは理想的にはひとつのことだけをするべきだということです。将来、コンポーネントが肥大化してしまった場合には、小さなコンポーネントに分割するべきです。

React公式ページ「Reactの流儀」より

これ以外にもコンポーネント設計について言及されているので一読されることをおすすめします。

コンポーネントを実装してみる

コンポーネントごとの設計についてはここまでで分かったので、それをどのように実装するか、良いパターンとアンチパターンを例にあげてみたいと思います。

例えば下記の図のようなシンプルに4つの要素で構成されているページがあるとします。

これを良いパターンの例で実装すると

こんな感じで上のコンポーネントは「役割」だけ、下のコンポーネントでは「スタイル情報」だけが記述されています。

上記ではわかりやすく表現するためにCSSをインラインスタイルで記述しています。

基本的にはCSSは分けて書くか、MUI(Material-UI)などのUIライブラリを使って表現するCSS-in-JSパターンで記述します。

次はアンチパターンの例です。

一つのコンポーネントに「役割」も「レイアウト」「スタイル情報」も含まれていることが分かります。

まとめると…

※ソースコードは例としてわかりやすく記述しています。実際の実装とは異なることをご了承ください。

UIデザイナーとの協業を考える

そこでUIデザイナーとの協業をどうするか、です。

自身の経験で言うと、SPAではない、従来のWeb開発だとUIデザイナーの方にまるっとHTMLやCSSの部分をお願いして、あとは最後にサーバーサイドと結合する…とかがよくあるパターンなのではないでしょうか。(あくまで個人の経験談です。)

先の「コンポーネントを実装してみる」では、1コンポーネントに

  • データを取得…振る舞い・アクション
  • 画面構成を表現…構造
  • UIデザインを表示…見た目・UI

などが含まれています。

これらの構成から従来のWeb開発での作業分担は難しいと思います。

SPAの開発において、開発者は、スタイルやレイアウトにも関わっていき、よりUI/UX/ユーザービリティを意識しないといけないのかなと思っています。

そう、協業…というより協働してお互いに一つのものを作り上げていく必要があると思っています。

協業…ある生産工程や業務を、多くの労働者や企業が、分担し合って組織的に働くこと。

協働…複数の主体が、何らかの目標を共有し、ともに力を合わせて活動することをいう。 コラボレーション(collaboration)、パートナーシップ(partnership)とも。

またUIデザイナーと開発者がコンポーネントを共有することができる「Storybook」などのツールもあります。

ここでは詳細は割愛させて頂きますが、Storybookは、UIコンポーネントとページを分離して構築するためのオープンソースツールです。アプリケーションとは独立して、コンポーネントごとにテスト、動作確認をすることができ、UIデザイナーと開発者との円滑なコミュニケーションツールとなり、齟齬をなくすことができます。その他にも、Figma、Sketch、Adobe XDなどデザインツールに対応したアドオンにより連携できるなどの利点がありコンポーネント開発においておすすめのツールです。

おわりに

SPAでコンポーネントごとに開発をしていくと、UIデザイナーの方とどう作業分担すればいいのだろう…という話をよく聞きました。

私もどうしても従来のWeb開発と比較しがちで、「これが正解!」というのはまだ分からないですが、少しでもコンポーネント設計、コンポーネント指向開発の参考になれば嬉しいです。

みなさまのよきフロントエンドライフを願っています。

最後までお読みいただき誠にありがとうございます。