Next.jsとは

Next.js入門

Next.jsZeit社によって開発されている ユニバーサルなReactアプリを開発するためのフレームワーク です。Next.jsを使うことによって、サーバーサイドレンダリング (Server Side Rendering)機能を含めたIsomorphicなReactアプリを比較的手軽に構築することができます。このシリーズでは「実際にサンプルとなるWebサイトをTypeScriptで開発するところまでをご紹介したいと思っています。

今回は紹介しませんが、Next.jsには静的サイトエクスポート機能やDynamic Importなど様々な機能が提供されています。興味のある方は公式ドキュメントを参照してみてください。

もくじ

この記事はNext.jsのバージョン 7.0.2 を対象にして書かれています。

サーバーサイドレンダリング(Server Side Rendering)

通常、Reactでのサーバーサイドレンダリングとは「Node.jsなどのサーバー側でJavaScriptを実行することによってReactをレンダリング、その結果としてのHTMLを生成してクライアントに返すこと」を一般的には指します。なぜ、こんなことが必要になるのか、というと主に下記の SEO上の理由 からです。

  • * GoogleなどのクローラーにReactアプリのコンテンツを確実に認識してもらう
  • * 初期レンダリング速度の向上

以下の図でサーバーサイドレンダリングありの場合と、なしの場合を比較してみます。

サーバーサイドレンダリングしない場合

サーバーサイドレンダリングなしの場合

サーバーサイドレンダリングを行う場合

Reactをサーバーサイドレンダリングする場合

サーバーサイドレンダリングなしの場合、サーバー側からレスポンスがあった時点ではHTMLは生成されておらず、ブラウザなどのクライアントがJavaScriptを実行して、はじめてHTMLが生成されます。そのため、タイミング如何など何らかの理由によっては Googleのクローラーが正しくコンテンツを認識できないケース などが出てきます。

筆者も過去に個人サイトをサーバーサイドレンダリングなしで実装していた時にGoogleにコンテンツが認識されず、検索結果に出てこなかったことが失敗経験としてあります...

サーバーサイドレンダリングを行う場合にはサーバーサイド側でJavaScriptを実行して、その実行結果をHTMLとしてクライアントに返し、通常はさらにブラウザ内部でReactを動かして、レスポンスとして返ってきたものと同じHTMLをReactで生成します。

この サーバーサイドレンダリング (Server Side Rendering = SSR) を自分で実装するとなると、ディレクトリ構成やコンポーネントの設計面から、ビルド設定、サーバーに関する知識など深い知識が要求され、また開発コストなども比較的高くなります。Next.jsはこうした Reactアプリのサーバーサイドレンダリング実装や設計のコスト面を肩代わり して、ある程度の土台を提供してくれます。

Next.jsのインストール

まずは適当なディレクトリを作成し、そこにNext.jsをインストールしていきます。

mkdir myNextApp
cd myNextApp

Next.jsは下記のように npm コマンド、もしくは yarn コマンドでインストールすることができます。

npm init -y
npm install --save next react react-dom
or
# yarn add next react react-dom

Next.jsをインストールしたら、packkage.jsonの script の項目にNext.jsを起動するスクリプトを追記します。「next」というコマンドが【それ】です。

# pakcage.json

{
  "name": "myNextApp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
  "author": "",
  "license": "UNLICENSED",
  "private": true,
  "dependencies": {
    "next": "^7.0.2",
    "react": "^16.7.0",
    "react-dom": "^16.7.0"
  }
}

次はトップページを作りましょう。 Next.jsでは pages というディレクトリは特別な意味を持ちます。Next.jsで新しいページ、例えばトップページや問い合わせページなど、を作りたい場合には、 pages ディレクトリ配下に.js ファイルを作成して、Reactコンポーネントを定義します。ここではpagesディレクトリを作成して、その中に index.js を定義しましょう。これがトップページとなります。

Next.jsでpagesディレクトリの中のindex.jsを定義する

そして、下記のReactコンポーネントを返すように定義します。

/* index.js */

export default () => <h1>Next.jsアプリのトップページ</h1>;

定義し終わったら、下記のコマンドを叩いてみましょう。

npm run dev

nextコマンドが内部的に走って開発用サーバーを起動します。デフォルトは3000番ポートで起動するので、http://localhost:3000/ にアクセスすると、上の index.jsで 定義したReactコンポーネントがサーバーサイドレンダリングされた上で表示されます。

index.js

上記のようにNext.jsでは新しいページを作成する時には基本的には pages ディレクトリ配下にファイルを作成して、Reactコンポーネントを定義していく流れになります。

ここまでのコードはこちらのGithubリポジトリに上げておきます。

Next.jsのサンプル集

Next.jsには公式が提供している豊富なサンプルがあります。TypeScriptなどでNext.jsを動かしたい場合やFirebaseにホスティングしてみたい場合の設定などは下記のサンプル群を見てみると参考になるかもしれませんので、ご興味があればこちらも見てみてください。

Next.jsのサンプル群

Next.jsサンプル集

TypeScriptでNext.jsを動かす

TypeScriptでNext.jsを動作させるためには幾つかの手順が必要です。まずはZeit社が公式でプラグインを提供しているので、インストールします。

https://github.com/zeit/next-plugins/tree/master/packages/next-typescript

npm install --save-dev @zeit/next-typescript
# or
yarn add -D @zeit/next-typescript

ここで、React等の型定義ファイルを一緒にインストールします。

npm install --save-dev @types/react
npm install --save-dev @types/react-dom
npm install --save-dev @types/next

# or

yarn add -D @types/react
yarn add -D @types/react-dom
yarn add -D @types/next
/* package.json */
{
  "name": "myNextApp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
  "author": "",
  "license": "UNLICENSED",
  "private": true,
  "dependencies": {
    "next": "^7.0.2",
    "react": "^16.7.0",
    "react-dom": "^16.7.0"
  },
  "devDependencies": {
    "@types/next": "^7.0.6",
    "@types/react": "^16.7.18",
    "@types/react-dom": "^16.0.11",
    "@zeit/next-typescript": "^1.1.1"
  }
}

next.config.jsを作成・カスタマイズ

Next.jsの設定を編集するために、「next.config.js」を作成して、編集します。

/* next.config.js */

const withTypescript = require("@zeit/next-typescript");
module.exports = withTypescript({
  poweredByHeader: false
});

.babelrcの作成・カスタマイズ

Babelによるビルド設定を変更するために、「.babelrc」を作成して、編集します。

{
  "presets": ["next/babel", "@zeit/next-typescript/babel"]
}

Reactコンポーネントを.tsx形式で記述する。

では最初に作成したトップページを変更します。「pages/index.js」を「pages/index.tsx」に名前変更して、下記のように編集しましょう。

/* pages/index.tsx */
export default () => <h1>Hello Next.js With TypeScript!</h1>;

この時点でディレクトリ構成・ファイルは下記のようになっているはずです。

Next.js TypeScriptコード

そして、下記コマンドを打って、再度 http://localhost:3000/ にアクセスします。無事にTypeScriptがコンパイルされて、ページが更新されていることが確認できます

npm run dev
# or
yarn dev
Next.js TypeScript実行結果

ここまでのコードはこちらのGithubリポジトリに配置しておきます。

もし、ReactやTypeScript自体がはじめてで難しいと感じる場合はこちらのチュートリアルやReact自体を解説したサイトや書籍などありますので、もしご興味あれば手にとって見てください。

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

速習TypeScript: altJSのデファクトスタンダートを素早く学ぶ! 速習シリーズ

Next.jsを使う際の注意点

IsomorphicにReactをサーバーサイドレンダリングする時に気をつけないといけない点と共通するのですが、基本的に、サーバー側 (Node.js)でもクライアント側 (ブラウザ側) でも共通して動作するJavaScriptを書く必要があります。

例えば、documentwindowなどNode.jsには存在しないプロパティにアクセスするコードを書くと、Node.js側でそのコードを呼び出した時にクラッシュします。また、fsモジュールなど基本的にNode.jsのみに存在して、ブラウザ側に存在しないモジュールを使おうとすると、今度はブラウザ側で動作しません。そのためNext.jsでは、基本はサーバー側とクライアント側のどちらの環境でも動くように、JavaScript・TypeScriptを書いていくことになります。