フロントエンドにおけるコンポーネントとは

# TL;DR
ついこの間。
ジュニアのマークアップエンジニアの話を聞いていて、
「意外とこの基準わかりづらいものなんだな」と思ったので、
ここ最近身につけた知識ベースで、直感的ではなくなるべく**言語化**する形で
「コンポーネントとはなんぞや」
「その粒度について」
示しておこうと思いました。

# 本題
## コンポーネントとは

> コンポーネントとは、部品、成分、構成要素などの意味を持つ英単語。 ITの分野では機器やソフトウェア、システムの構成する部品や要素などのことを意味する。

[※コンポーネントとは - IT用語辞典](https://e-words.jp/w/%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88.html#:~:text=%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%A8%E3%81%AF%E3%80%81%E9%83%A8%E5%93%81%E3%80%81%E6%88%90%E5%88%86,%E3%81%AE%E3%81%93%E3%81%A8%E3%82%92%E6%84%8F%E5%91%B3%E3%81%99%E3%82%8B%E3%80%82)

上記の通りコンポーネントとは、ある程度まとまったものを「部品として」分解したものになります。
さらにコンポーネントをその「部品」として分割する理由は以下になります。

> コンポーネントがコンポーネントであるための前提として、「関心の分離」というものがあります。
厳密な定義で説明すると少し難しいのですが、噛み砕いていってしまえば、機能や振る舞いなどを明確に分離する、ということです。

※Web製作者のためのCSS設計の教科書 p42

つまり、コンポーネントとは
・これはタイトルだよね
・これはリンク
・これはボタン
・これはタイトルと抜粋文とボタンがまとまったカード
のように、その「関心・目的」に沿って分割したパーツの総称になります。

## コンポーネントの粒度とは
さて、上記のようにパーツごとにコンポーネントを分割するとして、
どのくらいの粒度で分割すべきなのかがわからない！ということが出てくるかと思います。

個人的には、Atomic Designの定義がこの「粒度の基準」としては、
かなり明確で、なおかつわかりやすいのではないかと思いました。

Atomic Designでは、以下のようにコンポーネントの粒度を定義しています。

| 粒度 | 定義 | 実際のパーツ |
| --- | --- | --- |
| Atoms | 原子 | ボタン、リンク、フォームパーツなど|
| Molecules | 分子 | フォームパーツとボタンを組み合わせた検索フォームパーツ、ニュースリストの1行など、<br>「動作・存在意図が明確」なパーツ |
| Organisms | 有機体 | ブログのコンテンツなど、Molecules（動作）が複数まとまったことにより、<br>ページ内のコンテンツの「ひとまとまり」となっているパーツ|
| Templates | ページ内のレイアウトテンプレート | ヘッダー、フッター、左カラム、右カラムなど |
| Pages | ページ全体 | ページ全体 |

特に、Atoms Designにおける「Atoms」「Molecules」の基準が、
MindBEMdingにおけるコンポーネント分割で重要な基準になります。

たとえば、以下の粒度のパーツは「Atoms」「Molecules」の粒度のコンポーネントとして成立します。

- ボタンコンポーネントである **c-btn** （Atoms）
- ボタンの中にアイコンを表示させる **c-icon** （Atoms）
- 各段落のh要素である **c-headingXX** （Atoms）
- 「検索してください」という文言、input-text、「送信」ボタンをひとまとめにした **c-search-form**（Molecules）
- 日付、タイトル、カテゴリ、リンクをひとまとめにしたお知らせエリア内の1行 **c-news-line** （Molecules）

実際にAtomic Designのコンポーネント命名基準を利用するかは別として、
上記粒度でコンポーネントを区切り、CSSを分けることによって
汎用性の高いコンポーネント設計を作ることが
できるのではないかと思います。

## 実際にコンポーネントを分割してみる
コンポーネントを作成するにあたり、
上記の粒度で分割したコンポーネントはもちろん、
そのコンポーネントを「包括するパーツ」もコンポーネントとなり得ます。

たとえば、Qiitaのトップページは以下のような分割になり得ます。
（Atomsまで入れるとややこしくなるためAtomsは割愛します）

![qiita.com_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288273/11bd5e8b-b17a-af42-ca0f-a7a1f694f53d.png)

~~・・・とおもったけど、OrganismsとMoleculesが曖昧だなぁ・・・~~

このように、大きいコンポーネントの中に小さいコンポーネントを入れ子にして
一つ一つのコンポーネントを構成していきます。
1つのコンポーネントには**孫要素くらい（できれば子要素）までのCSS**を指定し、
それより内側の情報に関しては別コンポーネントとしてCSSを指定するようにします。

## まとめ
上記の通り、コーディングする際のコンポーネント設計は
「小さいパーツをたくさん作る」
　↓
「パーツを組み合わせる」
　↓
「組み合わせたパーツを構造としてまとめる」
という**ボトムアップ**の考え方で実装していくとうまくいくかと思います。

~~今の私がそう言うのできているかは置いておいて~~
綺麗なマークアップやプログラミングができるようになると
**後々の自分（これ重要）**やそのプロジェクトを引き継いだ人を助けることになります。
・・・というわけでがんばりまっしょい！！！！

## 参考
### 本文に引用
[Web製作者のためのCSS設計の教科書](https://www.amazon.co.jp/dp/B00M0ESXUI/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)（情報古め）
[Atomic Design](https://www.amazon.co.jp/Atomic-Design-%EF%BD%9E%E5%A0%85%E7%89%A2%E3%81%A7%E4%BD%BF%E3%81%84%E3%82%84%E3%81%99%E3%81%84UI%E3%82%92%E5%8A%B9%E7%8E%87%E8%89%AF%E3%81%8F%E8%A8%AD%E8%A8%88%E3%81%99%E3%82%8B-%E4%BA%94%E8%97%A4-%E4%BD%91%E5%85%B8-ebook/dp/B07CJ5TLK2/ref=sr_1_1?crid=2CCV17E3JOAQG&keywords=atomic+design&qid=1647500210&s=digital-text&sprefix=atomic%2Cdigital-text%2C226&sr=1-1)

### おすすめ
[Every Layout](https://www.amazon.co.jp/Every-Layout-%E3%83%98%E3%82%A4%E3%83%89%E3%83%B3%E3%83%BB%E3%83%94%E3%82%AB%E3%83%AA%E3%83%B3%E3%82%B0-ebook/dp/B09LQNQ7CW/ref=sr_1_1?keywords=every+layout&qid=1647500225&s=digital-text&sprefix=every+lay%2Cdigital-text%2C207&sr=1-1)（ただしコンポーネント設計の説明はない気がする）
[ざっくりつかむ　CSS設計 Kindle版](https://www.amazon.co.jp/%E3%81%96%E3%81%A3%E3%81%8F%E3%82%8A%E3%81%A4%E3%81%8B%E3%82%80-CSS%E8%A8%AD%E8%A8%88-%E9%AB%98%E6%B4%A5%E6%88%B8-%E5%A3%AE-ebook/dp/B09NKR8RCZ/ref=sr_1_1?crid=1X40P6NA5VJUM&keywords=%E3%81%96%E3%81%A3%E3%81%8F%E3%82%8A%E3%81%A4%E3%81%8B%E3%82%80+css%E8%A8%AD%E8%A8%88&qid=1647500152&s=digital-text&sprefix=%E3%81%96%E3%81%A3%E3%81%8F%E3%82%8A%E3%81%A4%E3%81%8B%E3%82%80+%2Cdigital-text%2C233&sr=1-1)（初心者向け）