結論
最近、React のスタイリングライブラリである styled-components と emotion を比較してみました。
先に結論だけ話すと、個人的にはemotionの書き方が好みでした。
emotionの方が良かった理由
- スタイルと要素が直接的に確認でき、DOM構造が視覚的に分かりやすい
- スタイルコンポーネントの命名に苦しめられない
前提
- 自己学習の規模で styled-components と emotionを比較
メリット1: スタイルと要素が直接的に確認でき、DOM構造が視覚的に分かりやすい
📝 styled-componentsの書き方とemotionの書き方をコードで比較する
styled-componentsは、要素の宣言をスタイル側に持たせているため、<Box>というコンポーネントがどのようなHTMLタグで構成されているのか、またはどんなスタイルが適用されているのかを確認する場合はスタイルを定義しているファイルまで遡って調べる必要がある。
(Example.tsxの<Box>がどういう意図をもった要素なのかBox.tsxを確認しないと分からない)
一方でemotionはタグの役割やスタイルが一目で確認できる。スタイルが明示的に指定されているため、コード内でどの要素にどのスタイルが適用されているかがわかりやすく、スタイルを確認するために別ファイルに移動して確認する必要がない。
(Example.tsxを確認するだけで、divがどういった意図を持った要素なのか一目で分かる)
メリット2: コンポーネントの命名に苦しめられない
「コンポーネントの命名に苦しめられない」のメリットを話す前に、styled-componentを使用時に起こりがちな2つケースについて紹介したい
1. styled-componentsと外部コンポーネントの区別が付きづらいケース
// 外部コンポーネントの読み込み
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タグの出自が分かりづらいケース
メリット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を使っている人には、よく挙げられる声の1つだったのと、開発中に規模が大きくなるにつれて後々、命名が大変そうだなと感じたので紹介させてもらいました。
styled-Componentsを採用した場合は、以下のようにスタイル用のコンポーネントファイルが作成されるイメージ?
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

