📣

(ハックなしで)Amplify HostingにNext.js v14 SSG使えるようになったよ!

2024/09/27に公開

はじめに

こんにちは!
「愛犬との毎日を楽しく便利にするアプリ オトとりっぷ」でエンジニアしています、足立です!

2024 年 9 月 27 日に発表された、Amplify Hosting への Next.js v14 SSG を試したいと思います。
ハックなしで?元々できたんじゃないの? と思われている方の参考になれば幸いです。

Next.js SSG 利用時のハック

実は、Amplify Hosting で Next.js v14 の SSG を利用する場合、ちょっとしたハックが必要でした。
具体的には、こちらの記事に詳しく書かれています。

https://developers.play.jp/entry/2023/11/06/085943

大まかにいうと、

  • Amplify Hosting には静的サイトを扱うためのWEB、動的サイトを扱うためのWEB_DYNAMIC、そして両方扱える新規格のWEB_COMPUTEの 3 つのプラットフォームモードが存在し、どのモードに振り分けられるかはpackage.jsonの中身を見て判断される
  • Next.js は、ビルドコマンドが"build": "next build"の場合WEB_COMPUTEに、"build": "next build && next export"の場合WEBに振り分けられる
  • Next.js v14 でビルドコマンドが"next build"に統一された影響で、SSR, SSG いずれであってもWEB_COMPUTEモードに振り分けられた
  • 今回の変更以前のWEB_COMPUTEモードには Next.js SSR 設定しか無かったので、SSG したければビルドコマンドを"build": "next build && next export"にするしかない
  • ならばハックだ

ということです。具体的には、Amplify に認識してもらう用のダミー用のビルドコマンドと、実際に利用するビルドコマンドを分ける方法でした。

package.json
"scripts": {
    ...
    "build": "next build && next export",
    "build:release": "next build",
    ...
}

アップデート後の利用方法

今回のアップデートでこのようなハックが不要になりました。
実際に確認してみましょう。

まず、テンプレートから Next.js プロジェクトを作成します。

$ npx create-next-app@latest

✔ What is your project named? … ssg-amplify
✔ Would you like to use TypeScript? … Yes
✔ Would you like to use ESLint? … No
✔ Would you like to use Tailwind CSS? … No
✔ Would you like to use `src/` directory? … Yes
✔ Would you like to use App Router? (recommended) … No
✔ Would you like to customize the default import alias (@/*)? … No

次に、next.config.mjsを修正し、SSG 設定に変更します。

next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
+  output: 'export',
};

export default nextConfig;

次に、src/index.tsxから余計な内容を削除します。

src/index.tsx
export default function Home() {
  return (
    <div>
      <h1>Amplify SSG </h1>
    </div>
  );
}

次に、デプロイ設定用を記述するためのamplify.ymlを root 以下に作成します。

amplify.yml
version: 1
frontend:
  phases:
    preBuild:
      commands:
        - npm ci
    build:
      commands:
        - npm run build
  artifacts:
    baseDirectory: .next
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

ポイントは、baseDirectory: .nextとすることですね。

あとは他の Hosting の場合と同じで、Git 連携してパイプラインを構築し、自動的にデプロイされるのを待ちます。
以前だと、ビルド時に「SSR 用の設定がないぞ!」と怒られていたエラーが出なくなりました。この辺の設定が変更されたってことですね。

完了すると、https://main.<AppID>.amplifyapp.comのような URL が払い出されるので、アクセスして無事表示されるのを確認します。簡単ですね。

Hosting の設定詳細を確認すると、

プラットフォームがWEB_COMPUTE、フレームワークがNext.js SSRとなってますね。

既存からの移行方法

では、すでにハックで Next.js v14 SSG を利用している人はどうすればいいのでしょう。
公式にマイグレーションガイドが出ていないので、本日(2024 年 9 月 27 日)時点での方法を紹介します。

まず、package.jsonを本来のビルドコマンドに書き換えます。

package.json
"scripts": {
    ...
-    "build": "next build && next export",
-    "build:release": "next build",
+    "build": "next build",
    ...
}

次にamplify.ymlを書き換えます。

amplify.yml
version: 1
frontend:
  phases:
    preBuild:
      commands:
        - npm ci
    build:
      commands:
        - npm run build
  artifacts:
-    baseDirectory: out
+    baseDirectory: .next
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

で、この状態でデプロイするんですが、それだけだとエラーになるかもしれません。その理由は、元々WEBモードの人は Next.js SSR を検知するとWEB_DYNAMICモードに振り分けられてしまうみたいです。なので、手動でWEB_COMPUTEモードに変更する必要があります。
また、もしかするとエラーは出ないがページにアクセスできないかもしれません。その理由は、WEBモードから切り替わっていないのにbaseDirectory: .nextにしたからアクセスするためのファイルが存在しないからです。なので、この場合も手動でWEB_COMPUTEモードに変更する必要があります。

まず、AWS マネージメントコンソール上で CloudShell を起動します。

次に、コンソールに以下の通り入力します。

$ aws amplify update-app --app-id <APP_ID> --platform WEB_COMPUTE
$ aws amplify update-branch --app-id <APP_ID> --branch-name main --framework 'Next.js - SSR'

この状態で再度ビルド開始すると、無事に完了すると思います。

アップデート後の注意事項

Next.js の trailingSlash オプションに難ありです。

https://nextjs.org/docs/app/api-reference/next-config-js/trailingSlash

この設定は true にすると、/aboutpage は、/about.htmlではなく/about/index.htmlにアクセスするようになります。その結果/aboutpage へアクセスすると/about/page にリダイレクトされます。false にすると逆に/about/page にアクセスすると/aboutpage にリダイレクトされます。

この設定が、アップデート後に適応されません。
その結果、trailingSlash : trueにすると今まで/aboutでアクセスできていたページにアクセスできない事象が発生します。逆にtrailingSlash : false (デフォルトの場合もこちら) にすると/about/でアクセスできていたページにアクセスできなくなります。
ご注意ください。

関連ドキュメント

公式ドキュメントはこちらです。
https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/deploy-nextjs-app.html#build-setting-detection-ssg-14

また、関連の Issue はこちらです。

https://github.com/aws-amplify/amplify-hosting/issues/3872

最後に

ここまで読んでいただきありがとうございました。
ちょっとしたアップデートですが、地味に嬉しいやつですね、最近 Amplify Hosting 関連のアップデートが続いており、日々ワクワクしています。

もし犬専用の音楽アプリに興味を持っていただけたら、ぜひダウンロードしてみてください!

https://www.oto-trip.com/

Discussion