Vueを使ってサイトを1ヶ月で作った話。そして、それを、1ヶ月使ってリプレイスした話。

この記事は[Ateam Hikkoshi Samurai Inc. & Ateam Connect Inc.（エイチーム引越し侍、エイチームコネクト） Advent Calendar 2019](https://qiita.com/advent-calendar/2019/hikkoshi) 9日目の記事になります。


## はじめに

「引越し侍　まるごとスイッチ」
https://hikkoshizamurai.jp/switch/

というサイトを12月2日にリリースしました。
引越しの際に必要な、電気やガスの切り替えが一括で行えるサイトで、
ゆくゆくは水道や金融機関、郵便など、引越しにまつわる、様々な手続きをサポートしていく予定です。

この記事は、このサイトをVueを使って1ヶ月で作った話。
そして、それを1ヶ月使ってリプレイスをした話をします。

簡単でテンポよく開発できる`Vue.js`、`Nuxt.js`を設計せずに使うとどんなことが起こるのか、
どうすれば、`Vue.js`、`Nuxt.js`の良さを活かしつつ、開発ができるのか
是非見ていってください！

## TL;DR
- `Vue.js`、`Nuxt.js`は簡単に使える。
- が、、故に、きちんとやらないと破綻する。
- どんなに急いでいても、コンポーネント設計やVuexの設計、準備はきちんとしようねという話

## 背景

「引越し侍　まるごとスイッチ」
https://hikkoshizamurai.jp/switch/

実はこのサイト、
内閣官房が推進している引越しワンストップサービスというものの協力主体として、
弊社が参画し、作ったサービスになります。

制作に与えられた期限は約2ヶ月半。
（最初の半月はDB設計等をしていたので、フロントに与えられたのは実質2ヶ月）
限られたリソースの中で、仕様を詰めながら、
どんなサイトにするかを考え、作る。（もちろんバックエンドも、管理画面も）

その中で僕たち制作メンバーが選んだフロント技術は`Vue.js`、`Nuxt.js`です。

`Vue.js`の良さは、簡単で柔軟性の高いというところ
`Nuxt.js`の良さは、開発スピードが出せるという点です。

ですが、その良さの反面、きちんとした設計をしないと、すぐに破綻する時がやって来ます。

この記事では、`Vue.js`、`Nuxt.js`を使って1ヶ月でβ版を作った話。
そして、それを1ヶ月使ってリプレイスした話をします。

最初の1ヶ月で何があって、残りの1ヶ月で何をしたのか、是非、見ていってください。

## 最初の1ヶ月

最初の1ヶ月、我々制作チームが奮闘したのは、とにかく早くリリースをするという点でした。
いわゆる`βリリース`のようなものが1ヶ月後にあったのです。

そうです。時間がなかったのです。。
みんなで決めて、とりあえず開発速度を意識した実装をすることにしました。
そして、**（来ることは知ってたけど、思ったより早く）訪れたこと**

- コピペ地獄
- どこか修正するとどこかがバグる
- Vuexに入れていたはずのデータがどこかで書き換わってる
- 書き方が統一されていない
- 変わり続ける仕様に対応できない

開発しはじめて、1ヶ月しか経っていないにも関わらず、こんなことが起きていました。

## なぜこんなことになったのか？

### コンポーネント設計をしなかった
これが、最大のミスです。
弊社では、他のプロジェクトでも`Vue.js`や`Nuxt.js`を使った経験があり、
その時はしていたはずのコンポーネント設計を怠りました。
これにより、コピペの嵐、何か仕様変更があると、全てを書き換える必要がありました。
当然、どこにバグを埋め込んでしまったのか検討もつかない状態になりました。

### Vuexを乱用しすぎた
何でもかんでもVuexに入れているプロジェクトをよく見ますが、
Vuexの乱用は完全なアンチパターンだと思っています。
思っていたのにやったのです。。

すると、あるページで変更した内容が他のページに来た時にも反映されていたり、
値がなくて落ちたりするのです。。


### Linterを無視した
途中で流石にやばいと思って、コマンドを打って見たんです。

```bash
yarn lint
...
3043 problems
```

おわた :angel: 

```bash
yarn lint --fix
```

をする勇気もなく、したところで解消できる数ではなさそうなので、そっとしておきました
こうして、書き方がバラバラのプロジェクトができあがりました。


## 残りの1ヶ月

なんとか一時的にリリースを果たしましたが、、

**このままでは、ダメだ**

このまま行くと、必ず破綻する。
リリース後、誰も触りたくないプロジェクトになってしまう。

仮のCSSだったので、本リリースまでの間にCSSをフルチェンジする必要があった我々は、
このタイミングで、きちんと話をして、コンポーネント設計やVuexの設計をする時間を設けました。

以下は、残りの1ヶ月でやったことです。

### コンポーネント設計をした

他のプロジェクト同様、`Atomic Design`を採用しました。
きちんとチケットにどの粒度でコンポーネントを切るか明記し、
迷った時は議論しながら進めました。

`atoms/ molecules/ organisms/`でディレクトリを切って、
どこに何のコンポーネントを入れるか話し合いながら決めました。

もしコンポーネントの切り方に興味のある方は、以下のURLで
簡単なタスクリストを作るアプリケーションを作って見たので、
実際に手を動かすとなった時に、参考にしていただけると幸いです。

https://codesandbox.io/embed/atomic-sample-137cy?fontsize=14&hidenavigation=1&theme=dark

### Vuexを極力使わないようにした
改めて言います。
Vuexの乱用はアンチパターンです。
きちんとその性質を理解して使うようにしてください。

Vuexは便利な一方、どこからでも値の参照や格納ができてしまうグローバル変数です。
使い方を誤れば、どこかのページで格納したデータがどこかのページに来た時に反映されていたり、
書き換わってしまっていてバグが生まれます。

そして、我々のチームで、定めたルールが以下の通りです。

**1. ページをまたいで、データを保持したい時以外は使わない**
ページをまたがないデータ保持は、一番上の親にデータを持たせて、
`v-model`、`v-bind`、`v-on`を使えば解決します

**2. ページをまたいで必要な時も、値の格納は一回しかしない**
一つのモジュールで値の格納があるのは一回で十分だと思います。

**3. ページをまたいで必要な時も、`<nuxt-child>`で代用できないか考える**
`nuxt-child`は`Nuxt.js`のページ単位で親子の関係を作ることができます。
1とほぼ同様で、親にデータを持たせたいが、ページ間を超えてデータが必要になる際に使います。

**4. `Atomic Design`の生体（`organisms`）以上の単位でしか参照や格納はしない**
原子(`atom`)、分子(`molecules`)の単位で`Vuex`にアクセスしてしまうと、
汎用性のないコンポーネントになってしまいます。


### ESLintやPrettierの設定をした
書き方の統一のため、ESlintとPrettierを導入しました。
VSCodeで自動フォーマットし、人によるばらつきが出ないようにしました。

## これにより生まれたこと

### バグが少なく、スピードのある開発ができるようになった。

最初にコンポーネント設計や、Vuexの設計をしたことで、
この場合はどうする？、ここはこれで行こうと思うけど、いいかなーなど
今までになかったコミュニケーションが生まれました。
結果として、バグが入りにくく、スピードを加速させることができました。

### 変更や新しいデザインに強くなった

コンポーネント設計をし、`slot`を用いた柔軟性の高いコンポーネントが作れたことにより、
新しいデザインが来た時も、同じコンポーネントを使い回せるようになった。
結果として、変化し続けるサービスのパフォーマンスを最大にすることができた。

### うまく、Vuexと付き合えるようになった。（サイトの表示速度も上がった）

あらゆるところから参照、値の格納をしていたVuexですが、
うまく、サイト全体で必要な情報だけ取得して来て、レンダリングすることで、
サイトの表示速度も上がりました。

### レビューの速度が上がった

小さな単位でレビューをすることが容易になったこと、
複雑な処理が分割されたこと、
Linterなどの導入により、書き方が統一されたことにより、
レビュー速度も上がりました。

## 最後に2ヶ月を振り返って

最初「時間がないから、設計や設定をせずに行こう」という話をしましたが、
終わって見て振り返ると「**時間がないからこそ、設計や設定を最初にきちんとしよう**」
というのが正解だと思いました。

実際、後半の1ヶ月の方が開発スピードは速く、バグにすぐさま対応できるようになっていたと思います。

そして、何より今回、サイトの書き換えをしたにも関わらず、スピードをあげて開発ができた背景には、
**メンバー間のコミュニケーションがきちんと取れていて、
素直に改善をすることができるメンバーに恵まれたという点にあると思います。**

皆さんも`Vue.js`、`Nuxt.js`で何かを作る際は、**設計やルール、設定をきちんとみんなで話し合い**、
スタートすることをお勧めします。

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

## お知らせ
エイチームグループでは一緒に活躍してくれる優秀な人材を募集中です。
興味のある方はぜひとも[エイチームグループ採用ページ](https://www.a-tm.co.jp/recruit/)よりご応募ください！
（[Webエンジニア詳細ページ](https://www.a-tm.co.jp/recruit/requirements/career/lifestylesupport-webengineer/)）よりお問い合わせ下さい。

フロントエンンドエンジニアも募集しております
https://www.a-tm.co.jp/recruit/requirements/career/lifestylesupport-frontenddesigner/

## 明日
いかがでしたでしょうか？
明日のエイチーム引越し侍、エイチーム コネクトアドベントカレンダーの担当は、
期待の新卒チーズ@cheez921です！

是非、明日も見て下さい！