Atomic Designの導入で押さえておくべき“決定ポイント”を書いてみた話

ブレインパッドの自社開発プロダクトチームのエンジニアが、UIデザインシステムの1つであるAtomic Designの導入までのプロセスと、その中で押さえておくと良い「決定ポイント」をブログにまとめました。
Atomic Designを実際に導入をしてみた感想としてメリット・デメリットについても紹介しています。

f:id:brainpad-inc:20210701093416p:plain

そろそろ中堅どころが見え始めている自社サービス開発エンジニアの子田です。

今回フロントエンド開発の環境を立ち上げる際に、Atomic Designを取り入れました。実際に導入してみて、事前に決定しておくとスムーズだろうと思うポイントがあったので、本ブログで紹介します。 これからAtomic Designを始める方や、やっているけど悩みどころがある方に少しでも共感してもらえたり、力になれば嬉しいです。

Atomic Designを導入した背景

現在の開発プロジェクトやフロントエンドの開発環境を踏まえ以下の内容を実現したいと考え、Atomic Designを導入しました。

  • コンポーネントの粒度・役割のばらつきを抑えて、生産性(実装・意思決定)と保守性を向上させたい。
  • ユーザーインターフェイスのレイアウトやページ遷移などが大きく変わることが想定されるため、影響範囲を限定したり、変更を容易にできるようにしたい。
  • OOUI的な視点で情報設計上のObjectに該当するコンポーネントをコード化して明示化したい。

上記内容の実現のため、押さえるべき"決定ポイント"と取り入れるまでのステップを紹介します。

Overview

Atomic Designの導入時、以下の項目を決めておくと良いかと思います。 まず前提条件を簡単に説明した後に、"決定ポイント"を押さえつつステップを紹介していきます。

"決定ポイント"の中での関連事項は以下のとおりです。 (下記のステップと対応はしていません)

  • 言語・フレームワーク
    • Nuxtjs、TypeScript、openapi、nodejs
  • 設計
    • コンポーネントの命名や振る舞いとページの構成
  • 開発環境
    • ディレクトリ構成、lint (vue, typescript)、IDE (VisualStudioCode, IntelliJ)
  • ソースコード
    • 利用API、state管理

前提条件

  • Nuxtjs を利用しているため、 ディレクトリ構造やvuejsの制約があります。
  • Typescript + OpenAPI openapi形式のyamlファイルから通信部分とpayloadを表すクラスを自動生成しており、出力ディレクトリと形式は固定の制約があります。 Atomic Design とは直接関係しませんが、コンポーネントの作成に関係します。
  • node 14.5.x(stable) ご共有までに記載しています。

Step of Direction Atomic Design

意思決定のステップは大まかに言うとこのように進められると思います。 各ステップについてポイントを書いていきます。

  1. Atomic Designの「導入する・しない」を決めるための準備をする。
  2. モジュールサイズ と 管理指針を決める。
  3. コンポーネントの設計指針を決める。
  4. コンポーネントの作り方を決める。
  5. その他雑多なこと ...。

1:Atomic Designの「導入する・しない」を決めるための準備をする

Atomic Designは銀の弾丸ではないのでまずは本当に「導入する」か「しない」かを決定し、導入した場合、「どんなことをしたいのか?」についてチーム内で共通認識をもっておくと進行がスムーズです。

✅ やりたいことを明確にする。目的を明確にして判断の軸を決める。

✅ MVP, Viper, MVVMなど他のアプローチ中に別の手法を実行したい。

✅ UI Component Frameworkを利用するから必要ない。

2:モジュールサイズと管理指針を決める

Atoms, Molecules, organisms, template, pages の粒度の概念があります。 これらをNuxtに当てはめて運用する必要があります。

✅ モジュールサイズを決めるためのディレクトリ構成を決める。

✅ サブグループ化したディレクトリの運用の可否を決める。

参考リポジトリ (h-tachikawa/nuxt-atomic-design-ts-example) を元に以下のディレクトリ構成にしています。

※ componentsにすべてのレイヤーやlayouts を除いた形もあるので、運用はその現場での決定内容に依存します。

<参考ディレクトリ例>
components/
  atoms/        ... 基本的にタグ1つで形成されるもの
  molecules/    ... 再利用がある複数タグのもの、または特定のorganismsで利用するもの
  organisms/    ... atoms, molecules で形成して用途が明確なものpagesが利用するもの
  layouts/       ... pages でレイアウト(テンプレート)利用するもの
  pages/        ... URLで表示するページ

また、コンポーネントは疎結合で再利用性が高いことが良い点ですが、対象のpages, organismsでの利用しかないものは用途別にディレクトリを分けて運用しています。

components/
   molecules/
      xxxx/
         someOrganismsComponent.vue
   pages/
      xxxx/
         somePageComponent.vue

3:コンポーネントの設計指針を決める

各レイヤーでのコンポーネントの表示面と機能面と命名規則について指針を決めます。

✅ vueが提供する機能の利用可能範囲を決める。

✅ コンポーネントの機能それぞれの命名規則を決める。

表示と機能面の調整表例

凡例:

○ コンポーネントでの定義利用許可

× コンポーネントでの定義利用不可

Layer css(scoped)利用 状態管理 タグ属性 備考
atoms o x o v-modelを実装するなど決めておくと良い
molecules o o o
organisms o o o
layouts x x x
pages x o x organismsとlayouts を組み合わせることで1つのpagesにできるようにする

命名規則の観点例

スネークケース、パスカルケースなどの形式と名詞、動詞などの命名規則を決めます。

カテゴリ 項目 description
タグ名 コンポーネント名 v2.15.x からコンポーネント名の解決が変わったので注意が必要
Props(Attribute) 種類 Input などタグ機能の切り替える属性名
装飾 フォントやマージンなど装飾関係の属性名
emit イベント名 emit のイベントと値の型名
変数・関数名 data binding object コンポーネントのtemplate内で利用する変数名
computed computed の名称
method template 内と外部向け関数名

4:コンポーネントの作り方を決める

✅ 利用するAPIをOptions/Composition から決める。

✅ 状態管理の方法をvuex/reactivity/other から決める。

✅ 状態管理の粒度感を決める、または決め方を決める。

✅ 共通で利用する定数やi18nのファイル置き場と運用方法を決める。

利用APIと状態管理方法

利用するAPIと状態管理方法があるので、バラバラにならないようにあらかじめ決定しておきます。

項目 Options API Composition API
props props: 同じ
data data: {} ref, reactive
method methods: {} setup() { const fn =()=>{}; return { fn} }
state $store useStore(), provide/inject
emit emits: ['xxxx','yyy'] 同じ

状態管理の粒度は、コードの可読性と保守性にかかわってきます。 そのため、失敗するとバグの温床になったり、進捗に影響を及ぼすことがあります。

その点へのアプローチは、あらかじめサイズ感を決めておくアプローチと、設計のフェーズで決めるアプローチと、どちらのアプローチでも可能だと思います。 どのアプローチで進めるのか、合意形成しておくと、開発時に決定しなければならない時間のコストを削減できます。

constant variable, i18n

  • constant variable : 単一ファイル定義または、個別コンポーネント内に定義などの作法を決める。
  • i18n:Jsonファイルに定義になるので、ページ単位などでまとめるなどJsonのデータ構造を決める。

5:その他

✅ vue template, typescript のlintやIDEの設定共通化をしてCoding styleのばらつきを抑える。

✅ ビジュアル・インタラクション・ロジックテストなどをどうするかを決める。

参考:1年間単体テストを書き続けた現場から送る Vue Component のテスト

感想

Atomic Designを導入してみて、以下のようなメリットとデメリットがあるなと思いました。

メリット

  • タスクの分解粒度が決めやすくなった。
  • レビュー観点・範囲が決まりやすくなった。
  • テスト設計時にインタラクション、ビジュアルテストなどの適用範囲の整理が容易になった。
  • 情報設計の反映やチーム参画時にキャッチアップする点が明確になった。

デメリット

  • チームに後から入った人はキャッチアップの作業・作法が多くなった。
  • 画面の作成時にコンポーネント構成の設計について認識合わせが大変になった。(画面が複雑になると特に)

参考リンク

ブレインパッドでは、開発エンジニアやデータサイエンティストを積極的に募集しています。サービス開発やそのサービス運用を支えていただける方、新卒採用・キャリア採用ともにご応募をお待ちしています!

www.brainpad.co.jp