Nuxt で Vue を SSR するプロジェクトを複数人で始めるとき、考えたこと・やったこと

本記事は、Vue.js Advent Calendar 2018 #1 11日目の記事です。

はじめまして、[ライダー](https://twitter.com/mtmtkzm)です :motorcycle: 

初めてのSPAのSSRプロジェクトで、初めての複数人での開発をやっていくにあたって、考えたこと、実践したことを綴ります :pen_fountain: 

## そもそも弊社の制作環境
主にWebサイトの受託制作をしています。規模は様々ですが、コーポレートサイト、キャンペーンサイトやメディアサイトなど、WordPress のサイトが中心です。いわゆる SPA など、 JavaScript で View を含めたロジックをゴリゴリ書くことはあまり多くありません（WebGLなどアニメーション実装はままあるようです）。

LIG 制作実績: https://liginc.co.jp/works

### プロジェクトのバックグラウンド
Nuxt 2 をフレームワークとして、 Vue.js をサーバサイドレンダリングしています。また、Nuxt の serverMiddleware で Express を BFF 的に扱っています。バックエンドは GO で microservices 化される予定です。

フロント周りのアプリケーション部分だけ雑に抜粋すると、こんなかんじでしょうか

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82699/da17e633-761f-9784-96c2-c79ac91c6e25.png)

### メンバー
フロントエンドエンジニアは僕を含めて2名で担当します。両者とも、SPAの開発経験は決して豊富なわけではありませんでした。

SSR しない Vue SPA や、 Nuxt の static 出力する静的サイトの実績はいくつかありますが、バックエンドは microservices化し、 BFF を扱い、SSR するようなそれなりに規模の大きいプロジェクトは会社的にも初めてです（たぶん）。

そんなプロジェクトを「絶対成功に導くぞ :muscle:」 と考えたこと・実践したことを書きます。同じような環境の方やチームのご参考になればと思います。

## 考えたこと・実践したこと

上記のような環境（メンバー・プロジェクト）で考えたこと・実践したことです。が、ある意味では、これらは全て今まで必要がなかった（オーバーだった）だけで、当然のことかもしれません。

### Nuxt 2 を導入した
フレームワークとして Nuxt を利用することにしました。周辺ライブラリを事前にお膳立てしてくれているため、それらの使い方を良い意味で縛ってくれます。そうすることで経験不足なふたりの間でも、認識が揃いやすいです。

今回はSSRする事情があったこともありますが、SSRしなかったとしても（Vue CLIと比べて）Nuxt を採用していたと思います。 static 出力する静的サイト作成はこれまでに経験があり、プロジェクト構成に親しみがもちやすかったこともあります。

### `README.md` をしっかり書いた

弊社では、Web制作環境としてボイラープレートが用意されており、全社的にそれを利用しておりました。それはそれは世界的に有名な（それこそNuxt 等）ライブラリ等を用いることが多いです。そのため、各プロジェクトで固有のことがない限り、 `README.md` を特別に書き記すことはあまり多くありませんでした（プロジェクトの立ち上げ方法はデフォルトのままで皆が理解できる）。

Nuxtでは、デフォルトのディレクトリ構成の説明のある [README.md が各ディレクトリに配置された状態](https://github.com/nuxt/create-nuxt-app/tree/master/template/nuxt)のものがインストールされるかと思います。

serverMiddleware をつかった BFF を `/api/` に、フロント側を `/client/` にしました（ちなみに、プロジェクトルートが散らかりがちな Nuxt なので、初めの段階でディレクトリをわけたのはいい判断だったとおもいます）。今回のディレクトリ構成はこんな感じです。 
それぞれ `README.md` を置いておきました。

```
.
├── README.md
├── api
│   ├── ...
│   └── README.md
├── client
│   ├── ...
│   └── README.md
└── server
    ├── ...
    └── README.md
```

ルートの README.md には、いつも通りプロジェクトの立ち上げコマンドや、デプロイ方法などを記載します。が、`/client/` であれば例えば、components ディレクトリの"意味"は、デフォルトで説明がありますよね。ただ、実際のところこのプロジェクトでどう扱うか、というのは当然そのプロジェクトによります。つまり、ここにはそういった説明を書きました。

具体的には

|ディレクトリ||
|:--|:--|
|`components/common/globals/`|グローバルに登録するコンポーネント<br>e.g. `AppIcon.vue`|
|`components/{page_name}/`|長くなるファイルを分割したいだけのステートレスなコンポーネント|
|など|など|

など、そもそもドキュメントに書いてある「ディレクトリの意味」をそのままは書きません。

### ESLint / Prettier を導入
Nuxt インストール時の設定で、eslint, prettier の2つを `YES` としておきました。そのままの設定では fix してくれなかったため、下記のようにコマンドを準備しておきます。

npm precommit にも 自動整形するコマンドを追記しておきました。

```diff:package.json
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
+ "lintfix": "eslint --fix --ext .js,.vue --ignore-path .gitignore .",
```

```diff:package.json
+ "precommit": "npm run lintfix"
```

その上でエディタのショートカット等、任意のタイミングにこれを仕込んでおくことにしました。いらない diff が発生しずらくて良いですね。

### メンバーが何をしているのか知っておく
これは僕が意識しているだけかもしれません。弊社では１人のエンジニアが１案件に長期間フルコミットすることは少なく、複数案件を掛け持ちしていることが多いです。そんな中で柔軟に動くことができるかもしれない、もしくは何かのタイミングを見計らうために、ある程度、誰はどこで何をしているのか、知れる範囲で知っておくようにしています。ストーカーみたいですが。

### オレオレしない
僕にとって、これは技術的に挑戦したプロジェクトです。そのため、まずいろんな記事を読み漁り、イベントに赴き、インプットを増やします。必要であればDEMOを作ってみるなど、アウトプットも行います。そうすると好奇心旺盛なエンジニアである僕はそれらを取り入れたくなるし、これからのプロジェクトに最適化しようと試みます。
しかし、インプット直後の浅い理解のままそれらを取り入れてしまうと、僕から説明をされたメンバーはそれに対しさらに浅い理解でプロジェクトを進めていくことになります。それに気づいたとき軌道修正しようにも、力がなく（強い意志が持てず）舵を切れなくなっていることが容易に想像できました...。
なので、変に最適化を目指さず、多少冗長だったとしてもシンプルさ・見通しの良さを保つことを意識しました。

### お互いプルリクエストを出す
お互いにプルリクエストをだすことで、プロジェクトを進めていくことにしました。

- 実装を見合うことでスピード感がつかめる
- 単純に、コードを読むことで学習になる

### もちろん実装についても話す
[スタイルガイド — Vue.js](https://jp.vuejs.org/v2/style-guide/index.html) を読み、「普通とは」をここで改めて定義し直した、..というか認識しなおしました。困ったや迷った時の指標があると思うだけで実装に踏み切る気持ちになれますね。

オレオレしないと書きましたが、このときに多少気持ち悪く思ったとしても、従うことの方が重要だと思い、今はそうしています。

Lint 等もできる限りこれにあわせようとしています。


## おわりに
さて、これだけふんわりしたことばかりを書きましたが、まだまだ走り出したばかりのプロジェクトです。落ち着いた頃にこの記事を振り返り、どんどん改善をしていきたいと思っております。

余談ですが、普段仕事中テンション高くはない僕ですが、出来るだけテンション上げ気味で頑張っています :joy: 

（（そしてあんまり Vue の話でなくてすみません... :pray:））