Open1

React Router v7&cloudflareのテスト

tonbitonbitonbitonbi

React Router v7&cloudflareのテスト

next.jsは重い、Vercelホスト前提の雰囲気(そんなに使ってるわけではないのでほんとかどうか知らない)なのでReact Router v7採用。
Web以外からも利用する可能性があるのでAPI用フレームワークとしてhono採用
個人プロジェクトにかけられるお金はないのでcloudflare採用。

テンプレート

https://github.com/yusukebe/hono-react-router-adapter
をチェックアウトしてexampleをコピー

~$ cp hono-react-router-adapter/examples/cloudflare-pages/ remix-hono-cloudflare-template -r
~$ cd remix-hono-cloudflare-template/
~/remix-hono-cloudflare-template$ npm install
npm error code EUNSUPPORTEDPROTOCOL
npm error Unsupported URL Type "workspace:": workspace:*

package.jsonがworkspace前提になってるので修正
その前にgitの初期化。.gitignoreにnode_modulesがなかったので追加。bun使うべきか?よくわかってないのでとりあえずnpmのまま。npm run devしてローカルで確認。

:~/remix-hono-cloudflare-template$ npm run dev

> dev
> react-router dev

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
~/remix-hono-cloudflare-template$ npm run deploy

> deploy
> npm run build && wrangler pages deploy

npm run deployして確認。
> build
> react-router build

vite v6.2.2 building for production...
✓ 40 modules transformed.
build/client/.vite/manifest.json                  1.27 kB │ gzip:  0.34 kB
build/client/assets/logo-CtyBJzAi.png            13.11 kB
build/client/assets/with-props-BIPqmJZE.js        0.22 kB │ gzip:  0.19 kB
build/client/assets/root-CMuCxoT-.js              0.43 kB │ gzip:  0.30 kB
build/client/assets/_index-DUnNUuyi.js            0.67 kB │ gzip:  0.41 kB
build/client/assets/chunk-GNGMS2XR-BXtwGOEY.js  105.22 kB │ gzip: 35.57 kB
build/client/assets/entry.client-DAqstufM.js    138.24 kB │ gzip: 44.62 kB
✓ built in 1.82s
vite v6.2.2 building SSR bundle for production...
✓ 7 modules transformed.
build/server/.vite/manifest.json        0.32 kB
build/server/assets/logo-CtyBJzAi.png  13.11 kB
build/server/index.js                   5.53 kB
✓ built in 121ms
▲ [WARNING] Warning: Your working directory is a git repo and has uncommitted changes

  To silence this warning, pass in --commit-dirty=true


✨ Compiled Worker successfully
🌍  Uploading... (9/9)

✨ Success! Uploaded 0 files (9 already uploaded) (0.46 sec)

✨ Uploading Functions bundle
🌎 Deploying...
✨ Deployment complete! Take a peek over at https://****.example-cloudflare-pages-akz.pages.dev

とりあえずここまででreact router&cloudflare&honoが利用できるようになった

honoの利用の確認

reactrouterのloader関数でhonoのAPIを利用するようにして確認。

~/remix-hono-cloudflare-template$ git diff .
diff --git a/app/routes/_index.tsx b/app/routes/_index.tsx
index 9ea44f2..a06c7af 100644
--- a/app/routes/_index.tsx
+++ b/app/routes/_index.tsx
@@ -1,12 +1,18 @@
 import type { Route } from './+types/_index'
 import logoDark from '/logo.png?inline'
 
-export const loader = (args: Route.LoaderArgs) => {
+interface Res {
+  message: string
+  var: string
+}
+export const loader = async (args: Route.LoaderArgs) => {
   const extra = args.context.extra
   const cloudflare = args.context.cloudflare
+  const res = await fetch(args.request.url+"api")
+  const j = await res.json() as Res
   const myVarInVariables = args.context.hono.context.get('MY_VAR_IN_VARIABLES')
   const isWaitUntilDefined = !!cloudflare.ctx.waitUntil
-  return { cloudflare, extra, myVarInVariables, isWaitUntilDefined }
+  return { cloudflare, extra, myVarInVariables, isWaitUntilDefined,...j }
 }
 
 export default function Index({ loaderData }: Route.ComponentProps) {
@@ -23,6 +29,8 @@ export default function Index({ loaderData }: Route.ComponentProps) {
       <h4>Extra is {extra}</h4>
       <h5>Var in Variables is {myVarInVariables}</h5>
       <h6>waitUntil is {isWaitUntilDefined ? 'defined' : 'not defined'}</h6>
+      <p>message = {loaderData.message}</p>
+      <p>var = {loaderData.var}</p>
       <img src={logoDark} alt='React Router' />
     </div>
   )

ここまでほとんど苦も無く成功。結構いいかも。

ログイン機能を作成

https://zenn.dev/achamaro/articles/b50dac4edf9883
を参考にログインページを作成と思ったけどsupabaseを利用したいので、https://github.com/kosei28/hono-supabase-auth