Open11

[MEMO]nextjsのSSGを使ってGithub Pagesサイトを作成する

sev3e3esev3e3e

記事書く用にやったことのメモを書き殴る

"next": "13.1.1"
"react": "18.2.0"
"typescript": "4.9.4"

sev3e3esev3e3e

ここを参考にRepository作成

https://docs.github.com/ja/pages/getting-started-with-github-pages/creating-a-github-pages-site

Repositoryの名前に注意

リポジトリの名前と、任意で説明を入力してください。 ユーザーまたは Organization サイトを作成する場合は、リポジトリに <user>.github.io または <organization>.github.io という名前を付ける必要があります。 ユーザーまたは Organization の名前に大文字が含まれている場合は、小文字にする必要があります。 詳細については、「GitHub Pages について」を参照してください。

sev3e3esev3e3e

作ったrepoをcloneする

PS H:\VSCode_Projects> git clone https://github.com/sev3e3e/sev3e3e.github.io.git
Cloning into 'sev3e3e.github.io'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
sev3e3esev3e3e

create-next-appを使ってnextjsをインストールする

https://nextjs.org/docs/api-reference/create-next-app

今までwith-typescriptテンプレートを使っていたが、そのテンプレートを使わなくてもTypeScriptを使えるらしい。

You will be asked for the name of your project, and then whether you want to create a TypeScript project:
✔ Would you like to use TypeScript with this project? … No / Yes

違いも気になったので今回はテンプレートを使わずにやる。

sev3e3esev3e3e

repo作るときにREADME.mdを生成したせいでエラー吐いた

PS H:\VSCode_Projects\sev3e3e.github.io> npx create-next-app@latest .
√ Would you like to use TypeScript with this project? ... No / Yes     
√ Would you like to use ESLint with this project? ... No / Yes
The directory sev3e3e.github.io contains files that could conflict:    

  README.md

Either try using a new directory name, or remove the files listed above.

普通は空のディレクトリからnextjsをインストールしてgithubへpushなのかな?

とりあえず削除して再度実行

PS H:\VSCode_Projects\sev3e3e.github.io> npx create-next-app@latest .
√ Would you like to use TypeScript with this project? ... No / Yes     
√ Would you like to use ESLint with this project? ... No / Yes
Creating a new Next.js app in H:\VSCode_Projects\sev3e3e.github.io.    

Using npm.

Installing dependencies:
- react
- react-dom
- next
- typescript
- @types/react
- @types/node
- @types/react-dom
- eslint
- eslint-config-next


added 251 packages, and audited 252 packages in 36s

87 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Initializing project with template: default

Success! Created sev3e3e.github.io at H:\VSCode_Projects\sev3e3e.github.io

A new version of `create-next-app` is available!
You can update by running: npm i -g create-next-app

できた。

sev3e3esev3e3e

と思ったらnpmが使われている。昔はyarnが使われていたようなきがするけど・・・

create-react-appはv5.0.0で変わったらしいので、そっちと混ざっちゃってるかも

https://zenn.dev/lilac/articles/c6240615b80185

まあnpxはnpmの機能だし、素直にyarn create next-appします。

...
├─ word-wrap@1.2.3
├─ yallist@4.0.0
└─ yocto-queue@0.1.0
Done in 21.52s.

Initializing project with template: default

Success! Created sev3e3e.github.io at H:\VSCode_Projects\sev3e3e.github.io

gitフォルダが読み込まれずvscodeリロードしたらターミナルログが消えちゃった。

ひとまずこの状態をcommitしておく

git commit -m "initial commit"
sev3e3esev3e3e

SSG用に設定する

https://nextjs.org/docs/advanced-features/static-html-export

を参考にbuildコマンドを書き換える

package.json
"build": "next build && next export"

で、実行するとエラー

Error: Image Optimization using Next.js' default loader is not compatible with `next export`.

上記ページにも記載がある通り、下記の機能はSSGでは動作しないらしい

  • Image Optimization (default loader)
  • Internationalized Routing
  • API Routes
  • Rewrites
  • Redirects
  • Headers
  • Middleware
  • Incremental Static Regeneration
  • fallback: true
  • getServerSideProps

なので

  • pages\apiディレクトリの削除
  • next/imageimgタグへ書き換え

の2つをやることにする

sev3e3esev3e3e

imgタグに書き換えるとeslintの警告が出る

Using `<img>` could result in slower LCP and higher bandwidth.
Use `<Image />` from `next/image` instead to utilize Image Optimization.
See: https://nextjs.org/docs/messages/no-img-elementeslint@next/next/no-img-element

https://nextjs.org/docs/messages/no-img-element

SSGだと必要ない警告なのでoffにする

.eslintrc.json
{
    "extends": "next/core-web-vitals",
    "rules": {
        "@next/next/no-img-element": "off"
    }
}
info  - using build directory: H:\VSCode_Projects\sev3e3e.github.io\.next
info  - Copying "static build" directory
info  - No "exportPathMap" found in "H:\VSCode_Projects\sev3e3e.github.io\next.config.js". Generating map from "./pages"
info  - Launching 11 workers
info  - Copying "public" directory
info  - Exporting (3/3)
Export successful. Files written to H:\VSCode_Projects\sev3e3e.github.io\out
Done in 7.65s.

無事build成功

sev3e3esev3e3e

生成したHTMLのpreviewをする

http-serverとか使おうかなと思ったけど、今回はVSCode拡張のLive Serverを使用する

で、これは現在開いているフォルダをrootとしてサーバーを建てるのでnextjs用に設定を変更する。

https://note.mersy418.com/article/vscode-liveserver-root

上記ではvscodeのglobal settings.jsonをいじってるが、プロジェクトごとに設定を変更したほうが良いと思うので下記の通りに設定ファイルを書く。

https://zenn.dev/youfuku/articles/7f1c8aaf1cc320

./.vscode/settings.json
{
    "liveServer.settings.root": "/out"
}

無事にPreview出来てる。OKOK

一旦ここまでcommit, push

git add --all
git commit -m "SSG化"
git push origin
sev3e3esev3e3e

github pagesにdeploy

ここまでやって気づいたけど、github pagesはそもそもhtmlがrepoに含まれていなければいけない。

buildとかなんか自動でやってくれるやつあるやろ・・・とおもったらやっぱりちゃんとあった。

https://dev.classmethod.jp/articles/github-pages-by-actions/

って調べてたら何か勝手にbuildが走ってる。

どうやらREADME.mdが公開されてるっぽい。ちょっと調べたけど、こういうもんなのか名言されてるソースが無かった。一応ここには

変更が特定のブランチにプッシュされたときにサイトを公開できます。

とあるので、デフォだとREADME.mdが勝手にpublishされるのかな?

sev3e3esev3e3e

Custom GitHub Actions Workflowsを使用する

https://dev.classmethod.jp/articles/github-pages-by-actions/

上記の通りにすすめてく。最終的にこんな感じのファイルが生成される。

.github/workflows/nextjs.yml
# Sample workflow for building and deploying a Next.js site to GitHub Pages
#
# To get started with Next.js see: https://nextjs.org/docs/getting-started
#
name: Deploy Next.js site to Pages

on:
  # Runs on pushes targeting the default branch
  push:
    branches: ["main"]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow one concurrent deployment
concurrency:
  group: "pages"
  cancel-in-progress: true

jobs:
  # Build job
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Detect package manager
        id: detect-package-manager
        run: |
          if [ -f "${{ github.workspace }}/yarn.lock" ]; then
            echo "manager=yarn" >> $GITHUB_OUTPUT
            echo "command=install" >> $GITHUB_OUTPUT
            echo "runner=yarn" >> $GITHUB_OUTPUT
            exit 0
          elif [ -f "${{ github.workspace }}/package.json" ]; then
            echo "manager=npm" >> $GITHUB_OUTPUT
            echo "command=ci" >> $GITHUB_OUTPUT
            echo "runner=npx --no-install" >> $GITHUB_OUTPUT
            exit 0
          else
            echo "Unable to determine packager manager"
            exit 1
          fi
      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: "16"
          cache: ${{ steps.detect-package-manager.outputs.manager }}
      - name: Setup Pages
        uses: actions/configure-pages@v2
        with:
          # Automatically inject basePath in your Next.js configuration file and disable
          # server side image optimization (https://nextjs.org/docs/api-reference/next/image#unoptimized).
          #
          # You may remove this line if you want to manage the configuration yourself.
          static_site_generator: next
      - name: Restore cache
        uses: actions/cache@v3
        with:
          path: |
            .next/cache
          # Generate a new cache whenever packages or source files change.
          key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
          # If source files changed but packages didn't, rebuild from a prior cache.
          restore-keys: |
            ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-
      - name: Install dependencies
        run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}
      - name: Build with Next.js
        run: ${{ steps.detect-package-manager.outputs.runner }} next build
      - name: Static HTML export with Next.js
        run: ${{ steps.detect-package-manager.outputs.runner }} next export
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v1
        with:
          path: ./out

  # Deployment job
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v1

deploy出来た。すげぇ簡単。