[初学者向け] Next.js で開発を始める前に知っておきたいポイントと開発方法

10 min read

想定読者

  • Next.js に触れたことがあまりない人
  • ちょっとした使い方を知りたい人

執筆同時のNext.js

  • next: v12.3.2

Next.js とは

Next.js は、Vercel 社が提供する React フレームワークである。

nextjs.orgNext.js by Vercel - The React FrameworkNext.js by Vercel is the full-stack React framework for the web.

なぜ、Next.js を使うのか

現在のフロントエンド開発において、React を始めとするフレームワークやライブラリは選択肢の1つとなっている。しかし、単独で React を使った場合、ルーティングやサーバーサイドレンダリング、パフォーマンスなどの面で課題が出てくる。

Next.js は React をより使いやすくするために開発されたフレームワークであり、以下のようなフロントエンド開発のベストプラクティスを特徴として持っており、この恩恵を開発の初期段階から享受できる。

  • ゼロコンフィグ
    ゼロコンフィグであるため、開発者は煩雑な環境設定などを行う必要がない
  • ファイルベースルーティング
    ルーティングの設定が非常に簡単でページの追加や変更が容易
  • 事前レンダリング
    ページの初期表示を高速化できるため、ユーザーエクスペリエンスの向上にも繋がる
  • 画像やフォントの最適化
    パフォーマンスの向上も期待できる

以上のように、Next.js は開発において多くの課題を解決するフレームワークであり、今後のフロントエンドの開発においても重要な選択肢となるだろう。

セットアップ

Next.js は執筆時点での最新バージョン v12.1.6 を想定。

手動でセットアップも可能だが、体系的に Next.js を学ぶのを目的とするため自動セットアップを利用する。

任意のディレクトリに移動して、下記のコマンドを実行する。コマンドを実行したディレクトリに任意のディレクトリ名(後述の「プロジェクト名」)で Next.js をインストールしたディレクトリが作成される。

npx create-next-app@latest --typescript --use-npm

--use-npmを付けないと yarn でセットアップが行われる。こちらは環境に応じて任意でつける。

上記のコマンドを実行すると以下の流れで Next.js のインストールが行われる。

  1. 下記のように訊かれたら、yを入力
    Need to install the following packages:
      create-next-app@latest
    Ok to proceed? (y)
    
  2. プロジェクト名を訊かれるので、任意のプロジェクト名を入力
    ✔ What is your project named?
    
  3. 作成されたファイル一覧
     .
     ├── .eslintrc.json
     ├── .gitignore
     ├── .next
     ├── README.md
     ├── next-env.d.ts
     ├── next.config.js
     ├── package-lock.json
     ├── package.json
     ├── pages
     │   ├── _app.tsx
     │   ├── about.js
     │   ├── api
     │   │   └── hello.ts
     │   └── index.tsx
     ├── public
     │   ├── favicon.ico
     │   └── vercel.svg
     ├── styles
     │   ├── Home.module.css
     │   └── globals.css
     └── tsconfig.json
    

基本的な開発手順

  1. 下記のコマンドを実行し、開発サーバを起動する
    npm run dev
    
    (他のコマンドについては割愛)
  2. 開発サーバ起動後、http://localhost:3000 でアプリケーションの実行を確認
    (デフォルトの設定だとポートは3000
localhost:3000へアクセスして表示される画面
3. 開発サーバ実行中に任意のファイルを編集するとライブリロードされて内容が反映される

ファイルベースルーティング

pagesディレクトリ内に配置した React コンポーネント(.js,.jsx,.ts,.tsxファイル)によって、ルーティングが決定する。

例えば、以下のような React コンポーネントを pages/about.js というファイルで配置すると、/aboutへとアクセスできるようになる。ディレクトリを任意の名称にして、index を配置する形(pages/about/index.js)でも同様の動きになる。

// pages/about.js

const About = () => {
  return <div>About</div>;
};

export default About;

インデックスルート

indexというファイルは、ルートとしてルーティングされる。

  • pages/index.jsx/
  • pages/about.jsx
    pages/about/index.js/about

ネストされたルート

ネストされたディレクトリ構造も同じようにルーティングされる。

  • pages/posts/first-post.jsx/posts/first-post
  • pages/dashboard/settings/username.jsx/dashboard/settings/username

事前レンダリング(プリレンダリング)とは

Next.js には、SSR(Server-side Rendering)と SG(Static Generation)の 2 つの事前レンダリング形式がある。

事前レンダリングとは、各ページの HTML をクライアントサイドの JavaScript でレンダリングするのではなく、サーバサイドの JavaScript で事前に生成しておくことを指す。

これらの違いは、ページの HTML を生成するタイミングにある。

  • SG(Static Generation): ビルド時に HTML を生成する
  • SSR(Server-side Rendering): リクエストごとに HTML を生成する

事前レンダリングなし

事前レンダリングなし
事前レンダリングなし - 'Pre-rendering - Pre-rendering and Data Fetching | Learn Next.js'より

事前レンダリングがない場合、クライアントサイドで HTML を生成するため、JavaScript によるレンダリングが完了するまでコンテンツを見ることができない。また、JavaScript が無効化された状態では見ることが出来ない。

事前レンダリングあり

事前レンダリング(Next.js利用時)
事前レンダリングあり - 'Pre-rendering - Pre-rendering and Data Fetching | Learn Next.js'より

事前レンダリングの場合、事前に HTML は生成されたものをクライアントサイドはレンダリングする。生成された HTML は JavaScript と関連付けられており、ページが読み込まれた後に JavaScript は実行され、アプリケーションはインタラクティブになる。このプロセスはハイドレーション(Hydration)と呼ばれる。

SG: Static Generation / SSG: Static-site Generation

SG(Static Generation)は、ビルド時に HTML を生成する事前レンダリング方式。

Static Generation
Static Generation - 'Pre-rendering - Pre-rendering and Data Fetching | Learn Next.js'より

We recommend using Static Generation (with and without data) whenever possible because your page can be built once and served by CDN, which makes it much faster than having a server render the page on every request.
https://nextjs.org/learn/basics/data-fetching/two-forms

ちなみに Next.js は、パフォーマンスの観点から可能な限り SG を使用することを推奨している。

Next.js での利用方法

pages ディレクトリ内のコンポーネントでgetStaticProps()を利用する。

export async function getStaticProps(context) {
  return {
    props: {}, // ページコンポーネントに props として渡す
  };
}

以下はBlogコンポーネントのデータを SG 時に API 経由でセットするケース。

// この関数はサーバーサイドのビルド時(Node.js)に呼び出される
// ブラウザ上ではなく Node.js で実行されるので DOM などへのアクセスはできない
export async function getStaticProps() {
  const res = await fetch("https://.../posts");
  const posts = await res.json();

  // `props: { posts }` を返すことで
  // Blog コンポーネントはビルド時に `posts` を `props` として受け取れる
  return {
    props: {
      posts,
    },
  };
}

// `posts` は、ビルド時に `getStaticProps()` で取得した値が設定される
function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  );
}

export default Blog;

いつ使うべきか

  • ページをレンダリングするのに必要なデータが、ビルド時にユーザーのリクエストよりも先に利用可能である場合
  • データをヘッドレス CMS や API から取得する場合
  • データがユーザー固有のものでなく public にキャッシュできる場合
  • SEO などの理由でページを事前レンダリングする必要があり、かつ非常に高速でなければならない場合

SSR: Server-side Rendering

SSR(Server-side Rendering)は、ユーザのリクエストごとに HTML をサーバー側で生成する事前レンダリング方式。

Server-side Rendering
Static Generation - 'Pre-rendering - Pre-rendering and Data Fetching | Learn Next.js'より

Next.js での利用方法

pages ディレクトリ内のコンポーネントでgetServerSideProps を利用する。

export async function getServerSideProps(context) {
  return {
    props: {}, // ページコンポーネントに props として渡す
  };
}

以下はBlogコンポーネントのデータを SSR でセットするケース。

// この関数はサーバーサイドのリクエスト時(Node.js)に呼び出される
// ブラウザ上ではなく Node.js で実行されるので DOM などへのアクセスはできない
export async function getServerSideProps(context) {
  const res = await fetch("https://.../posts");
  const posts = await res.json();

  // `props: { posts }` を返すことで
  // Blog コンポーネントはリクエスト時に `posts` を `props` として受け取れる
  return {
    props: {
      posts,
    },
  };
}

// `posts` は、リクエスト時に `getServerSideProps()` で取得した値が設定される
function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  );
}

export default Blog;

いつ使うべきか

  • クエリパラメータで動的にデータが変わるページ
  • HTTP ヘッダーを必要とするページ

参考


WIP