Overview
自分のポートフォリオサイト ( emahiro.dev ) の技術スタックを Nuxt3 -> Next に更新しました。
フレームワークの部分のみ置き換え、その他の要素(ホスティング先等)はそのままにしてます。
なぜ変えようと思ったか
個人で作ってるものなのでほとんど気分にはなるのですが、あえて理由づけするなら以下になります。
- Vue のパラダイムのみで生きていたので React の空気を感じてみたかった。
- 仕事で使う上ではエコシステムが充実してる React を今後技術選択の上で採用していこうと考えていたので触っておきたかった。
特に2つ目の理由についてですが、自分は Vue でも React もどちらがいい、みたいな議論にはあまり興味がなく、技術は選択する人のスキルレベルや好みで選択をすればいいと思っているタイプなのですが、Vue のパラダイムが 3系になってある程度枯れるまでに React のエコシステムが充実して、React の方が現時点ではより枯れてしまったという現象が発生してると感じています。
実際、Vue のパラダイムの中で動いてるプロダクト(Nuxt, Vuetifyなど)は Vue2とVue3 の間で断絶が発生しており、メジャーバージョンが上がる部分で既存の資産が使えない事象が発生しており、ちょっとした負債になりつつあります。( Vue2 系のサポートは 今年まで )
実際現職の業務であるツールをフルスクラッチで作り直したときに Vuetify (Vue2系) を採用したのですが、Vue3 に対応した最新版の調査をしたところ Vuetify が 2系でサポートしていたコンポーネントをほぼサポートせず、 Vue3 対応した Vuetify を使うというのはほぼプロダクト作り直しと同義、という事象にぶち当たりました。
結局プロダクトとして採用するには、サポート体制やエコシステム、コミュニティの充実度(= どれだけ枯れているか?)というのが採用の一つの基準になると考えており、その観点では Vercel という企業がそのエコシステムの上で事業をしているので、3系がようやく枯れ始めてきた Vue と比べると現段階では Next に寄せておくほうが無難、という考えを持っています。
ちょっと前に以下のようなブログもバズってましたが、CompositionAPI よりも僕個人の見解としては、このエコシステムのサポート(どれだけ枯れているか度)というものが大きな違いとして発生してしまったのではないかなと考えています。
※ 実際 Nuxt3 はほぼ React を書いてるような雰囲気を感じることもありますし、ある一点に向かって収斂しつつあるような状況にもなっています。
移行手順
- もともとの package.json を削除。
- Get Started をベースに Next のアプリケーションを生成する。
- Firebase Hosting で Hosting するディレクトリを Next が生成する Static page のディレクトリに合わせる (*1)
※1. Firebase Hosting は、設定にある public
に指定したディレクトリの直下に index.html
があればページを Hosting することができます。
Memo
ここからは移行したときのメモです。
Font を変更する
next/font
を使います。
使い方は Font に関する 公式ドキュメント を参照しました。
個人的には以下のサイトもわかりやすくてよかったです。
スタイルをあてる
CSS について色々忘れてるところがありましたが css のスタイルを import して className
二指定してスタイルを当てる、というのはわかりやすい設定方法でした。
この辺のスタイル定義のプラクティスがあれば調べたいなと思いました。
個人的には routing(ディレクトリ構造)ごとに css module を用意するのが今のところ良いのかなと思ってますが、いい感じに scoped にする方法を調べたいなと思います。
Static page を生成する。
Static Page の生成について Static Export を参照することで index.html を生成するようになります。
出力されるディレクトリは Nuxt3 のときはディレクトリ名をカスタマイズすることができましたが、Next で Static export を使うケースでは out
ディレクトリになります。
なのでこの out
ディレクトリを firebase の hosting が参照する public 先に指定します。
この static page の生成モードへの変更は config で以下のように設定します。
const nextConfig = { output: "export", };
Static export を設定してる状態では Image をそのまま使うには最適化モードを false にする。
※ 最適化モードにした状態で画像を扱う方法は自分はまだ調べてません。
Static export の設定してる状態でが画像の最適化モードを off にしないと以下のエラーが発生します。
Unhandled Runtime Error Error: Image Optimization using the default loader is not compatible with `{ output: 'export' }`. Possible solutions: - Remove `{ output: 'export' }` and run "next start" to run server mode including the Image Optimization API. - Configure `{ images: { unoptimized: true } }` in `next.config.js` to disable the Image Optimization API. Read more: https://nextjs.org/docs/messages/export-image-api
最適化モードはすぐには必要ないので一旦 off にしました。next config ファイルで非最適化モードを true にします。
const nextConfig = { images: { unoptimized: true, }, };
favicon を設定する
favicon の設定もほぼ 公式のドキュメント 通りに進めました。
favicon の作成はオンラインで生成してくれるツールがあるので特に困ることはありませんでした。
雑感
Nuxt3 を触るようになってから従来の Vue 感はあまり感じていなかったので、Next を使い始めてもあまり違和感なく触ることができました。
functions の返り値に html を記述していく方法は割と今だと一般的なんですかね?
HTML を雰囲気で書けて、かつ SFC の中で CSS を scoped にできるとうい点で自分は Vue を選択しがちだった、というのがあるので Next に触ってみて似たようなことができるというのは移行のしやすさの観点から考えても学びがありました。
まだ全機能使えてるわけではないのでもうちょっと機能追加しつつ色んな機能を触ってみようと思います。