Counts the Clouds

Next.jsをAmplifyにデプロイする
2021.11.09

Next.js
AWS
Amplify

danielle-macinnes-ahzw2Tg7IXs-unsplash.jpg

AmplifyのCLIツールをインストール

公式のとおり試してみる。

% npm install -g @aws-amplify/cli
...
+ @aws-amplify/cli@6.3.1
added 1421 packages from 781 contributors in 121.088s

Amplify CLIの設定

ウェブでAWSコンソールが開く。ログイン済みだったのでこのままEnter。

% amplify configure
Follow these steps to set up access to your AWS account:

Sign in to your AWS administrator account:
https://console.aws.amazon.com/
Press Enter to continue

Specify the AWS Region
? region:  ap-northeast-1

Regionはap-northeast-1(東京)を選択。

IAMユーザーの作成

またAWSコンソールが開くので、ユーザーを作成する。作成したユーザーのアクセスキーとシークレットキーを入力。

Specify the username of the new IAM user:
? user name:  amplify-110chang-com-next-user
Complete the user creation using the AWS console
https://console.aws.amazon.com/iam/home...
Press Enter to continue

Enter the access key of the newly created user:
? accessKeyId:  ********************
? secretAccessKey:  ****************************************
This would update/create the AWS Profile in your local machine
? Profile Name:  default

Successfully set up the new user.

Next.jsのアプリを準備

% npx create-next-app@latest

Currently, Amplify doesn’t fully support Image Component and Automatic Image Optimization available in Next.js 10.

AmplifyではImage Optimizationに対応していないそうなので、該当部分を書き直す。

- import Image from 'next/image'
// ...
- <Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
+ <img src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />

npm scriptのbuildコマンドを書き直す。next exportは静的ファイルをoutディレクトリに書き出す。つまりSSG Onlyということ。

  "scripts": {
    "dev": "next dev",
-   "build": "next build",
+   "build": "next build && next export",
    "start": "next start"
  },

The build script next build && next export indicates that the app supports SSG pages only. next export allows you to export your app to static HTML, which can be run standalone without the need of a Node.js server.

eslintの設定を変更。

  {
    "extends": ["next", "next/core-web-vitals"],
+   "rules": {
+     "@next/next/no-img-element": "off"
+   }
  }

ビルドしてみる。

% yarn build
yarn run v1.22.11
$ next build && next export
...
Export successful. Files written to /Users/.../nextjs-amplify-trial/out
✨  Done in 11.06s.

Amplifyアプリの初期化

Amplifyの初期化をプロジェクトルートで行う。

% amplify init

いろいろ訊かれる。

? 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: out
? 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

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html

? Please choose the profile you want to use default
Adding backend environment dev to AWS Amplify Console app: d15ieg747mn5le
...

Distribution Directory Pathだけ、静的ファイルがあるoutディレクトリに変更する。それ以外はデフォルト。

? Distribution Directory Path: out

終わると、Amplifyのコンソールにアプリが追加されている。ローカルにもいろいろ追加されてる。

Amplifyホスティングの追加とデプロイ

次にホスティングを追加。公式に従ってManual deploymentを設定する。Manual deploymentはコマンドで端末からデプロイする。

% amplify add hosting
? Select the plugin module to execute Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
? Choose a type Manual deployment

You can now publish your app using the following command:

Command: amplify publish

デプロイが終わるとURLが表示されるのでアクセスできる。

% amplify publish
✔ Successfully pulled backend environment dev from the cloud.
...
Export successful. Files written to /Users/.../nextjs-amplify-trial/out
✔ Zipping artifacts completed.
✔ Deployment complete!
https://dev...amplifyapp.com

ダイナミックルートを追加

公式に従い、ダイナミックルートを試してみる。next exportしているので、AWS側でリダイレクトを設定しないといけない。

/pages/posts/[id].jsを作成。

// /pages/posts/[id].js
import { useRouter } from 'next/router'

const Post = () => {
  const router = useRouter()
  const { id } = router.query

  return <p>Post: {id}</p>
}

export default Post
% amplify publish

Amplifyコンソールの“書き換えて、リダイレクト”からリダイレクト設定を追加する。翻訳がひどい。

この辺を手動で設定しなければならないのはちょっと厳しいな。

ハイブリッドアプリ

ハイブリッドアプリ(SSR + SSG)のデプロイも試してみる。こちらはGitHubからソースコードを取得させるので、GitHubにpushする。

% npx create-next-app@latest
...
% cd nextjs-amplify-hybrid-trial
% git remote add origin git@github.com:...
% git push -u origin main

Distribution Directory Pathを.nextディレクトリに変更する。それ以外の設定はそのまま。

? Distribution Directory Path: .next

アプリの初期化

% amplify init
...
? 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

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html

? Please choose the profile you want to use default
Adding backend environment dev to AWS Amplify Console app: d3lshkmfnnmule
...

ホスティングを追加

% amplify add hosting
? Select the plugin module to execute Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
? Choose a type Continuous deployment (Git-based deployments)
? Continuous deployment is configured in the Amplify Console. Please hit enter once you connect your repository

今度はGitHubからデプロイするのでContinuous deploymentを設定。

  1. コンソールが開くので、“Frontend environments”でGitHubを選択して“Connect branch”。
  2. GitHub側のダイアログが開くので許可する
  3. “リポジトリブランチの追加”で先ほど作成したブランチを選択して次へ。
  4. “ビルド設定の構成”でEnvironmentをdevに
  5. はじめと同様にユーザーロールを作って設定して次へ。

コンソールの“Frontend environments”で、わかりにくいがデプロイが進む。ビルドでこけた。

The engine “node” is incompatible with this module.

ログを見ると環境とアプリでnodeのバージョンが合ってないみたい。

[INFO]: # Executing command: yarn install
[INFO]: yarn install v1.22.0
[INFO]: [1/4] Resolving packages...
[INFO]: [2/4] Fetching packages...
[WARNING]: error next@12.0.3: The engine "node" is incompatible with this module. Expected version ">=12.22.0". Got "12.21.0"
[WARNING]: error Found incompatible module.
[INFO]: info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
[ERROR]: !!! Build failed
[ERROR]: !!! Non-Zero Exit Code detected
[INFO]: # Starting environment caching...
[INFO]: # Environment caching completed
Terminating logging...

“ビルドの設定”でltsの最新をインストールするようにした。

version: 1
frontend:
  phases:
    preBuild:
      commands:
        - nvm install lts/erbium
        - nvm use lts/erbium
        - yarn install
    build:
      commands:
        - yarn run build
  artifacts:
    baseDirectory: .next
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

ビルドが終わらない……

10分ぐらいかかったけどデプロイできた。ltsのインストールに時間かかっているのかも。

AmplifyはAWSの画面のわかりにくさ継承しているし、現時点ではあまり使いたいとは思えなかった。