巨大複雑VueコンポーネントをComposition APIへ書き換えて得られた知見

## [オンライン開催【シューマイ】Tech Lead Engineerから最新技術を学べ！Vue.js編](https://shuuu-mai.connpass.com/event/196096/)
[![Screen Shot 2020-12-02 at 17.03.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/4224061f-0cf1-4c5b-5e72-c28b201cc327.png)](https://shuuu-mai.connpass.com/event/196096/)

---

## はじめに

Vue Composition APIをつかって巨大複雑コンポーネントを書き換えた体験談をします
![382326.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/7e72a538-2e68-8794-cc50-b3ae776a4d90.jpeg)


対象は下記の方を想定しています

 - 可読性の高い、クリーンな設計を行いたい
 - リリースからサービスが順調に成長し中〜大規模になってきた
 - Composition APIを検討している,触り始めている

---

## やること, やらないこと

### やる :thumbsup: 
Composition APIで複雑にどう立ち向かうか、考え方の紹介
### やら :thumbsdown: 
細かい実装については割愛。コードもほとんど出てこないので楽に聞いてください

**ざっくりと、Composition APIがどんなものなのか掴んでいただければと思います**

---

## 自己紹介

![Screen Shot 2020-12-02 at 16.00.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/ff0ca7ea-e246-efbd-bee7-920fd89c9fd3.png)
シェアフル株式会社,フロントエンドエンジニアの福田京平です。

最後に写真撮ってから一年以上髪の毛を切っていないので別人になっていますw

会社の外では[個人でサービスを運営しており](https://labelmake.jp/) 、[運営者ギルドというコミュニティ](https://qiita.com/organizations/admin-guild) にも参加させていただいております。


OSSは最近あんまりできていないけど、[自分でライブラリ作ったり](https://www.npmjs.com/package/labelmake) issue立てたり翻訳をしたりです。
主にReactが多いですが雑食です。

**開発者友達募集中**なので[github:hand-dot](https://github.com/hand-dot)と[twitter:labelmake](https://twitter.com/labelmake)などフォローしていただけば嬉しいです..!!

---

## 会社紹介
![SnapCrab_NoName_2020-6-6_17-39-42_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/6b082333-63db-f587-8483-85a813b87174.png)
シェアフルはパーソルホールディングスとランサーズの合弁で作られた全く新しい会社で
**1日単位のお仕事のマッチングプラットフォームを開発し提供しています。**

開発チームもサービスを体現するべく、副業・フリーランスの方が多く、様々な人とモダンなフロントエンド技術で開発ができます。

**1日で入って1日で抜けられる開発組織を目指しています！**

---

## 技術スタック紹介

![Screen Shot 2020-12-02 at 14.16.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/77564577-3a92-c145-8059-b808f0dc3ed2.png)


様々な技術を採用しています。言語以外にも新しいツールも入っていてモダンな環境で開発できます。
フロントはReact-Nativeでios,androidのアプリを開発していて、Nuxt.jsで求人登録するクライアント様の管理画面を作っています

もし興味がある方は[wantedly](https://www.wantedly.com/companies/sharefull)や
自分の[github](https://github.com/hand-dot)か[ツイッター](https://twitter.com/labelmake)からも絡んでいただけると...!

---


## なぜComposition APIへ書き換えたの？

リリースからサービスが順調に成長し
MVPのプロダクトから中規模〜大規模程度になったためいくつかの問題がありました

リリースしてから時間の経過、機能の複雑化とともに求人登録画面のコンポーネントがとんでもないことに...

![15t.kiki7_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/960c8eb3-8509-cafe-e772-61a9c0defdf8.jpeg)


- 機能追加に対して速度がでない
- 開発しているのか壊しているのかわからなくなる
- コンポーネントがデカすぎて新人さんにこういうこともありますよね みたいな顔される

どうにかしないと..

---

## 最初はあんなに可愛かったコンポネントさん、少し目を離したらどうしちゃったんだろうね？

![howl_sophie_castle-330x220.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/735f38ca-34c3-93a4-7891-2c8b09d110cf.gif)


- 読みにくい:thumbsdown: 
- メンテナンスしにくい:thumbsdown: 
- 再利用しにくい:thumbsdown: 

時間の経過と共に大規模に,機能の追加に伴って複雑化していくコードに対して

なんらかのアプローチが必要でした

---

## 具体的になぜComposition APIなの？

シェアフルでは一年近く前からComposition APIを導入し少しずつ書き換えています。

大規模開発で弱いと言われていたVueでComposition API化し、

- **型推論:thumbsup:**
- **関心の分離:thumbsup:**

の観点でコードの品質を高めることができます。

(Composition APIは一部に導入,既存のコードと併用ができます)

---


## この巨大複雑コンポーネントどうしてこうなっちゃった？

![382326.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/f842cb90-4de1-9b5e-3ab6-6147ed2765f6.jpeg)


Composition APIで何をするかではなく、一歩下がって何故この巨大複雑コンポーネントができあがったのでしょうか？

**一般的な流れを検索コンポーネントを例にみていきましょう。**

---

## 純粋無垢なサーチ
![Screen Shot 2020-12-02 at 15.12.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/10cf2af4-2bea-f0dc-1c8c-fa0c7561484f.png)

---

## 並び替えを要求された元サーチ
![Screen Shot 2020-12-02 at 15.12.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/0b72e522-8f0c-f20c-5e21-a97bc195fcc6.png)

---

## 要求は続く

![Screen Shot 2020-12-02 at 15.35.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/2ac67d05-93f2-3943-5f93-e1df4aebe791.png)


- ページング 
- お気に入り検索条件
- 検索履歴
- etc...

あちこちに新機能のためのコードが散らばります。

**サーチ、最近変わったよねと噂されみんなから距離をおかれるコンポネントに...**

---

## どうすればよいのか？

**機能・関心（何をしたいのか）毎に分離し整理する必要があります**
![Screen Shot 2020-12-02 at 15.13.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/ef03e1a9-8fbd-15a7-18fb-ecc8a7c356d5.png)

さきほどのサーチをComposition API化するとこのようになります
![Screen Shot 2020-12-02 at 17.25.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/bade19c6-1dbc-2e21-c68b-73d7cfc99642.png)



さらに"検索"と"並び替え"のロジックを別のファイルに切り出す
![Screen Shot 2020-12-02 at 15.21.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/d19ee1f7-8661-f208-c00f-1a07ae27b4d8.png)


Composition APIで書き換えて関心に基づいて分離し、ファイルを分けることで
コンポーネント内をあちこちジャンプしなくても何で構成されているのかわかります。

<!-- setupの中のコードはこのコンポーネントを口で説明しているようなコードになります -->

---

## 銀の弾丸はない

![silverbullet-2020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/2f542d4b-af71-2423-afbd-966f1cd98aed.png)

Composition APIをつかうことでコードを整理しやすくなりますが、元のコードに比べてファイル数は増えるし、コードは少しだけ冗長になります。

**Composition API はコード品質の上限を上げる一方で、下限を下げることにもなります。**

というのは、これまでのOptions-based APIに比べるとフレームワークの部分が薄くなり、自由度が増すためです。

**Vueコンポーネントから剥がしたTypescriptファイル中心の開発にすることで求められるのはシンプルなプログラミング力と設計力。**

逆にいうと整理されたTypescriptのコードを書くことはComposition API を使うことで整理されたVueコードを書くスキルに直結します。

---

## 共通認識

![Screen Shot 2020-12-02 at 16.49.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/279c9db4-4f9a-8b77-d47b-05a9a7f95840.png)


自分が大事だと思ったのは、

**単にコードの書き方をComposition APIにするのではなく、
今後のためにコードを綺麗な形に保ちやすくしようというチームの共通認識です。**

具体的なアクションとしてシェアフルでやったことはモブプロを行ってみんなで書き換えていくことをやりました。

**モブプロの振り返りの中で有識者へ質問ができる環境をつくって共通認識を育てていく。**

関心に基づいて分離していくのは一定の経験が必要になってくる場合もあるので、レビュワーは判断ロジックを明文化したり、説明することでチーム全体で同じ美意識を持てると考えています。

---

## 振り返って(サービス観点)

![Screen Shot 2020-12-02 at 16.28.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/ce57aefd-cc92-c1fb-9d72-be51b86569d9.png)


- 巨大コンポーネントが分離されたことで**見通しの良さが明らかに上がった**
- **読み方を知っていれば**、関心に基づいて整理しているのでファイルが増えてもコードが増えても***精神的に絡み合ったコードが減ったように感じることができる*
- フレームワークから分離するので単体テストがしやすい
- 一気にリファクタして一斉リリースではなく、毎回のリリースにComposition API化したものを少しづつ入れていく感じで書き換えています

---

## 振り返って(プログラマ観点)

![kelly-sikkema-YK0HPwWDJ1I-unsplash.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/d74305f5-8060-243f-1d17-a29fd3736fe7.jpeg)



ReactのHooksもそうだけどフレームワークから`this`が取り除かれ、
結果としてフレームワークが魔法的なものから、よりシンプルで薄いものになってきた印象。

Vue,Reactは魔法ではなく、仮想DomはめっちゃすごいinnerHTMLなんだということを再認識させられる


**これからは「フレームワーク力」よりも「プログラミング力」の方が大事になってくるかなと思っています。
フレームワーク任せにしない設計力も重要になってくると感じました。**

---

## 興味をお持ちいただけたら

![Screen Shot 2020-12-02 at 18.28.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/11eeeb18-2886-ef06-cdb5-9d195c67f550.png)

導入は `@vue/composition-api` を追加することで、Vue2系でも簡単に使用できますのでぜひお試しあれ！

ドキュメント
RFC: https://composition-api.vuejs.org/
API: https://composition-api.vuejs.org/api.html

---

## Back to basics

基礎に戻ってVueのこの先の進化もみんなで楽しんでいきましょう！

### [Clean Architecture](https://amzn.to/36v3owl)
[![Screen Shot 2020-12-02 at 15.54.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/12c312b3-3a7b-6740-d404-b8ff02b004aa.png) ](https://amzn.to/36v3owl)

### [Code Complete](https://amzn.to/33xTyI0)
[![Screen Shot 2020-12-02 at 15.54.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/41c9218d-6607-7704-95f0-df4e8a91c4ae.png)](https://amzn.to/33xTyI0)

参考資料:

- https://composition-api.vuejs.org/ 

---

## ありがとうございました

福田京平

![Screen Shot 2020-12-02 at 16.00.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/ff0ca7ea-e246-efbd-bee7-920fd89c9fd3.png)

[github:hand-dot](https://github.com/hand-dot)
[twitter:labelmake](https://twitter.com/labelmake)