styled-component と emotionを使ってみた個人的な感想

## 結論

最近、React のスタイリングライブラリである **styled-components** と **emotion** を比較してみました。
先に結論だけ話すと、個人的には**emotion**の書き方が好みでした。

## emotionの方が良かった理由
- スタイルと要素が直接的に確認でき、DOM構造が視覚的に分かりやすい
- スタイルコンポーネントの命名に苦しめられない
## 前提
- 自己学習の規模で **styled-components** と **emotion**を比較

## メリット1: スタイルと要素が直接的に確認でき、DOM構造が視覚的に分かりやすい
📝 **styled-components**の書き方と**emotion**の書き方をコードで比較する

![スクリーンショット 2025-02-25 18.09.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4019693/bfb1c72b-4242-472e-be91-95279904a5c8.png)

**styled-components**は、要素の宣言をスタイル側に持たせているため、&lt;Box&gt;というコンポーネントがどのようなHTMLタグで構成されているのか、またはどんなスタイルが適用されているのかを確認する場合はスタイルを定義しているファイルまで遡って調べる必要がある。
（Example.tsxの&lt;Box&gt;がどういう意図をもった要素なのかBox.tsxを確認しないと分からない）

一方で**emotion**はタグの役割やスタイルが一目で確認できる。スタイルが明示的に指定されているため、コード内でどの要素にどのスタイルが適用されているかがわかりやすく、スタイルを確認するために別ファイルに移動して確認する必要がない。
（Example.tsxを確認するだけで、divがどういった意図を持った要素なのか一目で分かる）

## メリット2: コンポーネントの命名に苦しめられない

 「コンポーネントの命名に苦しめられない」のメリットを話す前に、styled-componentを使用時に起こりがちな2つケースについて紹介したい

1\. styled-componentsと外部コンポーネントの区別が付きづらいケース
```jsx:Example.tsx（styled-component）
// 外部コンポーネントの読み込み
import { OuterComponent } from '../components/OuterComponent';

// styled-componentsの定義
const Element = styled.p`margin: 8px auto;`;

export const Example = () => {
  return (
    <>
      <OuterComponent /> // 外部コンポーネント
      <Element />    // styled-componentsの定義
    </>
  );
};
```
上記のように外部から読み込んだOuterComponentと、ファイル内部で定義したstyled-componentsのElementは、それぞれ異なる方法で作成されたコンポーネントだが、実際に使う時の見た目や使い方がほとんど同じである

この例のようにシンプルな構造ならまだしも、コードの規模が大きくなってくると、コンポーネントの出所や作り方の違いが分かりづらくなる。特に、外部コンポーネントとstyled-componentsのスタイル付きコンポーネントが混在していると、どのコンポーネントがどこから来たものなのか、どのように定義されているのかを見分けるのが難しくなり、コードの見通しが悪くなる。


2\. **styled-components**でHTMLタグの出自が分かりづらいケース

![スクリーンショット 2025-02-25 18.08.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4019693/79efe5f5-0535-4be8-a9ab-48c9a77e61ed.png)

メリット1にも話した内容と被るが**styled-components**を使う場合、どのHTMLタグが使われているのかが直接的には分からず、それを把握するためには各コンポーネントの定義を見て確認する必要がある。あまり直感的ではなく、コンポーネント化によって分かりづらくなる側面がある。

上記の2つ課題は、命名規則を徹底して解決してやらないといけない

1\. **styled-components**と外部コンポーネントの区別が付きづらいケースの対策例
- style用のcomponentを生成する際はprefixを設定する
例) 「Box」=>「StyledBox」

2\. **styled-components**でHTMLタグの出自が分かりづらいケース対策例
-  styled-componentsの命名の先頭にHTMLタグ名を大文字で入れる
例) 「h2 → Title」 としていた部分を 「h2 → H2_Title」

**styled-components**ではstyleを定義したコンポーネントに対してそれぞれ命名しなければならない性質上、「命名規則」には常に気を遣わないといけない。
命名を考える時にもリソースを割かないといけないし、事後に命名が適切でなかった場合にも再度リソースを割くことになる。

emotionでは、スタイルを直接タグ内のcssプロパティに書き込む形が可能であり、style用のコンポーネントを用意する必要がないため、上記のような問題には悩まされるようなことはなさそう。

## 感想
今回、自己学習という狭い領域で**styled-component**と**emotion**を比較した前提もあってか、**emotion**に軍配が上がってしまいました。 「スタイルと要素が直接的に確認でき、DOM構造が視覚的に分かりやすくなる」のが個人的にツボだったのかもしれません。
「コンポーネントの命名に苦しめられない」メリットに関しては、自己学習の規模で影響を受けた部分は正直ありませんでしたが、**styled-component**を使っている人には、よく挙げられる声の１つだったのと、開発中に規模が大きくなるにつれて後々、命名が大変そうだなと感じたので紹介させてもらいました。


styled-Componentsを採用した場合は、以下のようにスタイル用のコンポーネントファイルが作成されるイメージ？

```xml:ディレクトリ構造例
src/
├── components/
│   ├── Button/
│   │   ├── Button.tsx
│   │   ├── Button.styles.ts
│   │   └── index.ts
│   ├── Header/
│   │   ├── Header.tsx
│   │   ├── Header.styles.ts
│   │   └── index.ts
│   └── ...
├── features/
│   ├── Home/
│   │   ├── Home.tsx
│   │   ├── Home.styles.ts
│   │   └── index.ts
│   └── ...
├── App.tsx
└── index.tsx
```