Next.js が好きな理由と2年間使い続けてきた感想

@Panda_Program

この記事は Next.js アドベントカレンダーの11日目の記事です。

Next.js が好きな理由と2年間使い続けてきた感想

私が Next.js を使い始めて2年が過ぎました。**Next.js を取り巻く現在の状況は2年前と比べると激変しており、Next.js を利用している企業、ユーザーが大きく増えています。**今では

さんが作成された Next.js の実践的な公式チュートリアルもあるし、有志によって翻訳されたドキュメントの日本語訳もあります(私も本当に微力ながらお手伝いしました)。

しかし、2年前の日本では Vue.js, Nuxt.js の勢いがすごく、Google 検索で「Next.js 〇〇」と入力しても結果に「もしかして: Nuxt.js 〇〇」と毎回表示されるほどでした。フロントエンドで開発するなら React ではなく Vue.js を選ぶのが良いと様々な記事で書かれていた記憶があります。

一方 React はというと、 Hooks の登場により、日本での人気を取り返し始めつつあるという環境でした。それ以前では Redux のボイラープレートを嫌って日本の開発者が React から Vue.js に流れてしまったと先輩から聞いたことがあります。そんな2年前はまだ「React で開発をするなら Create React App を選ぶ」ことが定石だったように記憶しています。

2年経った今では Next.js のカンファレンスも開催されるようになり、**一定以上の規模のサイト React で開発するなら Next.js を採用するのが一般的になったように見受けられます。**自分にとって節目の時期なので、少し過去を振り返ってみようと思います。

そこで、この記事では Next.js を使ってきて好きだと感じる点を紹介していきます。

Next.js のここが好き

自分が好きな点は、大まかに以下のようなところです。

  • 覚えることが少ない
  • JS の様々なライブラリを組み合わせて開発ができる
  • React で Web アプリを作る際に必須のライブラリ選定が不要
  • その他
    • 様々なライブラリを利用したサンプルが豊富
    • DX 向上に力を入れている
    • Vercel 社が開発している OSS であり、プロジェクト継続の安心感がある
    • 社外のチームを巻き込むのが上手い

以下では1つずつ説明を加えています。ただ、他にも API Route で簡単に API が作れる、メジャーバージョンが上がっても Breaking Change が少ないなど、細かいところを上げると枚挙にいとまが無いので、説明するのはある程度大きな話題に絞っています。

覚えることが少ない

React 開発者にとって、Next.js はそれほど学習コストを払う必要なく使えるフレームワークです。 一般的なフルスタックフレームワークと異なり、フレームワーク特有の書き方(いわゆるお作法)が少ないからです。

**サーバーサイドの一般的なフレームワークを使う時は、使われているプログラミング言語以外の学習が必要です。**学習対象は、ルーティングの書き方、DI の設定方法、モデルのメソッドには何があるのかなど、Web アプリを作るに当たり必要で便利な機能です。 また、その書き方はフレームワークが依存しているライブラリに左右されることもあります。

**Next.js にはそのような学習コストを払う必要はほとんどありません。**直感的に使えて覚えることが少なく、React の学習が終わってから何か Web サイトを作りたいと考える方にもオススメできます。

実際、以前業務で React 初心者のサーバーサイドエンジニアの方(すごく吸収が早くて優秀な方)と3ヶ月間ほど Next.js で Web アプリを作る経験をしたのですが、コードレビューでコメントした点は React の挙動の解説と TypeScript の書き方くらいだったように記憶しています。

**ただし、例外は SSR と SSG に関連する getServerSideProps / getStaticProps / getStaticPaths です。**これらは手元でコードを実行して挙動を確認するなど、学習が必要な機能です。以前はデータフェッチなら getInitialProps に書けばいいという設計だったので、データフェッチに関して考えることは少なかったのですが、ここは少し腰を据えた学習が必要です。

さて、Next.js はフルスタックフレームワークではなく覚えることが少ないという特徴は、次の「JS の多様な資産を活用できる」という利点に繋がります。

JS の様々なライブラリを組み合わせて開発ができる

Next.js はフルスタックフレームワークではないため、入力のバリデーションを行いたいときやテーブルからデータを取得したいときは、自分でライブラリを選定する必要があります。

この点はフルスタックフレームワークの特徴と表裏一体です。フルスタックフレームワークの方は基本的なライブラリ選定の必要はなく、一般的な Web サイトの開発に必要な機能を備えているのに対し、Next.js にはそれがありません。

しかし、特定の書き方やライブラリに依存していないからこそ Next.js は多様な JS の資産をフル活用できます。つまり、自分の好きなライブラリを自由に組み合わせてアプリを開発することが可能になるのです。

また、それらのライブラリは直接使用でき、プラグインをはさむ必要はありません。このため、以下のような開発者のペインを避けられます(以下は実際に自分が見聞してきたことです)。

  • あるライブラリを使用したいがそれ用のプラグインがないためライブラリが使えない
  • プラグインを使うべきか、そのまま元のライブラリを使うべきか議論に時間を取られる
  • ライブラリのバージョンが上がったのにプラグインが依存しているバージョンが古いため、ライブラリの新機能が使えない

ライブラリを自由に選定できるということは、ライブラリの盛衰に影響されないということです。一方で、技術選定の視点が必要になり、組織やチームにあった決断をする必要があるため、学習コストというよりは意思決定の部分で労力や調整が必要になるでしょう。これらの点はトレードオフです。

なお、Next.js を元に作られた Blitz は、バリデーションのライブラリに zod を、DB 接続に Prisma を選んでいるなど、Next.js をフルスタックにしたフレームワークです。

Next.js 自体はフルスタックのフレームワークではありませんが、次に紹介するような痒いところに手が届く機能を備えています。

React で Web アプリを作る際に必須のライブラリ選定が不要

Create React App を使って Web アプリを作るに当たって、毎回最初にしていたことは Router ライブラリ(react-router)のインストールでした。また、SSR 対応の有無もサイトの設計段階から検討が必要な項目だったように思います。

一方、Next.js には同梱の Router ライブラリがあります(next/router)。このモジュールを import するだけで簡単にページ遷移の実装ができます。また、ファイルルーティングを採用しているため URL とページコンポーネントの対応が直感的にわかります。

これにより、「このパスでアクセスしてきた時はこのコンポーネント / Viewを表示する」という、サーバーサイドのフレームワークで一般的なルーティングの記述が不要になります。

**また、Next.js は SSR の機能を備えているので、SSR が必要ならいつでも後から設定できます。**関数を1つ追加するだけでページ単位で SSR できるのはとても魅力的です。さらに、優秀なエンジニアの方が Next.js 本体で最適化をしてくれているので、Next.js のユーザーは難しいことを考える必要がありません。

Next.js が一般的になる以前、自前で SSR を実装する方法は何種類かあった上に、パフォーマンスのチューニングに苦労したと読んで記憶があります(ただ、自分で SSR 対応はしたことがなく、当時読んでいた記事の記憶で書いているため誤っている可能性があります)。

Next.js はフルスタックフレームワークではないものの、フレームワークだったら備えていてほしい機能がちゃんと用意されているところが自分の好きな点の1つです。

その他の特徴

様々なライブラリを利用したサンプルが豊富

**Next.js は様々なライブラリと組み合わせて使えるため、そのライブラリの設定や Next.js での簡単な使い方が examples のページに紹介されています。**このサンプルがとても豊富で重宝します。

**Next.js で自分が使いたいライブラリがあれば、この examples の中を検索すると大抵見つかります。**ただし、本当に hello world 程度なので、もしそのライブラリを使い込むのであればそのライブラリの公式ドキュメントを読み込むことが必要になります。

DX 向上に力を入れている

**Next.js はインストールしてすぐに使えます。**Webpack などの設定が不要だからです。そして、Webpack の設定をカスタマイズしたい時にはそのための記述も可能です。

また、以前は .env ファイルから環境変数を読み取ったり、scss を使って開発する際にはそれを実現するモジュールを使ったり、設定を記述する必要がありました。例えば、scss を使って CSS Modules を使う場合、next.config.jsに以下のように記述していました。

// next.config.js
const withSass = require('@zeit/next-sass')

module.exports = withSass({
	cssModules: true,
})

しかし、後のアップデートで CSS Module はデフォルトで使えるように、scss は npm install sass をするだけで使えるようになりました。このようなアップデートも DX 向上のためには嬉しい点です。

Vercel 社が開発している OSS であり、プロジェクト継続の安心感がある

Next.js の調査をしているときに、業務で導入するための説得がしやすかったのがこのポイントです。Next.js は OSS ですが、個人が開発しているプロジェクトではなく、Vercel 社が開発しているため、コアコントリビューターがいなくなって急に開発がストップする可能性はとても低いと考えられます。

社外のチームを巻き込むのが上手い

Next.js の開発主体は Vercel 社内に止まりません。これは OSS なので当然といえば当然です。ただし、Next.js は個人のコントリビューターのみならず、Facebook や Google といったテックジャイアントを積極的に巻き込んで特定の機能を開発しているのは特徴と呼べると考えています。

これは Next.js v11 リリースのブログからコミュニティに対する謝辞の中に両社の名前が追加されたことからもわかります(他社との共同作業自体は v9 あたりから 始まっています)。

例えば、Next.js は React の新機能である React Suspense や Streaming API などに対応しようとしています。この作業は React のコアチームと共同で行われています。また、画像の表示を最適化する Image コンポーネントコードの分割の最適化は、Google と共同で開発されたとのことです。

次に述べるように Next.js を開発している Vercel 社の目的の1つは Web を速くすることであり、その目的のためにやれることをなんでもやるという姿勢が伝わってきます。

Next.js と Vercel 社に賭けよう

Vercel 社の目標の1つは Web を速くすることです。Web を速くするとは、「Web 開発の速度を速くする(=リリースサイクルを早める)」ことと「ユーザー(クライアント)に高速に配信すること」の二つの意味があります。

最近 Vercel 社からその2つの側面がよく表れた発表がありました。前者に対しては、Rust 製コンパイラ swc の製作者と Pecel の作者を Vercel 社に採用したこと、後者に対しては Svelte の開発者を採用して、Svelte 開発に専念できるようにしたことです。

そしてビルドの速度を速くする swc を Next.js に組み込んだり、React より配信する JS のサイズが小さくて済む Svelte[^1] のカンファレンスに Rauch 氏が登壇したりしています。

Vercel 社がさらに気になった方は CEO の Rauch 氏のブログ記事もぜひご一読ください。「Vercel は Next.js の会社だ」という印象がきっと変わるでしょう。

そんな Vercel 社が開発する Next.js に対する好きな点の紹介でした。これからも Next.js の進化が楽しみです!

(なお、本記事は自分の主観と昔の記憶が入った記事なので、事実の誤認があれば Twitter で遠慮なくご指摘ください)

[^1]: https://macos.vercel.app/ の作者によると、元々 React で作っていた時は 146KB minify + brotli(圧縮)で JS は146kb だったそうですが、Svelte で作り直してさらに機能を追加した現在は 28.5KB のJS と 3.6KB の CSS で済んでいるそうです。詳しくは作者のブログをご覧ください。

Happy Coding 🎉

パンダのイラスト
パンダ

記事が面白いと思ったらツイートやはてブをお願いします!皆さんの感想が執筆のモチベーションになります。最後まで読んでくれてありがとう。

  • Share on Hatena
  • Share on Twitter
  • Share on Line
  • Copy to clipboard