Code Lab 🤔

🤔

Next.jsのISRをVercelを使わずに実装する

nextjs

npm

aws

公開:

今回は、Next.jsのISRをVercelを使わずに実装するということで Vercelを使えば一発ですがVercelを使わないで実装はできるのかやっていきます。

ざっと調べた感じ、キーワードとしては

  1. next.js
  2. serverless-nextjs
  3. AWS CLI

でした。 AWSはちょっと触ったことがある初心者です。
結構難易度高そうだなと思いつつやっていきます。

導入していく

next.jsをinit

$ npx create-next-app --example with-typescript-eslint-jest with-typescript-eslint-jest-app --use-npm

Serverless Framworkを導入

まずは、Serverless Frameworkをinstall globalに入れるように書いてあるけど、プロジェクトに含めてみた。

$ npm install -D serverless

確認

$ npx serverless --version
Framework Core: 2.44.0 (local)
Plugin: 5.2.0
SDK: 4.2.3
Components: 3.11.0

AWS CLI の設定する

次の工程調べてたら、AWS CLIの設定いろいろしなきゃみたいだった。 とりあえず、AWSアカウントを作成して設定してみる(まじで初心者)

aws configure

aws configureを実行

$ aws configure
AWS Access Key ID [None]:

Access Keyを聞かれたので、AWSのcliについて調べる....

アクセスキーはアクセスキー ID と秘密アクセスキーからなり、AWS に対するプログラムによるリクエストに署名するときに使用されます。アクセスキーがない場合は、AWS マネジメントコンソールから作成できます。ベストプラクティスとして、不必要なタスクでは、AWS アカウントのルートユーザーアクセスキーを使用しないでください。代わりに、ご自身のアクセスキーを持つ新しい管理者 IAM ユーザーを作成します 。

アクセスキー ID とシークレットアクセスキー

これですね。 IAMでユーザー作ろうねってことみたいです。

ポリシーの作成

ポリシーの作成で必要な権限を設定.....

必要な権限についてはAWS Permissions for deploymentを参考にしていきます

sqsの権限はISRを使うときは必須なので、今回は追加しています。

ユーザーグループの作成

適当に名前をつけて、先ほど作成したポリシーを選択し保存
基本的にカスタムドメインで必要なもの以外選択しました

ユーザーの作成
  1. ユーザー名を適当に決める
  2. アクセスの種類はプログラムによるアクセス
  3. 次のステップへ
  4. 先ほど作ったユーザーグループを指定
  5. 次のステップへ
  6. タグはつけず次のステップへ
  7. 問題なければユーザーの作成を押して完了です

生成されたAccess KeySecret Access Keyをコピーしておいて...

再度aws configureする
$ aws configure

Access KeySecret Access Keyを貼り付けて、あとはデフォのままenter
多分、よくわからなかったら調べなさいと言われるだろうけど、とりあえず動かしたいってモチベなので....

$ export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

そして、exportも設定してここは完了です!

Serverless Next.js Componentを導入

serverless.yamlを作成し...

serverless.yaml
myApp:
  component: '@sls-next/serverless-component@1.20.0-alpha.4'

componentを指定する 今回はISR対応したいので@sls-next/serverless-component@1.20.0-alpha.4を指定

いったんデプロイしてみる

なんか、serverless.yamlinputsを指定しているところが多いのですが、Zero-configを掲げてたと思うのでいけるんじゃない?という気持ちでやっちゃいます。

好奇心だいじ

$ npx serverless

色々デプロイされ....


  myApp: 
    appUrl:         https://********.cloudfront.net
    bucketName:    ********
    distributionId: ********

  ******************************************************************************************************************************************************************
  Warning: You are using the beta version of Serverless Components. Please migrate to the GA version for enhanced features: https://github.com/serverless/components
  ******************************************************************************************************************************************************************


  37s › myApp › done

Warningでてますが、ISR対応がまだベータ版なのでしかたなしですね。

ISR対応して確認していく

まずは、test/isr.tsxを作成

test/isr.tsx
import React from 'react'
import { GetStaticProps } from 'next'

interface Props {
  date: Date
}

export const getStaticProps: GetStaticProps = async () => {
  return {
    props: {
      date: new Date().toLocaleString(),
    },
    revalidate: 5,
  }
}

const Isr: React.VFC<Props> = ({ date }) => <p>{date}</p>

export default Isr

デプロイ

503 ERROR
The request could not be satisfied.

503エラーでました。 ふて寝しそうです。

オーマイオーマイ...
見落としてました権限も修正しないとですね
sqsのところが*になってますね

↓参考

オーマイオーマイ... もうこれでしたねしっかりと問題として上がってますね

Sure, let me take a look at the logs and let you know what happened EDIT: looks like the Lambda itself doesn't have permissions to access SQS endpoint:

{
    "errorType": "AccessDenied",
    "errorMessage": "Access to the resource https://sqs.us-east-1.amazonaws.com/ is denied.",
....

I'll fix but we should also make sure to mention in Readme to give the Lambda itself permissions to access SQS (if it > > wasn't obvious or already done)

↓参考

最終的に、CloudFront / SQS / Lambdaなどなど削除し、プロジェクト内の.serverlessを削除してから 再度デプロイしたら正常に権限が適用され、問題なく動作することを確認しました!

参考

めっちゃ参考にさせてもらいました! ありがとうございます....!