Next.js(React)でフロントエンド、Honoでバックエンドを開発したものをCloudflare Workersにデプロイ出来るようにしました

# 概要

先日よりCloudflare 公式のドキュメントより 「新しいプロジェクトにはCloudflare PagesよりもCloudflare Workersの使用を推奨しています。」と発表されました。
現代において主なユースケースとしては「Cloudflare Workers に SPA アプリケーションをデプロイする」ことがあげられると思われます。
その方法についてはこちらの記事にて大変詳しく解説されていました

[Cloudflare Workers に SPA アプリケーションをデプロイする](https://zenn.dev/mierune/articles/cloudflare-workers-static-spa-deploy)

こちらの記事を参考にして SPAアプリケーション(Webフロントエンド)を Next.js(React)で、バックエンド(WebAPI)をHonoで開発し、双方とも共存したものをCloudflare Workersにデプロイすることができたので(個人的な備忘録も兼ねて)その方法を紹介していきます。

なお実際にCloudflare Workersに共存させることに成功したソースコードはこちらになります

https://github.com/TakuKobayashi/SecureAuthChallange

実際にデプロイして公開しているサイトはこちらになります

https://secure-auth-challange.hackathonportal.workers.dev/

なお、[SecureAuthChallange](https://github.com/TakuKobayashi/SecureAuthChallange) のプロジェクトはセキュリティがしっかりした認証方式でのログインを可能にしたWebサイトを作ること試みたWebサイトになります(本プロジェクトの詳細についてはまた別の記事としてまとめます)

# 手順

## Next.JSにて新規プロジェクトを構築する

まずは以下のコマンドを実行してNext.jsのプロジェクトを作成します。
(※ すでにNext.jsのプロジェクトが存在する場合は不要)

```
npx create-next-app@latest プロジェクト名
```

#### 参考

* [How to set up a new Next.js project](https://nextjs.org/docs/app/getting-started/installation)

## Next.JSのプロジェクトからHTMLをエクスポートする

Next.jsをBuildした時に初期設定ではHTMLが出力されないので、Build時にHTMLが出力できるようにするために `next.config.js` に以下の要素を追記します。

```next.config.js
const nextConfig = {
  output: 'export',
}
module.exports = nextConfig
```

この状態でBuildを行います

```
yarn run build
```

※ ここでは `yarn` を使用していますが `npm` や `pnpm` など好みのツールのコマンドに置き換えてください (以下同様)

これで `out/` 以下にHTMLが出力されます(出力先は変更することもできます)

#### 参考

* [Static Exports](https://nextjs.org/docs/pages/guides/static-exports)
 
## Next.JSプロジェクトをCloudflare Workersにデプロイする

Cloudflare WorkersにCLIよりデプロイを行うために `wrangler` をインストールします

```
yarn add -D wrangler
```

wranglerの設定ファイルとして `wrangler.jsonc` を作成します

```
touch wrangler.jsonc
```

`wrangler.jsonc` に以下のような形で設定情報を記述していきます

```wrangler.jsonc
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "nextjs-hono-cloudflare-workers-deploy-example",
  "compatibility_date": "2025-05-04",
  "assets": {
    "directory": "./out/"
  }
}
```

上記のように `assets`の `directory` にはNext.JSプロジェクトでBuildすることにより出力された HTMLのプロジェクトのパスを指定します。(ここでは [Next.JSのプロジェクトからHTMLをエクスポートする](#Next.JSのプロジェクトからHTMLをエクスポートする)で出力された `out/` を指定しています)
このHTMLの内容がCloudflare Workersにデプロイされます。
次に Cloudflare Workersにデプロイを行うために `package.json` に以下のように`wrangler` 関連のコマンドを追記します

```package.json
{
  ...
  "scripts": {
    ...
    "cloudflare:dev": "wrangler dev",
    "cloudflare:deploy": "wrangler deploy --minify",
    "cloudflare:cf-typegen": "wrangler types --env-interface CloudflareBindings"
  },
}
```

`package.json` に追記したことで以下のコマンドを実行することでCloudflare WorkersにNext.jsのプロジェクトをデプロイすることができます。

```
yarn run cloudflare:deploy
```

デプロイが正常に完了するとURLが出てくるのでそのURLにアクセスすることで動作を確認することができます。

## Next.jsプロジェクトをCloudflare Workers環境下でのローカルサーバーの起動

`wrangler` を介したローカルサーバーの立ち上げを行う場合は以下のコマンドを実行します

```
yarn run cloudflare:dev
```

この時、`wrangler.jsonc` には`assets`には以下のように記述されています

```wrangler.jsonc
{
  ...
  "assets": {
    "directory": "./out/"
  }
}
```

このため、`./out/` 以下にhtmlがない場合ローカルサーバーを立ち上げようとするとエラーとなってしまいます。そのため、フロントエンドの確認を行う場合は毎回Buildしておく必要が出てきますので、ほっとリロードには対応しておりません。そのためNext.js上での動作確認を行う場合は `wrangler` を用いたローカルサーバーの立ち上げよりも、Next.js側のローカルサーバー(以下のコマンドを実行)を起動して開発を進めていくことをオススメします

```
yarn run dev
```

## HonoをインストールしてWebAPIの開発を行う

バックエンドの開発においては主にHonoやExpressなどのフロントエンドとは異なるライブラリ・フレームワークを用いた開発を行うのが一般的です
今回はフロントエンドとしてNext.jsにて開発を行いつつ、バックエンドとしてはHonoを採用し、Next.jsと同一のプロジェクト(同一のCloudflare Workersとして)開発を進めていきます。
(※ RDBの仕様があるのでたいていの場合はバックエンドはフロントエンドとは異なるプロジェクトとして管理していくことをオススメします)
今回はNext.jsと同一のプロジェクトとして開発を進めていくのでNext.jsのプロジェクト内でhonoをインストールします。

```
yarn add hono
```

Honoを用いたバックエンド以下の開発は `api/` 以下で行っていきます(バックエンドのソースコードはNext.jsとは別の領域で記述していくことをオススメします)
`api/index.ts` にhono側のルートのソースコードとして以下のように記述していきます

```index.ts
import { Hono } from 'hono'

const app = new Hono().basePath('/api')

app.get('/', (c) => {
  return c.text('Hello Hono!')
})

export default app
```

`new Hono().basePath('/api')` としたのは、ルートパスはすでにNext.js側のHTMLで使用しているため、バックエンドの処理部分は `/api` 以下とpathを切ることで切り分けるようにしています。
cloudflare workersにバックエンドの部分のソースコードを適用させるには `wrangler.jsonc` に 以下のように `main` 句を追加して、バックエンドが起動するルートの`ts`または`js`ファイルのパスを指定します

```diff_wrangler.jsonc
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "nextjs-hono-cloudflare-workers-deploy-example",
  "main": "api/index.ts",
  "compatibility_date": "2025-05-04",
  "assets": {
    "directory": "./out/"
  },
}
```

これで `"api/index.ts"` はバックエンド部分として認識されるようになったので、以降はhono側でリクエストのパスをきっていって開発を進めていきます。
バックエンド部分も含めてCloudflare Workersへとデプロイを行うには以下のコマンドを実行します

```
yarn run cloudflare:deploy
```

この状態で ルートパスはNext.jsのフロントエンドエンド部分、ルートパス/api/以下はHonoによるバックエンド部分、両共が共存した状態で Cloudfalre Workersにデプロイされることとなります。

※ なお初回のデプロイはデプロイが完了してもCloudflare側に反映されるまで少し時間がかかるので」、時間をおいて動作確認を行うようにしてください。

以上でWebフロントエンドとバックエンド、双方ともが共存状態でCloudflare Workersにデプロイが行われている状態にすることができました。