Vueコンポーネント設計について

f:id:branu_techblog:20210929150153p:plain


今回は Branu のフロントエンドチーム(Web ブラウザ版対応チーム)でのコンポーネント設計についてご紹介します。

「CAREECON for WORK 施工管理」ではVue/Nuxt&TypeScriptを使って開発されています。 私がジョインする前は(開発初期段階)は特にコンポーネント設計等は考えず、src/components 配下にあらゆるコンポーネントが積み込まれている状態でした。

こんな感じ

|- src
|   |- pages
|   |- components
|       |- containers
|           |- xxx.vue
|           |- .....
|       |- xxx.vue
|       |- .....
|

 

ここで問題となったのが、

コンポーネントが使い回されておらず、機能改修した際に、同一UIでも別々のコンポーネントを修正しないといけない

どこに、A機能コンポーネントがあるのかわからない

などの問題が浮上してきました。 この問題が起きたのは、もともと開発していた方々が別プロジェクトへ移動してしまい、新しくジョインした私が抱えた問題でした。

さすがにこのまま開発を続けると新機能が追加されるたびに可読性が下がりメンテナンスが行いづらくなってしまうので、今後新しく入ってくるメンバーのためにもコンポーネント設計をちゃんとしておこうと思いチームメンバーに問いかけました。

 

AtomicDesignを用いたコンポーネント構成案

私たちが取り入れたのは、Atomic Designを意識した設計です。 AtomicDesignを意識したと記述したのには理由があり、きっちりと、「このコンポーネントatomsである!!」ということはせずに、そこは開発者の考えに任せるとして、 AtomicDesignを意識した構造になっていればよしとしました。

考案したのが下記2パターンです。

patternA

f:id:branu_techblog:20210927170646p:plain

components配下にatoms, molecules, organisms, templatesを用意しておき、各粒度にあったコンポーネントを作成していく。

patternB

f:id:branu_techblog:20210927170722p:plain

components配下に各機能とcommon(共通コンポーネント)を用意しておき、その配下に、 atoms, molecules, organisms, templatesを用意する。

 

チーム内の課題

  • 各機能で共通されているものは共通するコンポーネントを使いまわしたい
  • 各機能でしか利用されないコンポーネントも存在するのでそこを明確化したい
  • わかりやすくするために、templatesとpageは基本的に1対1を保ちたい
  • 後から入ってきたエンジニアもすんなりとコンポーネント構造を理解できる形にしたい

上記課題を解決するために、patternBを採用しました。

 

理由

  • 各機能によってフォルダー分けされていることで、後から入ってきたエンジニアにとってわかりやすいと判断。
  • commonディレクトリと各機能のディレクトリを用意することで、全体で共通されているコンポーネントと各機能でしか利用されないコンポーネントを明確化
  • 各機能ごとにチーム分けをする際にもわかりやすい

 

まとめ

運用して約1年が経過していますが、現状大きな問題もなく運用できています。 とはいえ、これが100%正解というわけではないと思っています。今後も改善を続けてよりスピーディーかつ、ユーザーにとって価値のあるプロダクトを開発するための最善を考えていきたいです。

また、今後の課題は、各エンジニアによってコンポーネントの粒度が変わってくるところを統一化していけたらより開発は楽になりそうだなと考えています。 ガチガチにルールを作ってしまうのもエンジニアにとってやりづらくなり、ルールがなさすぎるのもメンテナス性が下がるのでバンラスよく設計していきたいです。