ちょっと話題の記事

AWS AmplifyでNext.jsのISRを試してみる

2021.08.02

まえがき

AWS AmplifyでついにNext.jsのISRに対応したようです。実際にやってみる。

少しハマったので備忘録も兼ねて。

Amplify + Next.jsをデプロイ

Next.jsのプロジェクトを作成

yarn create next-app --typescript
✔ What is your project named? … next-sample-app

Next.jsにISRのページを作成

サンプルでISRのページを新規作成します。簡単にタイムスタンプを表示し、5秒間キャッシュするようにします。

pages/isr.tsx

import Head from 'next/head'
import styles from '../styles/Home.module.css'
import { GetStaticProps } from 'next'

type Props = { timestamp: number }

export default function ISR(props: Props) {
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>ISRページ</h1>
        <p> time: {props.timestamp}</p>
      </main>
    </div>
  )
}

export const getStaticProps: GetStaticProps<Props> = async context => {
  return {
    props: {
      timestamp: new Date().getTime(),
    },
    revalidate: 5, //5秒キャッシュ
  }
}

isrのページにリンクするようにindex.tsxを修正

pages/index.tsx

import Head from 'next/head'
import styles from '../styles/Home.module.css'
import { GetStaticProps } from 'next'
import Link from 'next/link'

export default function Home() {
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>Welcome to Next.js!</h1>
        <Link href={'/isr'}>
          <a>isr動作確認ページへ</a>
        </Link>
      </main>
    </div>
  )
}

ISRの動作確認をする

yarn dev ですと、ブラウザの更新するたびにタイムスタンプが更新されるので、プロダクション環境相当で確認します。

$ yarn build
$ yarn start

更新があっても5秒の間はキャッシュされているはずです。

一旦GitHubなどにアップロードする

PublicでもPrivateでもよいのでアップロードしておきます。このブログではGitHubにしておきます。

$ git add .
$ git commit -am 'new project'
$ git remote add origin [ご自身のGitのレポジトリのURL].git
$ git push -u origin main

Amplifyを作成します

※すでにAmplify Cliが入っているとします。

❯ amplify version
5.2.1
amplify init

Amplify initでNext.jsのISR用の設定をします。

? Distribution Directory Path: .next

ここが最重要の設定です。

$ amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project nextsampleapp
? Initialize the project with the above configuration? No <- おすすめのままではだめ
? Enter a name for the environment dev
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: .next  // <- 最重要
? Build Command:  npm run-script build
? Start Command: npm run-script start
Using default provider  awscloudformation
? Select the authentication method you want to use: AWS profile // ここはご自身の環境に合わせてください

AmplifyのHostingを追加し、Next.jsをデプロイするCloudFrontなどを作成

CloudFrontは手動作成せず、Amplifyが裏で勝手に作成するものを使用します。つまり、CloudFrontを直接設定することはできないです。

$ amplify add hosting
? Select the plugin module to execute Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment) //Amplifyが作るものを利用する
? Choose a type Continuous deployment (Git-based deployments)
? Continuous deployment is configured in the Amplify Console. Please hit enter once you connect your repository

AWSのコンソール画面が立ち上がり、Frontend environmentから先程のGithubなどをリポジトリを選択します。

重要なのはNext.jsのVersionの設定です。 最新のNext.jsは11ですが、デフォルトのままだと10でデプロイされます。10でデプロイされるとISRのページが503エラーになってします。

現在はNext.js 11まで対応しています。

When you deploy a new Next.js app with Amplify, by default Amplify uses the most recent supported version of Next.js. Currently, Amplify supports Next.js version 11.

11と設定したいところですが、latestを指定するようです。

For Version, do one of the following: Enter 9 for support up to Next.js version 9.4.x. Enter 10 for support for Next.js versions 9.4.x to 10.x.x. Enter latest, to always upgrade to the latest Next.js version that Amplify supports.

一旦10でデプロイしてからあとでlatestに変えて再デプロイしても503エラーになってしまいました。(8/2時点)

必ず初めてのビルドでNext.jsのバージョンをlatestにするようにします。もし設定し忘れた場合は、作り直したほうが多分はやいはずです。

無事に設定がおわり、コンソールにもどりエンターを押すと、無事に連携できたことが確認できます。

? Continuous deployment is configured in the Amplify Console. Please hit enter once you connect your repository 
Amplify hosting urls: 
┌──────────────┬────────────────────────────────────────────┐
│ FrontEnd Env │ Domain                                     │
├──────────────┼────────────────────────────────────────────┤
│ main         │ https://main.xxxxxxxxxxxxxx.amplifyapp.com │
└──────────────┴────────────────────────────────────────────┘

amplify add hosting でファイルの差分ができますので、コミットしてpushしておこう

$ git add .
$ git commit -m 'add hosting'
$ git push

デプロイが完了するまで待ちます。

Amplifyのリダイレクトの設定

Next.jsはSPA,SSG,ISRに対応しています。基本的に/から初めてアクセスして使う文には問題ないのですが、ページの直リンクでアクセスしたとき404になってしまうので、index.hmtlを呼ぶように変更する必要あります。

初めてのデプロイが完了すると、リダイレクトの設定は最初1つ設定されていると思います。直アクセスして404のときにindex.htmlを呼ぶようにルールを追加します。

動作確認

AmplifyでデプロイされたURLにアクセスし、/isrのページにアクセスし、5秒間タイムスタンプが変わっていない。その後の更新でタイムスタンプが変わっている。