👌

はじめてのPages(2): Cloudflare Workers でKVの操作とNext.jsによる簡単なスクリプト実行を試す

2023/03/04に公開
5

この記事は、はじめてのPagesの続きです。

前回はPagesで簡単なHello WorldとWorkersの操作を試しました。この記事では2点、1) Workers経由でKVの操作 2) Next.jsによる簡単なスクリプト実行を試してみます。
前回同様gitの操作などは記事の範囲外となります。

  1. Pagesの新プロジェクト起動
    まずはこの手順を終わらせてください。
    functions/apiの下に"kvtest.js"というファイルを作成し以下を保存してください。
export async function onRequest(context) {
    const task = await context.env.TODO_LIST.get("test");
    return new Response(task);
  }

以下のコマンドを実行してDeployを行います。

git add -A
git commit -m "working example"
git push -u origin main -f

以下のようにマネージメントコンソールでデプロイが行われるまで待ちます。

この手順を参考にをKVを作っておきます。
また以下のようにテストデータを入れておきます。

その後以下の"設定"→"Functions"をクリックします。

"バインディングを追加"を押します。

このように設定し"保存"を押します

これでPages用WorkersからKVの"todo_list"を認識するようになりました。

その後"/api/kvtest"にアクセスすると値が無事読み込めていることがわかります。

もしエラーが出る様でしたら再度上のgitコマンドを実行しなおしてみてください。

Workersから直接KVを操作するときは以下のコードでした。

export default {
  async fetch(request, env, ctx) {
    const value = await env.TODO_LIST.get("test");

一方Pagesでは以下となっていることに注意してください。

export async function onRequest(context) {
    const task = await context.env.TODO_LIST.get("test");

少し呼び出しが変わっていますね。

  1. Next.jsによる簡単なスクリプト実行
    それでは一度Pagesのプロジェクトを削除してください。
    "設定"タブの一番下の画面にあります。

    Pagesでは二つのプロジェクトが1つのGitレポジトリを共有できないためです。(GitへのプッシュがDeployをトリガーしますので当たり前といえば当たりですね)

まずターミナルで以下を実行します。

cd ..
npx create-next-app my-app

入力は全てNoを選び、一番最後の入力はそのままエンターを押して下さい。
"pages/api"の下にある"hello.js"を以下の値で置き換えます。

export const config = {
  runtime: 'edge',
}

export default async function (req) {
  return Response.json({ name: 'John Doe' })
}

Cloudflare PagesはWorkersと異なりNode.jsの実行環境も構築することが可能ですが、今回のケースではEdgeランタイムという物を用いてNext.jsをオプトインさせ、Next.jsの実行を可能としています。詳しくはこのブログを見てください。

次に"next.config.js"を以下の値で置換して保存します。

const nextConfig = {
  reactStrictMode: true,
  experimental: {
    runtime: 'edge',
  }
}

module.exports = nextConfig

これによりエッジランタイムへのNext.jsオプトインが有効化されます。
つぎに/api/hello/route.jsを作成し以下の内容で保存します。

export const config = {
  runtime: 'edge',
}

export default async function (req) {
  const kvvalue = await process.env.KV.get('test')
  return new Response(kvvalue)
}

その後

npm install --save-dev @cloudflare/next-on-pages

を実行して必要モジュールをインストールしておきます。

以下のコマンドをターミナルで実行しgitレポジトリと連携させます。

git remote add origin <YOUR_GITHUB_REPO_URL>
git branch -M main
git push -u origin main -f

<YOUR_GITHUB_REPO_URL>は勿論皆さんの値に置き換えてください。
私の例であればhttps://github.com/harunobukameda/Pagesになります。

error: remote origin already exists.

エラーが手た人はgit remote remove originを実行してから再度上のコマンドを実行してください。

Pagesのプロジェクトを新規に作成します。

"プロジェクトを作成"を押します。
その後"gitに接続"を押します。

"Pages"を選び"セットアップの開始"を押します。
フレームワークに"Next.js"を選びます。

環境変数に以下を追加して"保存してデプロイする"を押してください。
(2023/12/09 Updates 16ではなく18を指定してください)

SettingsのFunctionsに以下を追加します。

デプロイが成功したらアクセスします。

このようにNext.jsが起動していることがわかります。
また"/api/hello"にアクセスするとサーバサイドでjsが実行され結果がJSONとしてクライアントに出力されていることがわかります。

この環境では上でテストしたfunctionsは無効化され"/pages/api"のjsが有効化されますので注意してください。

では最後にこの環境からKVを呼び出してみます。"hello.js"を以下に書き換えて再度コミット&プッシュしてください。

export const config = {
  runtime: 'edge',
}

export default async function (req) {
  const kvvalue = await process.env.KV.get('test')
  return new Response(kvvalue)
}


このようにKVをバインドしておきます。
KVのアイテムで"test"というキーを持つアイテムが表示されるはずです。

では今度はSSRを試してみましょう。hello.jsコードを以下に置き換え再度コミット&プッシュします。

export const config = {
  runtime: 'edge',
}

export default async function getServerSideProps() {
  const random = Math.floor(Math.random() * 100);
  return new Response(random);
}

サーバ側で乱数が生成され値が表示されます。
このページを参考にしました。

宿題:
色々検証した中でgetStaticPropsも同じ動き(デプロイ時ではなく読み込み時に乱数が生成されているよう)をしているようですので、ここは引き続き調査します。
またnext.jsのドキュメントにあるようにprops形式でreturnを返すとエラーになるようです。

Discussion

yusukebeyusukebe

上でやったようなenv.KVのようなKVへの接続が行えずGitでIssueとなっています。実際にやってみましたができませんでした。この環境でKVを使う方法は確認中です。

これなんですが、Issueのこちらのコメントにあるように、 process.env でアクセスできるみたいです。
https://github.com/cloudflare/next-on-pages/issues/1#issuecomment-1403845325

あと、

Cloudflare PagesはWorkersと異なりNode.jsをサポートします。そしてEdgeランタイムという物を用いてNext.jsをオプトインさせ、Next.jsの実行を可能としています。

Cloudflare Pagesも基本的にWorkersで動いてるので、Node.jsはサポートしていません(これからサポートするかもしれません)。だからこんなまどろっこしいことをしています。Edge RuntimeはVercelも含めて、Node.jsとは違うランタイムのことを指します。

kameoncloudkameoncloud

Node.jsの件表現変えました。process.env試してみます。ありがとうございます。

kameoncloudkameoncloud

const kvvalue = await process.env.KV.get('test')
で無事値がとれました。いつもありがとうございます。

yusukebeyusukebe

Cloudflare PagesはWorkersと異なりNode.jsが動作しますが、Edgeランタイムという物を用いてNext.jsをオプトインさせ、Next.jsの実行を可能としています。詳しくはこのブログを見てください。

繰り返しになりますが、Cloudflare Pagesはいくつかのフレームワークのアプリケーションをビルドする際にNode.jsが使えたりしますが、今回の文脈では「Node.jsは動作しません」。上記のブログでもNode.jsが動作するとは書かれていません。Cloudflare PagesをダイナミックにしているランタイムはWorkersと同じなので、当然のことです。

kameoncloudkameoncloud

コメントありがとうございます。今回の環境ではなく汎用の話としてPagesではNode環境を作ることは可能と言いたかった次第ですが、ご指摘の通りわかりづらいので以下に修正しました。

Cloudflare PagesはWorkersと異なりNode.jsの実行環境も構築することが可能ですが、今回のケースではEdgeランタイムという物を用いてNext.jsをオプトインさせ、Next.jsの実行を可能としています。詳しくはこのブログを見てください。