施工管理チームにおけるVueコンポーネント設計

どうも、施工管理チームのフロントエンドを担当している藤井です。

 

今回うちのチームで取り組んでいるVueプロジェクトのコンポーネント設計の移り変わりについてご紹介したいと思います。

 

別で存在する新規プロジェクトチームの方では、Vue/NuxtやTypeScript使ったりと、色々な取り組みをしているのですが、ANDPADの本体サービスは基本的に、Rails + Angular v1で成り立っています。(jQueryも入ってたりも)

 

そんな中で、実は本体の「(新)工程表」というサービスと「写真出力」という機能の一部は、最近Vue.jsで書かれています。(旧)工程表から(新)工程表への置き換えプロジェクトはだいたい2018年から約1年。そして写真出力の一部の置き換えは2019年の4月から約2ヶ月がかかっております。私がこのチームに入ったのは2019年の3月中旬でして、その際はまだ工程表というサービスのみがVueで作られていました。

 

f:id:yohei-fujii:20190607144908p:plain
(工程表のサンプル画像↑↑)

 

 当時、特にコンポーネント粒度等は仕分けされておりませんでした。そのため、中には1000行を超える巨大なファイルが存在したりしていました。しかし、とはいってもそれは一握りであり、適度に切り分けられ、肥大化していないファイルもありました。

 

その時のコンポーネント設計↓↓

|- components
| |- common
| | |- CommonHeader.vue
| |- workload
| |- WorkLoadItem.vue
| |- WorkLoadModal.vue
| |- .....
|

 

初見で思ったのは「粒度の仕分けもされていないし、メンテナンスしにくいな。」ということです。小さいコンポーネントも大きいものも混在している状態でした。「パーツとか使いまわせるものあるし整理しよう!」ということで、一度Atomic Designを意識した設計に変更しました。

 

|- components
| |- atoms
| |- molecules
| |- organisms
| |- templates
| |- pages
|

 

「よし!綺麗になったぞ!」これで新しく人が携わることになっても、粒度で別れているから理解しやすいだろうと思っていたのです。実際、工程表というサービスだけの時は、問題ありませんでした。

 

めでたし、めでたし!

å¬ãã表æã®ç·æ§ã®ã¤ã©ã¹ãï¼5段éï¼

 

 

しかし、次にANDPADの別の機能をVueで開発しようとなりました。それが「写真出力」のドラッグ&ドロップ機能です。

 

 

f:id:yohei-fujii:20190607145115g:plain

(開発途中のサンプル↑↑)

 

ここで、悩みが始まります。

さて、コンポーネント設計をどうしようかと。

 

今のAtomic Designベースのディレクトリに、写真出力のVueファイルもポコポコと入れていくのがいいかなと思って途中までやっていました。

 

|- components
| |- atoms
| |- molecules
| |- organisms
| |- PhotoOutputEditArea.vue
| |- PhotoOutputSelectArea.vue
| |- ....
| |- WorkloadItemModal.vue
| |- WorkloadChart.vue
| |- ....
| |- templates
| |- PhotoOutput.vue
| |- pages
|

 でも、気づいたのです。

「これ、もしかして他のサービス機能とかもVueで作るってなった時に、中でカオスになるよね・・・・。」同じ粒度だからと言って、どんどん同じディレクトリに入れていくと、今後大きくなってきた時に、様々な違った機能のパーツが混在していくことになります。

 

「まあ、ひとまず2つのサービスでしか使ってないからいいかぁ」その時はあまり深く考えずにそのまま進めました。

 

そして1ヶ月が過ぎます。

 

å¹³æãã令åã«å¤ããã«ã¬ã³ãã¼ã®ã¤ã©ã¹ã

 

 

すると、次に別のチームが「そっちでうまく行ったから、こちらのプロジェクトでもVueを使いたい!」と出てきます。

 

 

さぁここで本格的に頭を悩まします。

 

é ­ãæ±ãã¦æ©ãã§ãã人ã®ã¤ã©ã¹ãï¼ç·æ§ï¼

 

別のチームといっても、同じリポジトリを使っています。管理という面からも、必然とVueファイルは同じディレクトリを使っていくことになります。このままAtomic Designを続けていってもいいのですが、organismsの中に様々なプロジェクトのコンポーネントが混在することになるからです。atomsとmoleculesは共通部品と当初より考えていたのでよかったのですが、流石にorganismsくらいの大きさになると共通部品がほぼありません。混在させても良いのですが、見通しが悪くなります。また、今後どんどん別サービスがvueを採用していく可能性も否めませんので、そうなると整理するためにorganismsの下にまたプロジェクトディレクトリを作ることになります。そうすると、何が起こるかというと、templatesやpagesのディレクトリでも同じプロジェクトディレクトリを作ることになりました。

 

|- components
| |- atoms
| |- molecules
| |- organisms
| |- photoOutput
| |- PhotoOutputEditArea.vue
| |- PhotoOutputSelectArea.vue
| |- ...
| |- workload
| |- WorkloadItemModal.vue
| |- WorkloadChart.vue
| |- ...
| |- ....
| |- templates
| |- photoOutput
| |- PhotoOutput.vue
| |- ....
| |- pages
| |- workload
| |- workload.vue
|

 

うううう、これはやだなぁ。

 

もともとNuxtに切り出すプロジェクトもありますし、その点を考慮し、見やすい設計を模索していました。技術顧問や外部の人にも相談して、行き着いた答えが、「atomsとmoleculesはcomponents配下におくが、organisms以上のコンポーネントは各プロジェクトディレクトリ配下に置く」ということでした。

 

|- components
| |- atoms(共通)
| |- molecules(共通)
| |- photoOutput(独自)
| |- organisms
| |- PhotoOutputEditArea.vue
| |- PhotoOutputSelectArea.vue
| |- ...
| |- templates
| |- PhotoOutput.vue
| |- workload(独自)
|- organisms
| |- WorkloadItemModal.vue
| |- WorkloadChart.vue
| |- ...
| |- pages
| |- workload.vue
|

  

こうすることで、何が良いかというと、粒度の責務の切り分けができるようになりました。atomsとmoleculesは共通パーツとして使うもの。それ以上のoraganismsは各プロジェクトで独自のものというふうに分けることができます。

 

またそれと同時に、一番のメリットは、今後Nuxtへの移行を見据えた際に、移植しやすい構造にもなっております。その際にatomsやmoleculesに関しては、andpad-uiという社内フレームワークに切り出すが可能です。そうすることで、各プロジェクトで持つatomsやmoleculesのパーツは独自の必要最低限のものとなり、コンポーネント管理がしやすくなります。また、統一されたデザインパーツを使うことにより、デザインの統一性が計れることがわかりました。 

 

atomsなどのパーツに関しては、「先にコンポーネントをUIライブラリで作った方が良いのでは?」という意見もあると思います。しかし、以前の経験から先にコンポーネントを準備するということはしないことになりました。というのも、時間をかけてパーツを作っても、結局使わないものが出てくるからです。

 

以前、たくさんのボタンを時間をかけて設計して準備したのですが、結局使われているのはほんの一部ということがありました。

 

リソースが限られている中では、こちらでも紹介されているように、YAGNIって大事だということを身をもって体験しました。

 

qiita.com

 

Nuxt移行の段階で切り出したりすることで、サービス横断で本当に必要なパーツがリストに並ぶということになるのです。

 

 

以上のことから、現在ANDPADのフロントでは、Atomic Designを応用したコンポーネント設計を取り入れてます。今後もっと良い適した設計が現れるかもしれません。その際には柔軟に対応していこうと思います。

 

最近は、社内でフロントエンドに携わる人も増えてきて、社内ルールもまとまってきており、そのことから開発スピードは格段と上がっているように感じます。今後もVue.jsでの置き換え範囲は拡大していく予定です。