Next.jsのbuildプロセスをわかりやすく解説

はじめに

皆さんはNext.jsでアプリを開発するとき、どのようにして本番用のファイルを用意すればいいのか気になったことはないでしょうか。 Reactをベースにしているため、Create React Appのビルドと似ている部分もありますが、Next.jsならではの仕組みがいくつか存在します。 とくにbuildコマンドを実行すると、SSRの仕組みや静的ファイルの生成などが自動的に行われます。 そのおかげで高速かつ柔軟なWebアプリを用意できるのがNext.jsの特徴といえます。 ただ、初めて触れる方にとっては、「何をしているのか」「どうやって設定すればいいのか」がわからず戸惑うこともあるでしょう。 ここでは初心者にも理解しやすいように、next buildのプロセスを噛み砕いて紹介します。

この記事を読むとわかること

  • Next.jsのbuildプロセスの概要
  • 実際の開発で役立つbuildコマンドの使い方
  • SSRやSSGとbuildとの関わり
  • エラーが発生した場合に考えられるチェックポイント
  • 本番運用時に気を付けるべきポイント

Next.jsとbuildの関係とは

Next.jsはReactベースのフレームワークですが、サーバーサイドレンダリング(SSR)や静的サイト生成(SSG)、クライアントサイドレンダリング(CSR)などを使い分けられることが大きな特徴です。 これらのレンダリングの仕組みを最適化した形でまとめあげるのが、buildの工程になります。

アプリを開発するときは、ファイルを保存した瞬間に自動で再読み込みされる開発モードを使うのが一般的です。 しかし、本番にデプロイするときは開発モードではなく最適化された状態で動かす必要があります。 そこで行われるのがbuildです。

buildコマンドを実行すると、各ページやコンポーネントが実行環境に合わせてまとめられ、最終的にパフォーマンスと互換性を考慮したバンドルファイルが生成されます。 たとえば、SSRを使っているページがあれば、その部分はサーバーサイドで実行できる形にまとめられます。 一方、SSGが使われるページなら、HTMLが静的に書き出され、CDNなどから高速に配信できるようになります。 こうした自動的な振り分けのおかげで、開発者はあまり複雑な設定をしなくても、最適化されたアプリを用意できるわけです。

Next.js buildの基本的な実行方法

実際のプロジェクトでは、開発モードから本番用のファイルを作るために、以下の流れを踏むケースが多いです。 あらかじめNode.jsとNext.jsがプロジェクトに導入されていることを前提に話を進めます。

next buildコマンドを使う

Next.jsのアプリでbuildを行う場合は、プロジェクトのルートディレクトリでnext buildを実行します。 以下は簡単な例です。

npm install
npm run build

package.jsonにあらかじめ"build": "next build"と定義しておけば、上記のようにnpm run buildコマンドで簡単に実行できます。 実行すると、Next.jsはソースコードを解析し、SSRやSSGなどの処理を最適化した状態でバンドルします。 最後に「Compiled successfully」というメッセージが出れば、ビルド自体は成功です。

ビルドしたファイルを起動する

ビルドが完了したら、npm run start(または"start": "next start"に相当するコマンド)を実行することで、本番モードのサーバーを起動できます。 開発モードとは異なり、リアルタイムのホットリロードなどは無効化されますが、実際に公開したときの挙動を確認するにはこちらが便利です。 多くのホスティングサービスも、buildした後にstartコマンドを叩くような流れを採用しています。

buildプロセスで行われる主な処理

buildコマンドを叩くと、次のような作業が自動で行われます。 これらを把握しておくと、エラーが出たときにどのあたりをチェックすれば良いかなどの目安になります。

コードの最適化

まずはJSXやTypeScriptのコードを、ブラウザやサーバー上で動作可能なJavaScriptに変換し、不要な部分を削ぎ落とします。 この際にTree Shakingや圧縮などの処理が行われるため、開発モードに比べるとファイルサイズが小さくなりやすいです。 結果として読み込み速度が向上し、クライアントの負荷が減ります。

ルーティングとページ生成

Next.js特有のフォルダ構成に基づいて、pagesフォルダ内の各ファイルを自動的にルーティングとして認識し、SSRやSSGの仕組みを適用します。 getStaticPropsgetServerSidePropsが定義されているページは、それぞれの設定に応じてHTMLファイルやサーバーサイド用のコードが出力されます。 これによって、ビルド完了後にどのページが静的に生成されるのか、どのページがリクエスト時にサーバーサイドで生成されるのかが確定します。

イメージの最適化やその他機能

画像の最適化や、dynamic import機能を使った遅延読み込み(Code Splitting)なども自動的に反映されます。 たとえば、画像は適切なサイズやフォーマットに変換され、ユーザーが訪問するときの転送量を減らせます。 また、大きなライブラリなどは必要に応じて分割され、ユーザーがすぐに使わないコードは後から読み込まれる形になります。

SSR, SSG, CSRとの関わり

Next.jsが扱うレンダリング手法は、大きく分けてSSR、SSG、CSRの3つです。 buildプロセスでは、それぞれに必要な手順がまとめて行われるため、初心者の方は意識しなくとも裏でうまく処理される仕組みになっています。

SSR (Server-Side Rendering)

SSRを利用するページでは、リクエストが発生した段階でサーバーがHTMLを組み立てて返却します。 ビルド時点での処理は少なく、実際のリクエスト時にNode.jsサーバー上でレンダリングが行われるのが特徴です。

SSG (Static Site Generation)

SSGを利用するページでは、ビルド時に静的なHTMLファイルがあらかじめ生成されます。 これにより、ユーザーがアクセスした瞬間からHTMLが存在するため、高速かつスケールしやすいです。 たとえばブログ記事やランディングページなど、内容が頻繁には変わらないが高速表示が求められるケースではSSGがよく使われます。

CSR (Client-Side Rendering)

これはReactそのものと同じく、初期表示時に最小限のHTMLを返して、JavaScriptが読み込まれた後に画面を組み立てる手法です。 Next.jsではSSRやSSGと併用する形が多く、特定のコンポーネントだけをCSRで扱ったりすることが可能です。

実務で意識しておきたいシーン

Next.jsのbuildを使いこなすと、本番用の最適化がうまく行われてパフォーマンスの高いサイトを運用できます。 ここでは、いくつか実務で遭遇する場面について触れてみましょう。

CI/CDパイプラインへの統合

多くのプロジェクトでは、GitHubなどのリポジトリにコードをプッシュすると、自動的にテストやビルドが実行されるCI/CDパイプラインを導入しています。 このとき、ビルドステップにはnpm run buildyarn buildが入るのが一般的です。 ビルドが成功すれば、自動的にデプロイが行われる形にすることで、人の手を介さず運用を回せます。

環境変数の扱い

SSRやSSGのページでは、ビルド時に読み込む環境変数の使い方に注意が必要です。 なぜなら、.envファイルなどで定義された変数は、ビルドの段階で埋め込まれるからです。 機密情報をクライアントサイドで見られてしまうと困るケースもあるため、どの変数をサーバー専用にして、どの変数をクライアントでも使うかをnext.config.jsなどで整理しておく必要があります。

動的ルーティングと静的ページ生成

Next.jsではファイル名に[slug].jsのような書き方をすることで、動的ルーティングを実現できます。 SSGを利用したい場合はgetStaticPathsと組み合わせることが多いですが、ページ数やデータ量が大きいとビルドに時間がかかることがあります。 また、ビルド後に新規データを追加したい場合に、再ビルドが必要になることもあるため、 ISR (Incremental Static Regeneration)の活用を検討することも多いです。

buildでよくあるエラーとチェックポイント

実際にbuildを走らせると、さまざまなエラーが出ることがあります。 初心者の方は、原因を特定できずに戸惑うかもしれません。 そこで、よくあるパターンと対処の方向性を簡単にまとめてみます。

モジュールが見つからないエラー

Module not foundというメッセージが出る場合は、インポートしているパッケージが正しくインストールされていない可能性があります。 Node.jsのバージョンを切り替えたときなども発生しやすいので、再インストールや依存関係の確認を行ってみてください。

ESLintや型エラー

ビルドの途中でESLintやTypeScriptの型エラーが出ることがあります。 Next.jsの設定でstrictモードが有効になっていると、ちょっとしたタイポでもビルドが停止するケースがあります。 エラーメッセージをよく読み、該当箇所を修正してから再度ビルドを実行するのが基本です。

環境変数が定義されていない

.envファイルが正しく読み込まれず、undefinedになっているケースもあります。 SSRを使っている部分で環境変数が見つからないとビルドエラーを起こすことがあるため、.envファイルやnext.config.jsの設定を再確認してください。

build結果の確認とデプロイ

ビルドが成功したら、.nextフォルダに成果物が生成されます。 これを使って本番環境にデプロイするわけですが、どのような構成で運用するかによって手順はさまざまです。

Vercelを使う場合

Next.jsを開発している企業が提供しているホスティングサービスがVercelです。 Vercelの場合、リポジトリと連携しておくと、自動的にビルドとデプロイが行われるため、ローカルでのbuildコマンドは不要になることも多いです。 とはいえ、ローカルでテストする際にはnpm run buildして挙動を確認する手順が一般的といえるでしょう。

独自のサーバーを使う場合

AWSやGCPなどの仮想マシン上にNode.jsの実行環境を用意し、そこに**.nextフォルダをアップロードする形で運用することもあります。 あるいはDockerイメージを作成し、コンテナとしてデプロイするやり方もあります。 いずれにしても、Next.jsのプロダクションモードを起動するには、ビルドしたファイルを元にnpm run start**を実行する仕組みを準備しておく必要があります。

CI/CDパイプラインを導入している場合は、pushするだけで自動的にbuildとデプロイまで実施できるのが便利です。 ビルドエラーが出たら、手元で修正して再度pushする流れになるため、開発効率が高まります。

実際のソースコード例

ここでは、シンプルなNext.jsアプリを例にして、buildコマンドまでの流れを示します。 pages/index.jsに書かれたコードがトップページになります。

// pages/index.js
import React from "react";

export default function Home() {
  return (
    <div>
      <h1>Next.jsのサンプルページ</h1>
      <p>これはNext.jsのbuildテスト用のページです。</p>
    </div>
  );
}

次に、package.jsonではスクリプトとして"build"を定義しておくのが一般的です。

{
  "name": "nextjs-sample",
  "version": "1.0.0",
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "13.0.0",
    "react": "18.2.0",
    "react-dom": "18.2.0"
  }
}

あとはターミナルから以下のように実行してみるだけです。

npm install
npm run build
npm run start

この状態でhttp://localhost:3000にアクセスすると、本番モードで立ち上がったNext.jsアプリを確認できます。

本番運用時に気を付けたいポイント

初心者の方は、開発時に問題がなくても本番運用でトラブルに遭遇することがあるかもしれません。 いくつか注意したい点を挙げます。

キャッシュ戦略

静的ファイルや画像などをビルド時に生成した場合、ブラウザやCDNがキャッシュを持つことで更新が反映されにくくなることがあります。 ファイル名にハッシュを付ける方法や、キャッシュコントロールの設定を行うなど、運用ポリシーに合わせた仕組みづくりが大切です。

サーバーの負荷

SSRのページが多いと、サーバー側でのレンダリング回数が増えていきます。 同時アクセスが集中すると、サーバーが処理しきれず、応答が遅くなる可能性もあるでしょう。 この場合、SSRを部分的にSSGやCSRへ切り替えたり、読み込み頻度の高いデータをキャッシュするなどの対策が必要です。

動作検証の手間

ローカルで正常に動いていても、本番環境ではリソースのパスや環境変数の設定が異なることがあります。 そのため、本番と同じ構成のステージング環境を用意し、build → start → アクセスという流れで事前に確認するのがおすすめです。 万一エラーが起きた場合、ログの内容から何が原因で落ちているのかを洗い出す必要があります。

SSR中心の構成で大規模サイトを運用する場合、ビルド時間やサーバー負荷などを考慮してスケーリング戦略を考えることが不可欠です。 運用開始後にアクセスが増えると、思わぬボトルネックが発生するケースもあるでしょう。

まとめ

今回はNext.jsのbuildに焦点を当てて、その仕組みや実行方法、エラー対処、実務で役立つポイントなどを見てきました。 Next.jsではSSR、SSG、CSRといったレンダリング手法が統合的に扱われており、buildの段階でその最適化がまとめて行われます。 そのため、開発者が複雑な調整をしなくても、効率よく本番環境に対応できるのが特徴といえるでしょう。

実際のプロジェクトでは、CI/CDパイプラインへの組み込みや環境変数の管理、キャッシュ戦略など、ビルド以外にも気を付けるべきことが多くあります。 しかし、基本的なnext buildの流れや設定を理解していれば、エラーに対応する際も落ち着いて対処できるようになるはずです。

皆さんがNext.jsを使ってWebアプリケーションを開発する際に、ここで紹介した内容が少しでも参考になれば幸いです。 ぜひ色々なプロジェクトでnext buildを活用してみてください。

Next.jsをマスターしよう

この記事で学んだNext.jsの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。