Open9
cloudflare Pagesにremixアプリをデプロイしていく
![yuppe](https://res.cloudinary.com/zenn/image/fetch/s--pdj_rsd3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/dcea63de60.jpeg)
基本的にこちらを参考に進めてみる
![yuppe](https://res.cloudinary.com/zenn/image/fetch/s--pdj_rsd3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/dcea63de60.jpeg)
パッケージマネージャにはpnpmを使ってみた
installがめちゃくちゃ早い。
どうやらlockファイルはpnpm-lock.yamlというyaml拡張子のファイルらしい。
![yuppe](https://res.cloudinary.com/zenn/image/fetch/s--pdj_rsd3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/dcea63de60.jpeg)
デフォルトテンプレートのdependenciesを見るとNodejsランタイムが想定されているので、これをCloudflare Pages用に対応していく
pnpm rm @remix-run/node
![yuppe](https://res.cloudinary.com/zenn/image/fetch/s--pdj_rsd3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/dcea63de60.jpeg)
cloudfrare用の開発環境周りセットアップ(インストール編)
- cloudfrareのリソースいじるようのCLI追加
pnpm add -D wrangler
- TS環境でCloudflare Pages Functions(Workers)を使うための型定義ファイルを導入
pnpm add @cloudflare/workers-types -D
今回はRemix自体に用意されたexpressベースのサーバーも使用しないので外す
pnpm rm @remix-run/serve
- Cloudflare/PagesでRemixを起動するアダプターの追加
pnpm add @remix-run/cloudflare @remix-run/cloudflare-pages
![yuppe](https://res.cloudinary.com/zenn/image/fetch/s--pdj_rsd3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/dcea63de60.jpeg)
cloudfrare用の開発環境周りセットアップ(設定ファイル編)
- typesをCloudflare用に変更
tsconfig.json
"types": [
"@remix-run/cloudflare",
"vite/client",
"@cloudflare/workers-types/2023-07-01"
],
- 開発サーバー起動時にCloudflareランタイムをシュミレートするプラグイン追加
vite.config.ts
+ import { vitePlugin as remix, cloudflareDevProxyVitePlugin } from "@remix-run/dev";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
plugins: [
+ cloudflareDevProxyVitePlugin(),
remix({
future: {
v3_fetcherPersist: true,
v3_relativeSplatPath: true,
v3_throwAbortReason: true,
},
}),
tsconfigPaths(),
],
});
![yuppe](https://res.cloudinary.com/zenn/image/fetch/s--pdj_rsd3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/dcea63de60.jpeg)
Cloudflare Pages用のfunctionを設定する
詳しくは
functions/[[path]].ts
import { createPagesFunctionHandler } from '@remix-run/cloudflare-pages'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - the server build file is generated by `remix vite:build`
// eslint-disable-next-line import/no-unresolved
import * as build from '../build/server'
export const onRequest = createPagesFunctionHandler({ build })
catch-allファイル名ルールを使用することで、全てのリクエストをRemix側に流し、ビルド後に生成されるbuild/serverファイルとPages Functionsの繋ぎ込みを行なっている
![yuppe](https://res.cloudinary.com/zenn/image/fetch/s--pdj_rsd3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/dcea63de60.jpeg)
Remixサーバー側エントリーポイントをCloudflare仕様にする
- entry.server.tsxの編集
app/enter.server.tsx
/**
* By default, Remix will handle generating the HTTP Response for you.
* You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨
* For more information, see https://remix.run/file-conventions/entry.server
*/
import type { AppLoadContext, EntryContext } from "@remix-run/cloudflare"
import { RemixServer } from "@remix-run/react"
import { isbot } from "isbot"
// web標準のWeb Streamを生成する関数
import { renderToReadableStream } from "react-dom/server"
const ABORT_DELAY = 5_000;
export default async function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
// This is ignored so we can keep it in the template for visibility. Feel
// free to delete this parameter in your app if you're not using it!
// eslint-disable-next-line @typescript-eslint/no-unused-vars
loadContext: AppLoadContext
) {
const body = await renderToReadableStream(
<RemixServer context={remixContext} url={request.url} />,
{
signal: request.signal,
onError(error: unknown) {
// Log streaming rendering errors from inside the shell
console.error(error)
responseStatusCode = 500
}
}
)
if (isbot(request.headers.get("user-agent")) || "") {
await body.allReady
}
responseHeaders.set("Content-Type", "text/html")
return new Response(body, {
headers: responseHeaders,
status: responseStatusCode
})
}
- productionサーバー実行コマンドの書き換え
"scripts": {
"build": "remix vite:build",
"dev": "remix vite:dev",
"lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
- "start": "remix-serve ./build/server/index.js",
+ "start": "wrangler pages dev build/client",
"typecheck": "tsc"
},
![yuppe](https://res.cloudinary.com/zenn/image/fetch/s--pdj_rsd3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/dcea63de60.jpeg)
本番設定同様のサーバーへのアクセス
npm run build && npm run start
> build
> remix vite:build
vite v5.3.2 building for production...
✓ 85 modules transformed.
build/client/.vite/manifest.json 1.12 kB │ gzip: 0.32 kB
build/client/assets/root-BFUH26ow.css 5.36 kB │ gzip: 1.61 kB
build/client/assets/_index-B6hwyHK-.js 0.94 kB │ gzip: 0.40 kB
build/client/assets/root-SDu10Ik2.js 1.44 kB │ gzip: 0.84 kB
build/client/assets/entry.client-DFN7WZku.js 4.11 kB │ gzip: 1.56 kB
build/client/assets/jsx-runtime-56DGgGmo.js 8.11 kB │ gzip: 3.05 kB
build/client/assets/components-DxtGWM4Z.js 239.14 kB │ gzip: 77.05 kB
✓ built in 1.18s
vite v5.3.2 building SSR bundle for production...
✓ 6 modules transformed.
build/server/.vite/manifest.json 0.22 kB
build/server/assets/server-build-BFUH26ow.css 5.36 kB
build/server/index.js 5.15 kB
✓ built in 40ms
> start
> wrangler pages dev build/client
⛅️ wrangler 3.62.0
-------------------
✨ Compiled Worker successfully
✔ Would you like to help improve Wrangler by sending usage metrics to Cloudflare? … yes
Your choice has been saved in the following file: ../../../../../Library/Preferences/.wrangler/metrics.json.
You can override the user level setting for a project in `wrangler.toml`:
- to disable sending metrics for a project: `send_metrics = false`
- to enable sending metrics for a project: `send_metrics = true`
[wrangler:inf] Ready on http://localhost:8788
✌️
![yuppe](https://res.cloudinary.com/zenn/image/fetch/s--pdj_rsd3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/dcea63de60.jpeg)
実際にCloudflare Pagesへデプロイしていく
やること
- Cloudflareアカウント作成
- gitignoreに.wranglerフォルダ追加
- GitHubへpush
- Cloudflare Pagesで公開設定