Atomic Designを個人開発に導入 → 失敗と改善をまとめてみた
はじめに
個人開発でAtomic Designを導入してみた経験をもとに、感じたことや考えたコンポーネント設計のポイント、そして苦戦した部分をまとめます。
導入のきっかけと意識したこと
Atomic Designを意識することで、まずコンポーネントの責務を明確にするきっかけになりました。
また、コンポーネントの粒度を考えるようになり、特にUIライブラリやReact Hook Formと組み合わせた時に設計が整理されやすくなったのを実感しました。
- 段階的に作成できるため、コンポーネントの階層が整理されやすい
- テストを書く際に、どの粒度でテストすべきかを考えやすくなる
メリットとデメリット
私が個人開発で使って感じたメリットとデメリットを整理します。
メリット
- コンポーネント設計が自然と整理され、コードの見通しが良くなる
- コンポーネントが大きくなりすぎるのを防げる
- 再利用できるパーツを意識する習慣がつく
- 小規模でも段階的に構造化できる
デメリット
- 個人開発規模だと再利用シーンが少なく、分けるのが面倒に感じる
- 労力に対して効果が薄い場面もある
- 分割のメリットを実感しにくい場合がある
苦戦したポイント
導入当初は思うようにいかず、過去のプロジェクトの構成に引っ張られて混乱しました。
特に pages/
配下に containers
と presentations
を作った時は、Atomic Design の利点をうまく活かせませんでした。
過去に経験した構成(Atomic Design導入前)
components/
├─ parts/ # パーツコンポーネントをここに集約
│ ├─ Button/
│ ├─ Input/
│ └─ Card/
├─ pages/ # ページごとのコンポーネント
│ ├─ Home/
│ │ ├─ containers/ # ロジックを担当
│ │ └─ presentations/ # UIを担当
│ └─ About/
│ ├─ containers/
│ └─ presentations/
Atomic Design導入後(苦戦していたとき)
components/
├─ atoms/
│ ├─ Button/
│ ├─ Input/
│ └─ Label/
├─ molecules/
│ ├─ Modal/
│ └─ Post/
├─ organisms/
│ ├─ Header/
│ └─ Footer/
├─ templates/
│ └─ ???/ # 使いこなせず空の状態
└─ pages/
├─ report/
│ ├─ containers/ # ロジック担当
│ └─ presentations/ # UI担当
└─ posts/
├─ containers/
└─ presentations/
- 過去の
components/pages
の経験から、containers/presentations
を作ってしまった - atom や molecule にほぼ全てを入れてしまい、organism が活かせなかった
- pages に多くの処理を書いてしまい、template はまったく使えていなかった
「これで本当に良いのか?Atomic Designの利点が見えない」と感じたため、もう一度調べ直し、それぞれの階層の責務を意識しながら構成を作り直しました。
改善後の構成
components/
├─ atoms/
│ ├─ Button/
│ ├─ Card/
│ ├─ Select/
│ └─ TextField/
├─ molecules/
│ ├─ FormSelect/ # React Hook FormのControllerでラップしたSelect
│ ├─ FormTextField/ # ControllerでラップしたTextField
│ └─ Post/
├─ organisms/
│ ├─ PostList/
│ ├─ RegisterForm/ # formタグでラップした入力フォーム
│ └─ ReportForm/ # formタグでラップした入力フォーム
├─ templates/
│ ├─ Header/
│ ├─ Footer/
│ ├─ Layout/
│ └─ SingleColumn/
└─ pages/
├─ Posts/
├─ Register/
└─ Report/
このように変更したことで、以下のような整理ができました。
- atom → organism にかけて、自然に再利用できる流れを作れる
- template は 画面の大枠を決めるだけ が責務
- pages では template を選び、organism を children に渡すだけ
結果として、pages コンポーネントをシンプルに保ち、ロジックに集中できるようになりました。
pages/Report の例
"use client";
import React from "react";
import { ReportForm } from "@/components/Organisms/ReportForm";
import { SingleColumn } from "@/components/Templates/SingleColumn";
import { useReport } from "./useReport";
export function Report() {
const {
methods,
control,
errors,
・・・
} = useReport();
return (
<SingleColumn title="学習記録">
<ReportForm
methods={methods}
control={control}
errors={errors}
・・・
/>
</SingleColumn>
);
}
苦戦時と改善後の違いをまとめると以下のような感じになります。
項目 | 苦戦していたとき | 改善後 | 効果 |
---|---|---|---|
pages配下 | containers/presentations を配置 | pages は最小限、ロジックに集中 | ページがシンプルになり可読性UP |
organisms | 活用できていない | フォームやリストを整理して共通化 | 再利用性が向上 |
templates | 空のまま | レイアウト専用として責務を明確化 | レイアウトとロジックが分離 |
今回の導入で学んだこと
個人開発規模ではメリットを感じにくい部分もありますが、コンポーネントの責務を明確にし、粒度を意識する習慣は大いに役立ちます。これはAtomic Design以外の設計手法に切り替えたとしても活きる知識です。
またチーム開発では、共通化パーツを使う意識が芽生え、無駄な個別実装を減らせるのではと感じました。
初めてAtomic Designを導入する場合に意識したいこと
- すべてを厳密に分類しようとせず、必要な階層だけを作る
- まずは atom や molecule から始め、必要に応じて organism や template にまとめる
- pages と template の役割を整理し、レイアウトとロジックを分離する
Atomic Designは正解が一つではなく、プロジェクト規模やチーム体制に合わせて柔軟に取り入れるのが大事だと思います。
一度も試したことがない方は、ぜひ個人開発からAtomic Designを取り入れてみてはいかがでしょうか。
今回の内容が誰かの設計のヒントになれば嬉しいです!
Discussion
失礼します。
Atomic Design は、「コンポーネントの責務の大きさ」を検討するのに良い補助線になると思いますが、これをそのまんまディレクトリ構造にするのは筋が悪いと思います。
きちんと分類しようとすればするほど、import する / されるの依存関係のグラフがどんどん複雑化していくことが確実です。
それよりも、コロケーション原則(互いに import する / される の関係があるものを、同じディレクトリに置く)に基づいてディレクトリを切るのが良いと思います。
僕自身、実務でも「再利用のための Atom / Molecule / Organism / ...」分類は採用せず、コロケーションに従ったディレクトリ構造を採用しています。
「再利用できること」「共通化」は目的ではなく、まず「モジュール化」を目的とすべきで、その中の一部で「共通化」を意識すると良い場合があるだけ、という視点もあると良いと思います。