NUXT いるのかどうか (Vue CLI 3 との比較)

[Nuxt.jsいらない説](http://uyamazak.hatenablog.com/entry/2018/08/15/124952) という記事を読んだのをきっかけに、 NUXT と Vue CLI 3 どちらを使うべきか、その選び方を整理してみた。特にその記事に対する反論とかではない。

## Vue を使うときの選択肢

現状、 Vue CLI 3 と NUXT の二択だと思って良い。
少なくとも webpack で1からゴリゴリ書くのはおすすめしない。アップデートが死ねる。
parcel はちゃんと使ってないのでコメントしにくいが、 Vue CLI 3 ですら重たいような局面では使えるかも知れない。けど今回は選択肢には挙げない。

## Vue CLI 3 とは

### なにをするものなのか

Vue のツールチェーンがほぼ全部入りした CUI/GUI ツール。
`vue create` を叩くとローカルでの開発環境やビルドを備えたプロジェクトが作成される。その際、 Router や Vuex を導入するかも選択できる。
また、 [@vue ネームスペースのプラグイン](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue) で自動テストや PWA, typescript にも対応する。

### Vue CLI 2 までと何が違うのか

Vue CLI 2 ではあくまでテンプレートダウンローダーでしかなかったので、ほとんど別物だが、最も大きい変化は「ツールチェーンをアップデートできる」という点。
Vue CLI 2 で作成したプロジェクトは（テンプレートにもよるが大体は） build ディレクトリ内にビルド用の config やスクリプトが入っていて、例えば webpack 3 に更新しようと思ったときには自分でその build ディレクトリ内のスクリプトを更新するしかなかった。
Vue CLI 3 はこの点が解消しており、 [vue-cli-service](https://cli.vuejs.org/guide/cli-service.html) と各プラグインさえ更新すればよい。

## NUXT とは

Vue のプロジェクトで必要になるであろうものを全部入りしたフレームワーク。
ただ Vue 自体が小さいということもあり、 `A total of only 57kB min+gzip (53kB with Vuex).` （公式サイトより）ととても小さい。
設定より規約 (convention over configuration) の思想で作られていて、例えばルーティングは pages ディレクトリ以下に .vue ファイルをどう配置するかで自動生成されるなど、規約通りに書けば設定ファイルは小さくて済む。
出力は SSR, SPA, Static Generated が選べるので、 SSR が要らない場合は node.js サーバを用意する必要はなく、 S3 や GitHub Pages に SPA or Static Generated でビルドしたファイルを設置すればよい。

## Vue CLI 3 か NUXT か

### 規約がほしい -> NUXT

複数人で開発しているようなプロジェクトでは、事前に規約を決めておかないと無秩序になりがちである。
NUXT は上記の通り「設定より規約」な思想なので、ある程度秩序の保たれたプロジェクトができるという利点がある。
Vue CLI 3 の場合はページの .vue はどこにおくか、ルーティングはどこにどう書くかなどを自分で決定しなければならない。

### 細かくカスタマイズしたい -> Vue CLI 3

Vue CLI 3 は webpack ベースのツールチェーンを実装していて、 vue.config.js に `configureWebpack` `chainWebpack` というオプションでそのツールチェーンに手を入れることができる。
NUXT でも nuxt.config.js で同様のことが可能だが、 CLI 3 の場合 `vue inspect` というコマンドで webpack.config.js が実際どうなるのかを確認しながら追加できるので、よりカスタマイズ性が高い。
また、 `vue create` で選べる組み合わせが非常に多いので、自分好みの環境を作りやすい。

### SSR が必要 -> NUXT

SEO が必要な動的ページがたくさんできるようなサービスでは Server Side Rendering (SSR) が必要になるだろう。この場合は NUXT を選択しておいてほぼ間違いない。
Vue で SSR をやるのは [専用のドキュメントページ](https://ssr.vuejs.org/) ができる程度には大変である。例えば [Data Fetching](https://ssr.vuejs.org/guide/data.html) 一つとってみても `asyncData` という mixin を作ってそれをサーバとクライアント両方で読んで……という話になり、なかなか骨が折れる。 NUXT はこの `asyncData` が最初から存在し、使い方のドキュメントも用意されている。そういったものすべてを自前でやるかどうか？　という話になる。

Vue CLI 3 にも SSR の公式プラグインがあってもよさそうなものだが、 [Issue - Implement SSR mode (server side rendering)](https://github.com/vuejs/vue-cli/issues/1034) は「 NUXT があるから優先度が低い」という理由でクローズされている。


### 自動テストの環境も用意して欲しい -> Vue CLI 3

Vue CLI 3 は Unit テストと E2E テストの両方をプラグインでカバーしており、テストに使うフレームワークも複数用意されている。
NUXT は現状公式ページに [example](https://nuxtjs.org/examples/testing/) が載ってる程度であり、ここについては弱いと言わざるを得ない。
E2E の環境を用意するのは比較的簡単だからいいんだけど Vue の Unit テストは結構組むの面倒というか知識が要るので、なんとかなるといいなと思う。 Vue CLI 3 のコードを参考に組むことはできる。

## まとめ

NUXT も Vue CLI 3 もよくできてるので、結局はプロジェクトの要件とそれに関わるメンバーなどで判断しましょうってことになる。
個人的には Router の設定が面倒なのと、人間できることはやりたくなるから、ある程度規約があったほうがよいと思うので NUXT のほうが好み。

## 余談

NUXT も Vue CLI 3 も使っていない既存のプロジェクトの場合はどうすべきかというと、多分 Vue CLI 3 への移行の方が楽だけど、結構しんどい。 [移行記事](https://qiita.com/macoshita/items/40681358c86a0b4eed22) も書いているけど精神論が多め。
JS のツールチェーンはあっという間にレガシー化するので、 Vue CLI でも NUXT でもちゃんと話題を追っかけとくことと、全然別の何かが話題になったときには試してみるといった知識のアップデートが大事なのかなと思う。