🤗

Atomic designを辞めて利用目的別のディレクトリ構成に移行する

5 min read

かれこれ4、5年くらいAtomic designに触れてきて、こんなに使いづらいのになんで使ってるんんだっけ?ってなったので、脳死と妥協のAtomic designを辞めたいというモチベを高め、重い腰を上げて考えてみました。

前提

今回の趣旨はあくまでも共通コンポーネントにフォーカスしています。なのでpages(人によってはscreens,containersと命名しているかも)は考慮しません。

また、atomic designのデザインサイドの思想そのものについては言及しません。あくまでもディレクトリ構成の運用上の課題にフォーカスします。

ディレクトリを分ける意味とは

そもそも、components/配下をフラットに並べずにグルーピングする目的は何でしょうか。

使いたいものが明確な場合はディレクトリ構成はあまり寄与しません。「あのButtonコンポーネントを使いたい」であれば、ディレクトリ構成を意識せず、cmd + pなどで直接アクセスしにいくはずです。また、実際にコードを書く際はTSのコード補完を使うのでimport pathを書くことさえしないはずです。

ディレクトリ構成はコンポーネントアクセシビリティの肝であり、抽象化の指針となるもの

利用したいコンポーネントが明確でなかったり、そもそもどんなコンポーネントがあるのかわからない場合はディレクトリ構成が大事になってきます。特にコードベースに慣れていないエンジニアにとってはディレクトリ構成はオンボーディングの手助けになるものです。

また、実装時にコンポーネントを抽象化(共通化)する際、既存のディレクトリ構成は良くも悪くも指針となります。多くのエンジニアは既存ディレクトリ構成に従って抽象化を試みます(中には自己流でぶち壊す人もいますが、、)

components/配下のディレクトリ構成はコンポーネントのアクセシビリティを高め、良い抽象化を促すものである必要があります。

Atomic Designを見つめなおす

  • atoms
  • molecules
  • organisms
  • templates

templatesがなかったりlayoutsやpagesがあったりと亜種はあるものの、だいたいこんな感じになります。具体的な説明はあちこちにあるので省きますが、atomic designは、componentを物質的な分類学に基づいてグルーピングします。 原子が分子を構成し、分子が集まって有機体ができ、さらに有機体が集まるとテンプレートになり、、といった具合です。

分類しやすいが、探しにくい

物質的な分類は、コンポーネントを分類する際の指針には役立ちます。moleculesとorganismsの違いは?等の境界線の難しさはあれど、ある程度機械的に分けることができます。

しかし、物質的な観点で機械的に分類されたものは非常に探しにくいです。理由は単純で、UX観点で分類されていないからです。エンジニアも人間です。UX観点のない分類学が使いやすさや探しやすさに寄与するはずがないのです。

つまり、Atomic designは抽象化の指針としては優秀だが、コンポーネントのアクセシビリティを高めるものではありません。

コンポーネントアクセシビリティの高いディレクトリ構成とは

Atomic designが、UX観点のない分類がために探しにくさにつながっているのはわかりました。じゃあ探しやすい分類ってなんだとなるわけですが、無責任なことにわかりません。ただ、より意味のある分類、よりそのUIの利用目的にあった分類であるべきなのではという仮説があります。

デザインシステムに学ぶ、探しやすいグルーピング

よく考えれば、我々が日々使う共通コンポーネントの構成のヒントはインターネットにも転がっています。最近は質の良いUIライブラリも増えてきて、彼らがどのように分類しているかを見るのは参考になりそうです。

ant designを見てみる

https://ant.design/components/overview/

ant designは数あるReact UIライブラリの中でも成熟した質の高いライブラリです。ant designのコンポーネント分類はどうなっているのでしょうか

分類名 コンポーネント 目的
General Button, Icon, Typography 全般
Layout Divider, Grid, Layout, Space レイアウトに使う
Navigation Affix, Breadcrumb, Dropdown, Menu, Pagination, PageHeader, Steps ナビゲーションに使う
Data Entry AutoComplete, Checkbox, Cascader, DatePicker, Form, InputNumber, Input, Mentions, Rate, Radio, Switch, Slider, Select, TreeSelect, Transfer, TimePicker, Upload データ入力に使う(フォーム)
Data Display Avatar, Badge, Comment, Collapse, Carousel, Card, Calendar, Descriptions, Empty, Image, List, Popover, Statistic, Tree, Tooltip, Timeline, Tag, Tabs, Table データ表示に使う
Feedback Alert, Drawer, Modal, Message, Notification, Progress, Popconfirm, Result, Spin, Skeleton ユーザーへのフィードバックに使う
Other Anchor, BackTop, ConfigProvider その他

いかがでしょうか。Atomic design的な物質的な分類ではなく、目的別の分類になっていることがわかると思います。

ant design特有なものを見せられても、、となるかもしれません。しかし、意外にも他のライブラリをみても共通点が多いのです。

各ライブラリ比較 (antd, material-ui, chakra-ui)

ant designに加え, material ui, chakra uiを比べてみました。

https://next.material-ui.com/getting-started/installation/
https://chakra-ui.com/docs/getting-started

共通する分類

それぞれ違うように見えますが、5つも共通する分類があります。

  • layout
  • forms(inputs, data entry)
  • navigation
  • feedback
  • data display

意外と思う方も多いかもしれませんが、この実績ある3ライブラリが共通するということは割と説得力のある分類と言えそうな感じがします。また、otherという分類はantdとmaterial uiに共通する項目でした。

相違点

分類に関して上記の共通する5件を除けば、違いは数件のみです。

  • ant design
    • general (Button, Icon, Typography)
    • other
  • material ui
    • surfaces
    • utils
    • labs
  • chakra ui
    • typography(antdではgeneral/)
    • overlay(antd, materialではdata display/)
    • disclosure(antdではnavigation等)
    • media and icons(ant designではgenerarl/)
    • others

antdとchakraはotherがかぶっているので、かなり似た分類をしていることがわかるかと思います。

分類意外の相違点として、同じ分類でも内容が異なることはあるようです。例えばButton。chakraではforms内にButtonを置いていますが、AntdではButtonはgeneralにおいています。Buttonはform意外でも使うからということでしょう。Modalはmaterial-uiではutil,chakraではoverlay, antdではfeedbackといったかたちで扱いに差があるようでした。

利用目的別のディレクトリ構成

以上を踏まえ、ant design, material ui, chakra uiをベースにしたディレクトリ構成案です。
atomic designと同様に、プロジェクト似合わせて足し引きをしながら使うイメージです。場合によってはotherなどを加えてもいいでしょう。

分類名 コンポーネント例 目的
General Button, Icon, Typography 全般に使うもの
Layout Divider, Grid, Flex, Box, Stack レイアウトに使う
Navigation Breadcrumb, Dropdown, Menu, Pagination, PageHeader, Steps, Tabs ナビゲーションに使う
Form TextField, Checkbox, DatePicker, Radio, Select, Toggle データ入力に使う(フォーム)
Data Display Avatar, Badge, Comment, Collapse, Carousel, Card, Calendar, Descriptions, Empty, Image, List, Popover, Statistic, Tree, Tooltip, Timeline, Tag, Tabs, Table データ表示に使う
Feedback Alert, Drawer, Modal, Toast, Notification, Progress, Result, Spinner ユーザーへのフィードバックに使う
Util Portal, Transition util系

うまくいくのか?

どこかで実践してみようと思います。多くの場合うまくいきそうですが、銀の弾丸というわけでもないので困難もありそうです。

  • 複雑なUIを抽象化したい時に場所に困る?
  • Data Displayが肥大化する

特に後者はドメインが複雑だと、UserInfo, ProductCardのようなドメイン固有なものが増える可能性がありそうです(個人的にはそもそも早すぎる抽象化を避けることで破綻を防げるのではと思っています)。

やってみてまたプラクティスが見つかったらその時はまた共有できればと思います。

Discussion

ログインするとコメントできます