Nuxt.js によるフロントエンドの構築

Adventarを支える技術 Advent Calendar 2019 の3日目です。

今日はフロントエンドのフレームワークとして採用した Nuxt.js について感想を書こうと思います。

個人的には Vue.js よりも React のほうが好きなので、最初は Next.js を検討しましたが、ルーティングまわりのできの良さ、エコシステム、全体の完成度などを吟味した結果 Nuxt.js を選択しました。Next.js が全然ダメというわけではないので、好みにもよると思います。

ここがよかった Nuxt.js

オールインワンな環境

ビルドや Lint の環境が自動できて、テストのライブラリや State 管理の仕組みも組み込まれていて、デプロイもコマンド一発で簡単にできる環境がすぐに整うのはよかったです。

小さいライブラリを自分で組み合わせて作るのもいいですけど、Webフロントエンドの技術スタックは選択すべきものが多すぎるので、何も考えずに Nuxt.js が勧めてくるものを脳死で使うというは楽です。

このあたりはおそらく Next.js も大差ないですね。

エコシステム

プラグインやドキュメントが豊富なのはよかったです。Nuxt PWAなどは少し設定するだけで PWA の設定ができたり、nuxt-fontawesomeでパっと fontawesome が導入できたりとか。

View のコンポーネントライブラリについても Vue.js のライブラリが利用できるので、欲しいものはだいたいあるので良いですね。個人的に UI コンポーネントはよほど面倒なものじゃない限り自作するのが好きなので今回はほとんど使いませんでしたが。

ルーティング

Next.js との比較になりますが、ルーティングの機能はよくできていると思います。特に動的なルーティングに大きな違いがありました。

Adventar はもともと Rails でできていたので、/calendars/:id のような URL になっていました。これを Next.js で表現しようとすると、/calendars?id=100のようにするか、express などのサーバーを置いて処理するしかありませんでした(つまり SSR 必須)。

Nuxt.js では、以下のようなディレクトリ構成にするだけでこのルーティングを express などのサーバーを建てずに実現できます。

.
└── pages
    └── calendars
        └── _id # アンダースコアから始まる名前は動的な値を指定できる
            └── index.vue

ただ、この機能は Next.js にも少し前に入りました。

https://nextjs.org/blog/next-9#dynamic-route-segments

実際に試してはいませんが、これがあったら Next.js を採用していた可能性はあります。しかし、動的なルーティングのファイル名の規則が、Nuxt.js が _id のようにアンスコで始まる、というものに対して Next.js は [id] のようにブラケットで囲む、というものでありだいぶ気持ち悪い感じはありますね...。

ここは微妙だった Nuxt.js

TypeScript対応

TypeScript 対応に苦労しました。今は公式で対応しているので難しくないと思いますが、作り始めたころは絶賛 TypeScript 対応中という感じで、試行錯誤した覚えがあります。

また、これは Nuxt.js というよりは Vue.js の問題なのですが、TypeScript の型チェックがテンプレートに効かないので、結局テンプレートのところで型の齟齬が発生してエラーになることがあってせっかくの TypeScript が片手落ちという感じでした。Vuex と TypeScript の相性もアレですし。

Vue.js もそのうち改善されるとは思いますが、この点においては React のほうが圧倒的に好きです。

バージョンアップ

つらい。けっきょくまだバージョンアップできてません。

まとめ

総合的には Nuxt.js はよくできているフレームワークで、採用してよかったと思いました。ただやはり個人的には TypeScript との相性の面で React のほうが好きなので、Next.js に期待したいところです。

明日は gRPC-Web について書きます。