Remix(Remix classic compiler) + cloudflare workers で、wranglerの開発サーバーのホットリロードが動かない

最近Remixはじめました。
結論から言うと、Remix classic compiler版の公式のテンプレートでnpm run devしてもホットリロードききません。
とりあえずプロジェクト作る
npx create-remix@latest --template remix-run/remix/templates/classic-remix-compiler/cloudflare-workers

作成done
remixとwranglerのバージョンはそこそこ新しそう
やってみましょう
❯ cat package.json
{
"name": "remix-classic-compiler-cloudflare-workers",
"private": true,
"sideEffects": false,
"type": "module",
"scripts": {
"build": "remix build",
"deploy": "wrangler deploy",
"dev": "remix dev --manual -c \"npm start\"",
"lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
"start": "wrangler dev ./build/index.js",
"typecheck": "tsc"
},
"dependencies": {
"@cloudflare/kv-asset-handler": "^0.1.3",
"@remix-run/cloudflare": "^2.15.2",
"@remix-run/css-bundle": "^2.15.2",
"@remix-run/react": "^2.15.2",
"isbot": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20230518.0",
"@remix-run/dev": "^2.15.2",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"eslint": "^8.38.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"typescript": "^5.1.6",
"wrangler": "^3.24.0"
},
"engines": {
"node": ">=18.0.0"
}
}%

やっぱり npm run dev
でLiveReloadが反映されない。
ちなみにwrangler.tomlの[build]でnpm run buildを走らせてる。
[build]はデプロイ時とか wrangler devした時にひっかかるアクション
もうなんだか嫌な予感がする
wrangler.toml
name = "remix-cloudflare-workers"
workers_dev = true
main = "./build/index.js"
# https://developers.cloudflare.com/workers/platform/compatibility-dates
compatibility_date = "2023-04-20"
[site]
bucket = "./public"
[build]
command = "npm run build"

devコマンドについて解説
chatgptくんにきいてみた
このセットアップでは、Remixの開発サーバーとCloudflare Workersのローカルサーバー(wrangler dev
)を別々に起動していますが、wrangler dev
を使って実際のリクエスト処理を担当させています。
詳細な流れ
-
remix dev --manual
:- この部分で、Remixが通常の「アプリケーションサーバー」として起動する代わりに、コードのビルドや監視(ホットリロード)に限定されます。
- 実際のリクエスト処理(サーバー部分)は行わず、ビルド済みのファイル(
build/
ディレクトリ)を生成します。
-
-c "npm start"
:- この部分で、Cloudflare Workersをローカルで動作させる
wrangler dev
を起動します。 -
npm start
は次のスクリプトを実行します:つまり、"start": "wrangler dev ./build/index.js"
build/index.js
をCloudflare Workersとして実行します。
- この部分で、Cloudflare Workersをローカルで動作させる
-
役割の分担:
-
Remixの役割: 開発中のコード変更を監視し、ビルドを実行します(
build/
ディレクトリに出力)。 -
Cloudflare Workersの役割:
build/
ディレクトリに出力されたコードを実際のリクエスト処理サーバーとして動作させます。
-
Remixの役割: 開発中のコード変更を監視し、ビルドを実行します(
結論
- この設定では、Remixの開発サーバーは使わず、Cloudflare Workers(
wrangler dev
)をサーバーとして利用しています。 -
remix dev
はコード変更の監視とビルドに専念し、Cloudflare Workersがアプリケーションをホストしています。 - これにより、Cloudflare Workers特有の環境(KV、Durable Objectsなど)を意識した開発とテストが可能になります。
補足
この構成は、Cloudflare Workers向けに最適化されたテンプレート特有の方法です。通常のRemix開発サーバーを使う場合とは異なる点に注意してください。

npm run dev
のログ
remix devがnpm startを実行してwrangler dev ./build/index.jsが走り、そのwrangler devでwrangler.tomlのnpm run buildが走ってる。
それでそのビルドで変更を検知してさらにwrangler.tomlのnpm run buildが走ってるっぽい
The file src changed, restarting build...
Running custom build: npm run build
それでそのビルドも見てまたwrangler.tomlのnpm run buildされてる?無限ループしそうなものだけどなんだかここで止まってサーバー起動する
❯ npm run dev
> dev
> remix dev --manual -c "npm start"
💿 remix dev
warn Fetcher persistence behavior is changing in React Router v7
┃ You can use the `v3_fetcherPersist` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_fetcherPersist
┗
warn Route discovery/manifest behavior is changing in React Router v7
┃ You can use the `v3_lazyRouteDiscovery` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_lazyRouteDiscovery
┗
warn Relative routing behavior for splat routes is changing in React Router v7
┃ You can use the `v3_relativeSplatPath` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_relativeSplatPath
┗
warn Data fetching is changing to a single fetch in React Router v7
┃ You can use the `v3_singleFetch` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_singleFetch
┗
warn The format of errors thrown on aborted requests is changing in React Router v7
┃ You can use the `v3_throwAbortReason` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_throwAbortReason
┗
info building...
info built (778ms)
> start
> wrangler dev ./build/index.js
⛅️ wrangler 3.99.0
-------------------
Running custom build: npm run build
> build
> remix build
info building... (NODE_ENV=development)
warn Fetcher persistence behavior is changing in React Router v7
┃ You can use the `v3_fetcherPersist` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_fetcherPersist
┗
warn Route discovery/manifest behavior is changing in React Router v7
┃ You can use the `v3_lazyRouteDiscovery` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_lazyRouteDiscovery
┗
warn Relative routing behavior for splat routes is changing in React Router v7
┃ You can use the `v3_relativeSplatPath` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_relativeSplatPath
┗
warn Data fetching is changing to a single fetch in React Router v7
┃ You can use the `v3_singleFetch` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_singleFetch
┗
warn The format of errors thrown on aborted requests is changing in React Router v7
┃ You can use the `v3_throwAbortReason` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_throwAbortReason
┗
info built (654ms)
The file src changed, restarting build...
Running custom build: npm run build
[wrangler:inf] Ready on http://localhost:8787
> build
> remix build
info building... (NODE_ENV=development)
warn Fetcher persistence behavior is changing in React Router v7
┃ You can use the `v3_fetcherPersist` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_fetcherPersist
┗
warn Route discovery/manifest behavior is changing in React Router v7
┃ You can use the `v3_lazyRouteDiscovery` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_lazyRouteDiscovery
┗
warn Relative routing behavior for splat routes is changing in React Router v7
┃ You can use the `v3_relativeSplatPath` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_relativeSplatPath
┗
warn Data fetching is changing to a single fetch in React Router v7
┃ You can use the `v3_singleFetch` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_singleFetch
┗
warn The format of errors thrown on aborted requests is changing in React Router v7
┃ You can use the `v3_throwAbortReason` future flag to opt-in early.
┃ -> https://remix.run/docs/en/2.13.1/start/future-flags#v3_throwAbortReason
┗
info built (683ms)
⎔ Starting local server...
[REMIX DEV] ff8ceddf ready
[wrangler:inf] GET / 200 OK (56ms)
[wrangler:inf] GET /build/manifest-FF8CEDDF.js 200 OK (27ms)
[wrangler:inf] GET /build/routes/_index-4RWXJ64J.js 200 OK (29ms)
[wrangler:inf] GET /favicon.ico 200 OK (6ms)

ソースを変更した時のログ
wrangler側のログがなにも出てないので、Remix側が再ビルドしてもwrangler側が変更を検知できていないように見える。
よってwranglerのホットリロードが動作せず、再度ブラウザをリロードしようが、ソース変更分は反映されない。
info rebuilding... (~ app/routes/_index.tsx)
info building...
info rebuilt (313ms)

ShopifyのRemixいじってる方から諦めなさい的なコメント
かなしい

結論
Remix classic compiler + cloudflare workersは、現在のバージョンではホットリロードききません。
変更を反映させるためには、devコマンドもう一回叩いてサーバー立ち上げ直してください。
Remix Viteでは、cloudflareDevProxyVitePlugin
っていうworked環境をremixの開発サーバー(Node環境)上でよしなしに解決してくれるプラグインがあります。
これによってViteの爆速HMRで擬似的なworker環境で開発ができるので、cloudflare workers上でRemixアプリを作る場合はVite版のRemixを使うようにしましょう。
おしまい

imo
最近Remix触り始めたのでわからないけど、コメント見る感じ昔は動いてたっぽい感じがする。
wranglerなりremixなりのバージョンアップで動かなくなっちゃったんだろう、今後サポートも期待できないのでここでハマったら素直に公式が強くサポートしてるVite移行が吉