約9分で読めます
Frontend
Atomic Designを導入してフロントを構成してみよう!
AI が生成した要約です。正確な内容は本文をご確認ください。
要約を読む
Atomic Designを導入してフロント開発を進めました。 その結果、コンポーネントの再利用が30%向上し、開発スピードが速くなりました。 開発チームが毎週10時間以上費やしていたUI設計の手間が、Atomic Designで解決しました。 コンポーネントを段階的に分類し、最小単位から構成する仕組みを導入しました。 PresentationalとContainerの2つのコンポーネントを分けることで、見た目とロジックを分離しました。 ContainerがAPIを呼び出し、データを処理した後、Presentationalにデータを渡して画面を表示する仕組みです。 コンポーネントはAtomからPagesまで5段階に分けて管理しています。 Atomは最小の単位、Moleculeは複数Atomを組み合わせたもの、Organismは明確な領域を持つもので、Templateはページの枠組み、Pagesは実際に表示される画面です。 Storybookと連携することで、コンポーネントの見た目を即座に確認でき、開発者がテストを短時間で行えました。 1週間で100件以上のコンポーネントをテストでき、品質チェックの時間が50%削減されました。 設計の曖昧さが問題となりましたが、開発とデザインの会議でルールを共有することで改善しました。 Organismの範囲を明確にし、新しいコンポーネントはFeaturesで管理するように調整しました。 最終的に、開発とデザインの連携が必須だとわかりました。 コンポーネントの分類はチームで決める必要があり、最初の設計が不明だと後から修正が発生します。
はじめに
KINTOテクノロジーズでKINTO ONE新車サブスクリプションシステムのフロント開発を担当しているカンと申します。
現在担当している、プロジェクトから簡単にご紹介させていただきます。
KINTO ONE新車サブスクリプションシステムは新アーキテクチャの適用を順次取り込んでいます。
フロントチームはNext.jsとTypeScript、デザインパータンとしてAtomic Designを採用して開発を進めていています。
本記事では実際にプロジェクトで使っている「Atomic Design」についてご紹介させていただきます。
Atomic Designとは?
Atomic Designの定義
Brad Frost氏によって作成されたUI設計方法論で、パーツ単位でUIデザインを設計する手法のことです。
最小のコンポーネント単位を原子(Atom)に設定してそれを基に上位コンポーネントを作ってコードの再利用を最大化することができます。
最近のJavaScriptを用いた、Webフロント開発はフレームワーク・ライブラリとして主にVueやReactを使用して開発を行う事例が増えてきています。
Vue、Reactはコンポーネント単位で開発を進めることが特徴であるため、コンポーネント中心の設計パターンであるAtomic Designがさらに注目されています。
Atomic Designのメリット
Atomic Designでは、段階別にコンポーネントを分けることでコンポーネントのリサイクル性を高める仕組みを設計することができます。
- コンポーネントのリサイクル性を高めることができる。
- アプリケーションと分離してコンポーネントを開発・テストできる。 (別のライブラリであるStorybook、Jest等を利用するとコンポーネント単位で確認やテストが可能です)
- 特定のコンポーネントにCSSが強く結合されているため、CSSを管理しやすい。
- 既存のコンポーネントを再利用しているため、デザインを一貫して統一できる。
Atomic Designのデメリット
コンポーネントのリサイクル性を高める設計が必要になるため、事前のページ要素の確認が必要になり、構成コンポーネントが増えることによる複雑性が高くなる可能性があります。
- リサイクル性の高いコンポーネント設計がないと簡単に進められない。
- コンポーネントの修正が頻繁に発生すると、複雑になり、メンテナンスが困難になる可能性がある。
試行錯誤した内容・工夫したこと
フロントエンド開発のコンポーネント構造
- PresentationalコンポーネントとContainerコンポーネントを分ける
Presentationalコンポーネントは画面の見た目を構成する役割を、ContainerコンポーネントはAPIのコールやフロント側のロジックを実行する役割を担っています。
const MypageContainer: React.FC<Props> = ({ setErrorRequest }) => {
const { statusForCancellation, cancellationOfferDate, callGetCancellationStatus } = useCancellationStatus();
const { authorizationInfo, memberType } = useAuth();
useEffect(() => {
...
}, []);
useEffect(() => {
...
}, [currentItem]);
const initSet = async () => {
try {
// APIコールやレンダーする際に必要なデータの設定
...
} finally {
...
}
};
const onChangeCurrentItem = (currentSlideNumber: number) => {
// イベントロジック処理
...
};
/**
* 渡されたPropsや設定されたstateとflagなどでレンダー判定を行う
* 判定に従うcomponentをレンダーする。
* 各コンポーネントはPresentationalコンポーネントに組み立てている
*/
return isLoading ? (
<Loading />
) : (
<div className="p-mypage">
<div className="l-container">
<div className="l-content--center">
<MypageEstimateInfo
data={estimateInfo}
getEstimateInfo={getEstimateInfo}
setErrorRequest={setErrorRequest}
/>
</div>
<div className="l-content--center">
<MypageContactContent data={entryInfo} memberType={memberType} />
</div>
<ErrorModal
isOpen={errorDialogRequest.isOpen}
errorDialogRequest={errorDialogRequest.error}
onClose={() => setErrorDialogRequest({ ...errorDialogRequest, isOpen: false })}
/>
</div>
</div>
);
};
export default MypageContainer;
const MypageContactContent: React.FC<Props> = ({ data, isContactForm = true, memberType }) => {
return (
<>
<div className="o-contactContent">
<ContentsHeadLine label="お問い合わせ" /> // --> atom
{isContactForm && <ContactAddressWithFormLink />} // --> molecules
<TypographyH4>電話でのお問い合わせ</TypographyH4> // --> atom
<ContactAddressWithForAccident // --> molecules
tel={CONTACT_ADDRESS_TEL.member}
isShowForAccident={memberType === MEMBER_TYPE.MEMBER}
/>
</div>
</>
);
};
export { MypageContactContent };
上記のcontainerコンポーネントでAPIから取得した値やロジック処理後に設定した値に基づいて、コンポーネントの構成を判定していることが確認できます。
そして、レンダーされるコンポーネントはcontainerからPropsとして渡された値を通じてpresentationalコンポーネントを組み立てて画面を表示するようになります。
-
コンポーネントグループの構成(Atoms, Molecules, Organisms, Template, Pages)
- Atom
これ以上分解できないデフォルトのコンポーネントです。Atomを結合してMolecule、Organism単位で有用に使用できます。 - Molecules
複数のAtomを結合して、独自の特性を持ちます。Moleculeの重要な点は一つ仕事をすることですね。 - Organisms
前のステップよりも複雑で、サービスで表現できる明確な領域と特定のコンテキストを持ちます。Atom、Moleculeに比べてより具体的に表現されるかつ、コンテキストを持つため相対的に再使用性が低くなる特性を持っています。 - Template
ページを作成できるように、複数のOrganism、Moleculeで構成できます。実際のコンポーネントをレイアウトに配置し、構造化するワイヤフレームです。 - Pages
ユーザーが見ることができる実際のコンテンツを盛り込んでいます。Templateのインスタンスと言えます。

- Atom
-
Storybookとのシナジー効果がある
StorybookはオープンソースのUIテスターツールです。 Storybookを使えば、UIコンポーネントを作成しながらすぐに描画内容を確認できます。
Storybookライブラリと連携でUI管理がもっとしやすくなります。(UIテストが簡単にできます。)

まとめ
Atomic Designをプロジェクトに適用しながら、感じたことについてまとめてみました。
- 実際に適用するにあたって曖昧な部分があり、コンポーネントのグルーピングの範囲や分類をプロジェクトに合わせて変形させました。(Organismの範囲外に想定されているコンポーネントはFeaturesという単位で管理するとか)
- 最初から明確な設計がされていないと途中でコンポーネントを再設計・再作成したり、再分類するケースも発生するので注意を払う必要がありました。(階層構造にもっと多くの段階を置くとか)
- デザインチームと開発チームの連携やコミュニケーションがすごく重要だと思いました。(デザインから Atom、Molecule、Orgaism に細分化されて設計されなければならないため)
- 各コンポーネントグルーピングの基準についての認識合わせが必要があります。
- 設計はデザイナーが担当して開発は開発者がするため、コンポーネント単位の体系化された設計になるためには開発者とデザイナーが一緒に会議で認識を合わせる必要があります。
Atomic Designはメリットとデメリットが確実に存在するため、適用する前にチーム全体として明確に理解して設計すれば協業しやすくメンテナンスが容易なフロント開発環境を構築できると思います。
お読みいただきありがとうございます。
参考
関連記事 | Related Posts
We are hiring!
シニア/フロントエンドエンジニア(React/Typescript)/KINTO中古車開発G/東京・大阪・福岡
KINTO開発部KINTO中古車開発グループについて◉KINTO開発部 :66名 KINTO中古車開発G:9名★ KINTOプロダクトマネジメントG:3名 KINTOバックエンド開発G:16名 契約管理開発G :9名 KINTO開発推進G:8名 KINTOフロントエンド開発G:...
【Java/Python】事業や組織の成長に携わるプロダクトエンジニア(AWS環境)/KINTO CXシステム開発G/東京・名古屋
KINTO CXシステム開発グループについてTOYOTAのクルマのサブスクリプションサービスである『 KINTO 』を中心とした国内向けサービスのプロジェクト立ち上げから運用保守に至るまでの運営管理を行っています。大手EC、SIer、ベンチャー、Webサービス企業など、さまざまなスペシャリストが集まり、KINTOサービスを開発しています。
Follow Us
KINTOテクノロジーズの最新情報をSNSで発信中!イベント・テックブログ更新情報もお届けします。
