📚
Remix on Hono on Cloudflare Workers
9/26 Cloudflare Workersが静的アセットの配信に対応するようになりました。
これまで
Remix on Honoしたい
-> Workersにデプロイすると、Workersが静的アセットを返すのがイマイチ
-> イマイチだからPagesにデプロイするけど、honoと組み合わせるのが少しめんどくさい
みたいになっていた悩みが解決しそうです。
Static Assetsのドキュメント
- リクエストが静的アセットに一致すれば静的アセットを返し、一致しなければworkerを実行する
- 静的アセットへのリクエストは無料で無制限
- 静的アセットの設定wrangler.toml
assets = { directory = "./public/" } # こうすればworker内からも参照できる(env.ASSETS) assets = { directory = "./public/", binding = "ASSETS" }
動作確認
リポジトリ
セットアップ
こちらのページを参考にセットアップします。
pnpm create cloudflare@latest remix-on-cloudflare-workers --framework=remix --experimental
デプロイしてみる
cd remix-on-cloudflare-workers
pnpm run deploy
Cloudflareのコンソールを確認しに行くとデプロイメントが2つ増えています。
1つ目のバージョンIDを確認すると
Assets have not yet been deployed...
とのこと。2つ目のバージョンID(latest)を確認すると
表示されました。
Honoを追加する(11/13更新)
記事作成と同日にhono-remix-adapter
がworkers対応していたので、そちらを利用するように更新しました。
pnpm add hono hono-remix-adapter
pnpm add -D @hono/vite-dev-server
- Honoのエントリとして
server/index.ts
を作成
server/index.ts
import { Hono } from "hono";
import { poweredBy } from "hono/powered-by";
const app = new Hono();
app.use(poweredBy());
app.get("/api", (c) => {
return c.json({ message: "Hello, World!" });
});
export default app;
vite.config.ts
- cloudflareDevProxyVitePlugin({
- getLoadContext,
- }),
+ cloudflareDevProxyVitePlugin(),
// ...
+ serverAdapter({
+ adapter,
+ getLoadContext,
+ entry: "server/index.ts",
+ }),
- Cloudflare Workersのエントリとして
worker.ts
を作成
worker.ts
import handle from "hono-remix-adapter/cloudflare-workers";
// @ts-ignore This file won’t exist if it hasn’t yet been built
import * as build from "./build/server";
import { getLoadContext } from "./load-context";
import server from "./server";
export default handle(build, server, { getLoadContext });
wrangler.toml
-main = "./server.ts"
+main = "./worker.ts"
11/13更新前
pnpm add hono
server.ts
を書き換えます。
server.ts
export default {
async fetch(request, env, ctx) {
try {
const loadContext = getLoadContext({
request,
context: {
cloudflare: {
cf: request.cf,
ctx: {
waitUntil: ctx.waitUntil.bind(ctx),
passThroughOnException: ctx.passThroughOnException.bind(ctx),
},
caches,
env,
},
},
});
return await handleRemixRequest(request, loadContext);
} catch (error) {
console.log(error);
return new Response("An unexpected error occurred", { status: 500 });
}
},
} satisfies ExportedHandler<Env>;
↓
こんな感じ
server.ts
>const app = new Hono();
>app.use(poweredBy());
>app.use("*", async (c) => {
> const request = c.req.raw;
> const ctx = c.executionCtx;
try {
const loadContext = getLoadContext({
request,
context: {
cloudflare: {
cf: request.cf,
ctx: {
waitUntil: ctx.waitUntil.bind(ctx),
passThroughOnException: ctx.passThroughOnException.bind(ctx),
},
caches,
> env: env(c),
},
},
});
return await handleRemixRequest(request, loadContext);
} catch (error) {
console.log(error);
return new Response("An unexpected error occurred", { status: 500 });
}
});
>export default app;
デプロイしてみる
pnpm run deploy
ページにアクセスするとx-powered-by: Hono
となっていることが確認できました。
参考
Discussion