GitHub PagesにNext.js をデプロイする


Github PagesをNext.jsで作りたく思い検索したところ次の記事が大変参考になった。

React Next アプリを GitHub Actions で GitHub Pages にデプロイ

この記事を中心にググりながら完成させた際の手順を以下に記す。

まずは通常のNext.jsアプリを作る

Node.jsインストール済みの環境で下記コマンドを実行する。
ディレクトリ名はのちに作るGitHubリポジトリ名と合わせるためユーザー名.github.ioとしたがなんでもいい。

shell
mkdir ユーザー名.github.io
cd ユーザー名.github.io
npm init -y
npm install --save react react-dom next
mkdir pages

リンクでページ遷移をするだけのNext.jsアプリを作る。

pages/index.js
import Link from 'next/link'

const Index = () => {
  return (
    <>
      <div>Welcome to Next.js!</div>
      <Link href="/linkSample">
        <a>link Sample Page</a>
      </Link>
    </>
  )
}

export default Index
pages/linkSample.js
export default () => (
  <div>
    <p>This is the sample page</p>
  </div>
)

Next.jsアプリを実行するためのスクリプトをpackage.jsonに追記する。

package.json
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
  }

npm run buildコマンドでビルドしたのち、npm run startコマンドでNext.jsアプリを実行する。

ブラウザでhttp://localhost:3000にアクセスすると動作を確認できる。

静的なHTMLとしてNext.jsアプリを生成する

package.jsonのscriptsにexportを追記する。

package.json
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "export": "next export"
  }

npm run exportコマンドを実行することで、静的なHTMLとしてNext.jsアプリを生成する。

なお事前にnpm run buildコマンドでビルドしておくことが必須である。

このとき作られるoutディレクトリにHTMLファイル群があり、これらをローカルサーバーで実行することで動作を確認できる。

ローカルサーバーで動作を確認する(省略可)

ローカルサーバーを立てるにはnpmパッケージのserveが便利。
serveのGitHubリポジトリ

shell
npm install --save-dev serve

serveをインストールしたのち、outディレクトリ指定してを実行する。

shell
npx serve out

http://localhost:5000にアクセスすると動作を確認できる。

.gitignore

ここまでローカルでの動作確認のため2つのコマンドnpm run buildnpm run exportを実行した。

しかしNext.jsアプリをGitHub Pagesにデプロイする際、これらのコマンドはGitHub Actionsで実行する。

そのため、2つのコマンドによりプロジェクトルート直下に作られる.nextディレクトリとoutディレクトリはGitHubにpushする必要がない。

下のように.gitignoreに記述しpushされないようにする。

.gitignore
node_modules
.next
out

GitHub Actions でデプロイするための準備

GitHub Actions とはGitHubにおけるCI/CDツール。

アプリケーションルート直下に.github/workflows/gh-pages.ymlを用意しておきGitHubにpushするだけで、GitHub Actionsが開始し、gh-pages.ymlに記述した操作が自動的に行われる。

.github/wokflows/gh-pages.yml
name: github pages

# masterブランチにプッシュしたときjobsに記述した操作を行う
on:
  push:
    branches:
    - master

jobs:
  build-deploy:
    # ubuntu OS を仮想マシン上に用意する
    runs-on: ubuntu-18.04
    steps:
    - uses: actions/checkout@v2

    # Node.js環境のセットアップを行う
    - name: setup node
      uses: actions/setup-node@v1
      with:
        node-version: '12.x'

    # npm install の際にキャッシュを使うよう設定
    - name: Cache dependencies
      uses: actions/cache@v1
      with:
        path: ~/.npm
        key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
        restore-keys: |
          ${{ runner.os }}-node-

    # package.jsonに基づき依存パッケージをインストールする
    - name: install
      run: npm install --frozen-lockfile

    # Next.jsアプリをビルドする
    # プロジェクトルート直下に.nextディレクトリができる
    - name: build
      run: npm run build

    # 静的なHTMLとしてNext.jsアプリを生成する
    # プロジェクトルート直下にoutディレクトリができる
    # そのなかに、HTMLファイル群と、それらが読み込むJSファイル群を収めた_nextディレクトリがある
    - name: export
      run: npm run export

    # しかしGitHub Pagesの仕様として_から始まるディレクトリが見えず404となる
    # つまりHTMLからJSを読み込めない
    # これを回避するために.nojekyllファイルをoutディレクトリに作る
    - name: add nojekyll
      run: touch ./out/.nojekyll

    # gh-pagesブランチにoutディレクトリの中身をプッシュする
    # gh-pagesブランチは自動的に作成される
    - name: deploy
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./out

GitHubリポジトリを作りプッシュする

ユーザー名.github.ioリポジトリを作る。

他のリポジトリ名でもよいが、その場合GitHub PagesのURLがhttps://ユーザー名.github.io/リポジトリ名となる。

https://ユーザー名.github.io をURLにするならリポジトリ名をユーザー名.github.ioとする。

このリポジトリのmasterブランチにこれまで作ったものをpushすると、GitHub Actionsが開始され、上記gh-pages.ymlに記述した操作が自動的に開始されるので、終了するまで待つ。

GitHub Pages のSourceを変更する

ユーザー名.github.ioリポジトリのSettingsページに移動する。

下へスクロールすると、GitHub PageのSourceを設定する項目があるので、Branch:gh-pages /(root)に変更する。

完成

https://ユーザー名.github.ioにアクセスすると、GitHub Pagesにデプロイした
Next.jsアプリを見れる。

静的なHTMLファイルとしてデプロイしたが、動的ルート、プリフェッチ、プリロード、動的インポートなど、Next.jsのほぼすべての機能をサポートしているとのこと。

Static HTML Export | Next.js

クライアントサイドのページ遷移ができるか、次の方法で簡単に検証できる。

・ブラウザの開発者ツールを使って、 の background CSS プロパティを yellow に変更します。
・リンクをクリックして、2 つのページ間を進んだり戻ったりしてください。
・黄色の背景が、ページ遷移の間にも持続していることがわかります。

これは、ブラウザがページ全体をロードしているのではなく、クライアントサイドでのナビゲーション(ページ遷移)が機能していることを示しています。

出典: 大幅にリニューアルされた Next.js のチュートリアルをどこよりも早く全編和訳しました

上記の検証を完成したGitHub Pagesで行うと

Next.jsのクライアントサイドでのページ遷移が行われていることがわかる。

参考

React Next アプリを GitHub Actions で GitHub Pages にデプロイ
Next.jsで作ったアプリをGitHub Pagesにデプロイする
大幅にリニューアルされた Next.js のチュートリアルをどこよりも早く全編和訳しました
Next.jsチュートリアル翻訳
GitHubの新機能「GitHub Actions」で試すCI/CD
GitHub Actionsのドキュメント
GitHub Actions でキャッシュを使った高速化
Static HTML Export | Next.js
Deployment | Next.js