Closed26

Remix アプリを Cloudflare にデプロイする

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

このスクラップについて

このスクラップでは Remix アプリを Cloudflare Pages と Workers にデプロイする手順をまとめる。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

プロジェクトの作成方法

色々とある。

https://developers.cloudflare.com/pages/framework-guides/deploy-a-remix-site/

コマンド
npm create cloudflare@latest -- my-remix-app --framework=remix

https://developers.cloudflare.com/workers/frameworks/framework-guides/remix/

コマンド
npm create cloudflare@latest my-remix-app -- --framework=remix --experimental

https://remix.run/docs/en/main/guides/vite#cloudflare

コマンド
npx create-remix@latest --template remix-run/remix/templates/cloudflare

https://remix.run/docs/en/main/guides/vite#getting-started

コマンド
npx create-remix@latest --template remix-run/remix/templates/cloudflare-workers
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Remix 版も試してみる

コマンド
npx create-remix@latest --template remix-run/remix/templates/cloudflare-workers my-create-remix-workers
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

違いは何だろう?

コマンド
diff -r \
  --exclude='.wrangler' \
  --exclude='build' \
  --exclude='node_modules' \
  --exclude='.git' my-remix-app my-create-remix-workers
差分
diff -r --exclude=.wrangler --exclude=build --exclude=node_modules --exclude=.git my-remix-app/.gitignore my-create-remix-workers/.gitignore
7,8d6
< 
< .wrangler
diff -r --exclude=.wrangler --exclude=build --exclude=node_modules --exclude=.git my-remix-app/package-lock.json my-create-remix-workers/package-lock.json
2c2
<   "name": "my-remix-app",
---
>   "name": "my-create-remix-workers",
7c7
<       "name": "my-remix-app",
---
>       "name": "my-create-remix-workers",
17c17
<         "@cloudflare/workers-types": "^4.20250121.0",
---
>         "@cloudflare/workers-types": "^4.20241022.0",
35c35
<         "wrangler": "^3.105.0"
---
>         "wrangler": "3.84.0"
525,527c525,527
<       "version": "1.20241230.0",
<       "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20241230.0.tgz",
<       "integrity": "sha512-BZHLg4bbhNQoaY1Uan81O3FV/zcmWueC55juhnaI7NAobiQth9RppadPNpxNAmS9fK2mR5z8xrwMQSQrHmztyQ==",
---
>       "version": "1.20241022.0",
>       "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20241022.0.tgz",
>       "integrity": "sha512-1NNYun37myMTgCUiPQEJ0cMal4mKZVTpkD0b2tx9hV70xji+frVJcSK8YVLeUm1P+Rw1d/ct8DMgQuCpsz3Fsw==",
541,543c541,543
<       "version": "1.20241230.0",
<       "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20241230.0.tgz",
<       "integrity": "sha512-lllxycj7EzYoJ0VOJh8M3palUgoonVrILnzGrgsworgWlIpgjfXGS7b41tEGCw6AxSxL9prmTIGtfSPUvn/rjg==",
---
>       "version": "1.20241022.0",
>       "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20241022.0.tgz",
>       "integrity": "sha512-FOO/0P0U82EsTLTdweNVgw+4VOk5nghExLPLSppdOziq6IR5HVgP44Kmq5LdsUeHUhwUmfOh9hzaTpkNzUqKvw==",
557,559c557,559
<       "version": "1.20241230.0",
<       "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20241230.0.tgz",
<       "integrity": "sha512-Y3mHcW0KghOmWdNZyHYpEOG4Ba/ga8tht5vj1a+WXfagEjMO8Y98XhZUlCaYa9yB7Wh5jVcK5LM2jlO/BLgqpA==",
---
>       "version": "1.20241022.0",
>       "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20241022.0.tgz",
>       "integrity": "sha512-RsNc19BQJG9yd+ngnjuDeG9ywZG+7t1L4JeglgceyY5ViMNMKVO7Zpbsu69kXslU9h6xyQG+lrmclg3cBpnhYA==",
573,575c573,575
<       "version": "1.20241230.0",
<       "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20241230.0.tgz",
<       "integrity": "sha512-IAjhsWPlHzhhkJ6I49sDG6XfMnhPvv0szKGXxTWQK/IWMrbGdHm4RSfNKBSoLQm67jGMIzbmcrX9UIkms27Y1g==",
---
>       "version": "1.20241022.0",
>       "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20241022.0.tgz",
>       "integrity": "sha512-x5mUXpKxfsosxcFmcq5DaqLs37PejHYVRsNz1cWI59ma7aC4y4Qn6Tf3i0r9MwQTF/MccP4SjVslMU6m4W7IaA==",
589,591c589,591
<       "version": "1.20241230.0",
<       "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20241230.0.tgz",
<       "integrity": "sha512-y5SPIk9iOb2gz+yWtHxoeMnjPnkYQswiCJ480oHC6zexnJLlKTpcmBCjDH1nWCT4pQi8F25gaH8thgElf4NvXQ==",
---
>       "version": "1.20241022.0",
>       "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20241022.0.tgz",
>       "integrity": "sha512-eBCClx4szCOgKqOlxxbdNszMqQf3MRG1B9BRIqEM/diDfdR9IrZ8l3FaEm+l9gXgPmS6m1NBn40aWuGBl8UTSw==",
603a604,628
>     "node_modules/@cloudflare/workers-shared": {
>       "version": "0.7.0",
>       "resolved": "https://registry.npmjs.org/@cloudflare/workers-shared/-/workers-shared-0.7.0.tgz",
>       "integrity": "sha512-LLQRTqx7lKC7o2eCYMpyc5FXV8d0pUX6r3A+agzhqS9aoR5A6zCPefwQGcvbKx83ozX22ATZcemwxQXn12UofQ==",
>       "dev": true,
>       "dependencies": {
>         "mime": "^3.0.0",
>         "zod": "^3.22.3"
>       },
>       "engines": {
>         "node": ">=16.7.0"
>       }
>     },
>     "node_modules/@cloudflare/workers-shared/node_modules/mime": {
>       "version": "3.0.0",
>       "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
>       "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
>       "dev": true,
>       "bin": {
>         "mime": "cli.js"
>       },
>       "engines": {
>         "node": ">=10.0.0"
>       }
>     },
2032a2058,2066
>     "node_modules/@types/node-forge": {
>       "version": "1.3.11",
>       "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz",
>       "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==",
>       "dev": true,
>       "dependencies": {
>         "@types/node": "*"
>       }
>     },
3478a3513,3522
>     "node_modules/date-fns": {
>       "version": "4.1.0",
>       "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
>       "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
>       "dev": true,
>       "funding": {
>         "type": "github",
>         "url": "https://github.com/sponsors/kossnocorp"
>       }
>     },
6290a6335,6340
>     "node_modules/itty-time": {
>       "version": "1.0.6",
>       "resolved": "https://registry.npmjs.org/itty-time/-/itty-time-1.0.6.tgz",
>       "integrity": "sha512-+P8IZaLLBtFv8hCkIjcymZOp4UJ+xW6bSlQsXGqrkmJh7vSiMFSlNne0mCYagEE0N7HDNR5jJBRxwN0oYv61Rw==",
>       "dev": true
>     },
7534,7536c7584,7586
<       "version": "3.20241230.2",
<       "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20241230.2.tgz",
<       "integrity": "sha512-gFC3IaUKrLGdtA6y6PLpC/QE5YAjB5ITCfBZHkosRyFZ9ApaCHKcHRvrEFMc/R19QxxtHD+G3tExEHp7MmtsYQ==",
---
>       "version": "3.20241022.0",
>       "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20241022.0.tgz",
>       "integrity": "sha512-x9Fbq1Hmz1f0osIT9Qmj78iX4UpCP2EqlZnA/tzj/3+I49vc3Kq0fNqSSKplcdf6HlCHdL3fOBicmreQF4BUUQ==",
7547,7548c7597,7598
<         "workerd": "1.20241230.0",
<         "ws": "^8.18.0",
---
>         "workerd": "1.20241022.0",
>         "ws": "^8.17.1",
7858a7909,7917
>     "node_modules/node-forge": {
>       "version": "1.3.1",
>       "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
>       "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
>       "dev": true,
>       "engines": {
>         "node": ">= 6.13.0"
>       }
>     },
9493a9553,9565
>     "node_modules/selfsigned": {
>       "version": "2.4.1",
>       "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz",
>       "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==",
>       "dev": true,
>       "dependencies": {
>         "@types/node-forge": "^1.3.0",
>         "node-forge": "^1"
>       },
>       "engines": {
>         "node": ">=10"
>       }
>     },
10719,10721c10791,10794
<       "version": "2.0.0-rc.0",
<       "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.0.tgz",
<       "integrity": "sha512-H0kl2w8jFL/FAk0xvjVing4bS3jd//mbg1QChDnn58l9Sc5RtduaKmLAL8n+eBw5jJo8ZjYV7CrEGage5LAOZQ==",
---
>       "name": "unenv-nightly",
>       "version": "2.0.0-20241024-111401-d4156ac",
>       "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-20241024-111401-d4156ac.tgz",
>       "integrity": "sha512-xJO1hfY+Te+/XnfCYrCbFbRcgu6XEODND1s5wnVbaBCkuQX7JXF7fHEXPrukFE2j8EOH848P8QN19VO47XN8hw==",
10725d10797
<         "mlly": "^1.7.4",
11707,11709c11779,11781
<       "version": "1.20241230.0",
<       "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20241230.0.tgz",
<       "integrity": "sha512-EgixXP0JGXGq6J9lz17TKIZtfNDUvJNG+cl9paPMfZuYWT920fFpBx+K04YmnbQRLnglsivF1GT9pxh1yrlWhg==",
---
>       "version": "1.20241022.0",
>       "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20241022.0.tgz",
>       "integrity": "sha512-jyGXsgO9DRcJyx6Ovv7gUyDPc3UYC2i/E0p9GFUg6GUzpldw4Y93y9kOmdfsOnKZ3+lY53veSiUniiBPE6Q2NQ==",
11719,11723c11791,11795
<         "@cloudflare/workerd-darwin-64": "1.20241230.0",
<         "@cloudflare/workerd-darwin-arm64": "1.20241230.0",
<         "@cloudflare/workerd-linux-64": "1.20241230.0",
<         "@cloudflare/workerd-linux-arm64": "1.20241230.0",
<         "@cloudflare/workerd-windows-64": "1.20241230.0"
---
>         "@cloudflare/workerd-darwin-64": "1.20241022.0",
>         "@cloudflare/workerd-darwin-arm64": "1.20241022.0",
>         "@cloudflare/workerd-linux-64": "1.20241022.0",
>         "@cloudflare/workerd-linux-arm64": "1.20241022.0",
>         "@cloudflare/workerd-windows-64": "1.20241022.0"
11727,11729c11799,11801
<       "version": "3.105.0",
<       "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.105.0.tgz",
<       "integrity": "sha512-NX10iuUXtgiVRG9YJ7dwwEUuhQ38hu4stcxMWq4dbKCnfcOj7fLFh+HwaWudqOr1jDCPrnSOQVkgfAfG3ZH9Lw==",
---
>       "version": "3.84.0",
>       "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.84.0.tgz",
>       "integrity": "sha512-EA8oh7YQmZ3kD+a5MId9reHKGgXpodmsPWMLriE5gT5YmG9is66n0AA2tyLzQZKZXmgbo6JyGxvCDPcLeb/X0w==",
11733,11735c11805,11810
<         "@esbuild-plugins/node-globals-polyfill": "0.2.3",
<         "@esbuild-plugins/node-modules-polyfill": "0.2.2",
<         "blake3-wasm": "2.1.5",
---
>         "@cloudflare/workers-shared": "0.7.0",
>         "@esbuild-plugins/node-globals-polyfill": "^0.2.3",
>         "@esbuild-plugins/node-modules-polyfill": "^0.2.2",
>         "blake3-wasm": "^2.1.5",
>         "chokidar": "^3.5.3",
>         "date-fns": "^4.1.0",
11737,11740c11812,11822
<         "miniflare": "3.20241230.2",
<         "path-to-regexp": "6.3.0",
<         "unenv": "2.0.0-rc.0",
<         "workerd": "1.20241230.0"
---
>         "itty-time": "^1.0.6",
>         "miniflare": "3.20241022.0",
>         "nanoid": "^3.3.3",
>         "path-to-regexp": "^6.3.0",
>         "resolve": "^1.22.8",
>         "resolve.exports": "^2.0.2",
>         "selfsigned": "^2.0.1",
>         "source-map": "^0.6.1",
>         "unenv": "npm:unenv-nightly@2.0.0-20241024-111401-d4156ac",
>         "workerd": "1.20241022.0",
>         "xxhash-wasm": "^1.0.1"
11753c11835
<         "@cloudflare/workers-types": "^4.20241230.0"
---
>         "@cloudflare/workers-types": "^4.20241022.0"
12179a12262,12270
>     "node_modules/wrangler/node_modules/source-map": {
>       "version": "0.6.1",
>       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
>       "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
>       "dev": true,
>       "engines": {
>         "node": ">=0.10.0"
>       }
>     },
12308a12400,12405
>     },
>     "node_modules/xxhash-wasm": {
>       "version": "1.1.0",
>       "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz",
>       "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==",
>       "dev": true
diff -r --exclude=.wrangler --exclude=build --exclude=node_modules --exclude=.git my-remix-app/package.json my-create-remix-workers/package.json
2c2
<   "name": "my-remix-app",
---
>   "name": "my-create-remix-workers",
8c8
<     "deploy": "npm run build && wrangler deploy",
---
>     "deploy": "wrangler deploy",
13,15c13
<     "typegen": "wrangler types",
<     "preview": "npm run build && wrangler dev",
<     "cf-typegen": "wrangler types"
---
>     "typegen": "wrangler types"
26c24
<     "@cloudflare/workers-types": "^4.20250121.0",
---
>     "@cloudflare/workers-types": "^4.20241022.0",
44c42
<     "wrangler": "^3.105.0"
---
>     "wrangler": "3.84.0"
Only in my-remix-app/public: .assetsignore
diff -r --exclude=.wrangler --exclude=build --exclude=node_modules --exclude=.git my-remix-app/tsconfig.json my-create-remix-workers/tsconfig.json
15,17c15,17
<         "@remix-run/cloudflare",
<         "vite/client",
<         "@cloudflare/workers-types/2023-07-01"
---
>       "@remix-run/cloudflare",
>       "@cloudflare/workers-types",
>       "vite/client"
diff -r --exclude=.wrangler --exclude=build --exclude=node_modules --exclude=.git my-remix-app/worker-configuration.d.ts my-create-remix-workers/worker-configuration.d.ts
1,4c1,3
< // Generated by Wrangler
< // After adding bindings to `wrangler.toml`, regenerate this interface via `npm run cf-typegen`
< interface Env {
< }
---
> // Generated by Wrangler by running `wrangler types`
> 
> interface Env {}
diff -r --exclude=.wrangler --exclude=build --exclude=node_modules --exclude=.git my-remix-app/wrangler.toml my-create-remix-workers/wrangler.toml
2,5c2,3
< # For more details on how to configure Wrangler, refer to:
< # https://developers.cloudflare.com/workers/wrangler/configuration/
< name = "my-remix-app"
< compatibility_date = "2025-01-21"
---
> name = "remix-cloudflare-workers-template"
> 
6a5,7
> workers_dev = true
> # https://developers.cloudflare.com/workers/platform/compatibility-dates
> compatibility_date = "2024-09-26"
8a10
> # https://developers.cloudflare.com/workers/static-assets/binding/
11,44c13,14
< [observability]
< enabled = true
< 
< # Smart Placement
< # Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement
< # [placement]
< # mode = "smart"
< 
< ###
< # Bindings
< # Bindings allow your Worker to interact with resources on the Cloudflare Developer Platform, including
< # databases, object storage, AI inference, real-time communication and more.
< # https://developers.cloudflare.com/workers/runtime-apis/bindings/
< ###
< 
< # Environment Variables
< # https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables
< # [vars]
< # MY_VARIABLE = "production_value"
< 
< # Note: Use secrets to store sensitive data.
< # https://developers.cloudflare.com/workers/configuration/secrets/
< 
< # Static Assets
< # https://developers.cloudflare.com/workers/static-assets/binding/
< # [assets]
< # directory = "./public/"
< # binding = "ASSETS"
< 
< # Service Bindings (communicate between multiple Workers)
< # https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings
< # [[services]]
< # binding = "MY_SERVICE"
< # service = "my-service"
---
> [build]
> command = "npm run build"
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Git でも差分確認

コマンド
cd my-remix-app
git diff HEAD~1
差分
diff --git a/.gitignore b/.gitignore
index bc83be3..38d1587 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,5 @@ node_modules
 /build
 .env
 .dev.vars
+
+.wrangler
diff --git a/package-lock.json b/package-lock.json
index d980b66..872cae8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,7 +14,7 @@
         "react-dom": "^18.2.0"
       },
       "devDependencies": {
-        "@cloudflare/workers-types": "^4.20241022.0",
+        "@cloudflare/workers-types": "^4.20250121.0",
         "@remix-run/dev": "^2.15.2",
         "@types/react": "^18.2.20",
         "@types/react-dom": "^18.2.7",
@@ -32,7 +32,7 @@
         "typescript": "^5.1.6",
         "vite": "^5.1.0",
         "vite-tsconfig-paths": "^4.2.1",
-        "wrangler": "3.84.0"
+        "wrangler": "^3.105.0"
       },
       "engines": {
         "node": ">=20.0.0"
@@ -522,9 +522,9 @@
       }
     },
     "node_modules/@cloudflare/workerd-darwin-64": {
-      "version": "1.20241022.0",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20241022.0.tgz",
-      "integrity": "sha512-1NNYun37myMTgCUiPQEJ0cMal4mKZVTpkD0b2tx9hV70xji+frVJcSK8YVLeUm1P+Rw1d/ct8DMgQuCpsz3Fsw==",
+      "version": "1.20241230.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20241230.0.tgz",
+      "integrity": "sha512-BZHLg4bbhNQoaY1Uan81O3FV/zcmWueC55juhnaI7NAobiQth9RppadPNpxNAmS9fK2mR5z8xrwMQSQrHmztyQ==",
       "cpu": [
         "x64"
       ],
@@ -538,9 +538,9 @@
       }
     },
     "node_modules/@cloudflare/workerd-darwin-arm64": {
-      "version": "1.20241022.0",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20241022.0.tgz",
-      "integrity": "sha512-FOO/0P0U82EsTLTdweNVgw+4VOk5nghExLPLSppdOziq6IR5HVgP44Kmq5LdsUeHUhwUmfOh9hzaTpkNzUqKvw==",
+      "version": "1.20241230.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20241230.0.tgz",
+      "integrity": "sha512-lllxycj7EzYoJ0VOJh8M3palUgoonVrILnzGrgsworgWlIpgjfXGS7b41tEGCw6AxSxL9prmTIGtfSPUvn/rjg==",
       "cpu": [
         "arm64"
       ],
@@ -554,9 +554,9 @@
       }
     },
     "node_modules/@cloudflare/workerd-linux-64": {
-      "version": "1.20241022.0",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20241022.0.tgz",
-      "integrity": "sha512-RsNc19BQJG9yd+ngnjuDeG9ywZG+7t1L4JeglgceyY5ViMNMKVO7Zpbsu69kXslU9h6xyQG+lrmclg3cBpnhYA==",
+      "version": "1.20241230.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20241230.0.tgz",
+      "integrity": "sha512-Y3mHcW0KghOmWdNZyHYpEOG4Ba/ga8tht5vj1a+WXfagEjMO8Y98XhZUlCaYa9yB7Wh5jVcK5LM2jlO/BLgqpA==",
       "cpu": [
         "x64"
       ],
@@ -570,9 +570,9 @@
       }
     },
     "node_modules/@cloudflare/workerd-linux-arm64": {
-      "version": "1.20241022.0",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20241022.0.tgz",
-      "integrity": "sha512-x5mUXpKxfsosxcFmcq5DaqLs37PejHYVRsNz1cWI59ma7aC4y4Qn6Tf3i0r9MwQTF/MccP4SjVslMU6m4W7IaA==",
+      "version": "1.20241230.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20241230.0.tgz",
+      "integrity": "sha512-IAjhsWPlHzhhkJ6I49sDG6XfMnhPvv0szKGXxTWQK/IWMrbGdHm4RSfNKBSoLQm67jGMIzbmcrX9UIkms27Y1g==",
       "cpu": [
         "arm64"
       ],
@@ -586,9 +586,9 @@
       }
     },
     "node_modules/@cloudflare/workerd-windows-64": {
-      "version": "1.20241022.0",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20241022.0.tgz",
-      "integrity": "sha512-eBCClx4szCOgKqOlxxbdNszMqQf3MRG1B9BRIqEM/diDfdR9IrZ8l3FaEm+l9gXgPmS6m1NBn40aWuGBl8UTSw==",
+      "version": "1.20241230.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20241230.0.tgz",
+      "integrity": "sha512-y5SPIk9iOb2gz+yWtHxoeMnjPnkYQswiCJ480oHC6zexnJLlKTpcmBCjDH1nWCT4pQi8F25gaH8thgElf4NvXQ==",
       "cpu": [
         "x64"
       ],
@@ -601,31 +601,6 @@
         "node": ">=16"
       }
     },
-    "node_modules/@cloudflare/workers-shared": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workers-shared/-/workers-shared-0.7.0.tgz",
-      "integrity": "sha512-LLQRTqx7lKC7o2eCYMpyc5FXV8d0pUX6r3A+agzhqS9aoR5A6zCPefwQGcvbKx83ozX22ATZcemwxQXn12UofQ==",
-      "dev": true,
-      "dependencies": {
-        "mime": "^3.0.0",
-        "zod": "^3.22.3"
-      },
-      "engines": {
-        "node": ">=16.7.0"
-      }
-    },
-    "node_modules/@cloudflare/workers-shared/node_modules/mime": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
-      "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
-      "dev": true,
-      "bin": {
-        "mime": "cli.js"
-      },
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
     "node_modules/@cloudflare/workers-types": {
       "version": "4.20250121.0",
       "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20250121.0.tgz",
@@ -2055,15 +2030,6 @@
         "undici-types": "~6.20.0"
       }
     },
-    "node_modules/@types/node-forge": {
-      "version": "1.3.11",
-      "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz",
-      "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
     "node_modules/@types/prop-types": {
       "version": "15.7.14",
       "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
@@ -3510,16 +3476,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/date-fns": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
-      "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
-      "dev": true,
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/kossnocorp"
-      }
-    },
     "node_modules/debug": {
       "version": "4.4.0",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
@@ -6332,12 +6288,6 @@
         "node": ">= 0.4"
       }
     },
-    "node_modules/itty-time": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/itty-time/-/itty-time-1.0.6.tgz",
-      "integrity": "sha512-+P8IZaLLBtFv8hCkIjcymZOp4UJ+xW6bSlQsXGqrkmJh7vSiMFSlNne0mCYagEE0N7HDNR5jJBRxwN0oYv61Rw==",
-      "dev": true
-    },
     "node_modules/jackspeak": {
       "version": "3.4.3",
       "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
@@ -7581,9 +7531,9 @@
       }
     },
     "node_modules/miniflare": {
-      "version": "3.20241022.0",
-      "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20241022.0.tgz",
-      "integrity": "sha512-x9Fbq1Hmz1f0osIT9Qmj78iX4UpCP2EqlZnA/tzj/3+I49vc3Kq0fNqSSKplcdf6HlCHdL3fOBicmreQF4BUUQ==",
+      "version": "3.20241230.2",
+      "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20241230.2.tgz",
+      "integrity": "sha512-gFC3IaUKrLGdtA6y6PLpC/QE5YAjB5ITCfBZHkosRyFZ9ApaCHKcHRvrEFMc/R19QxxtHD+G3tExEHp7MmtsYQ==",
       "dev": true,
       "dependencies": {
         "@cspotcode/source-map-support": "0.8.1",
@@ -7594,8 +7544,8 @@
         "glob-to-regexp": "^0.4.1",
         "stoppable": "^1.1.0",
         "undici": "^5.28.4",
-        "workerd": "1.20241022.0",
-        "ws": "^8.17.1",
+        "workerd": "1.20241230.0",
+        "ws": "^8.18.0",
         "youch": "^3.2.2",
         "zod": "^3.22.3"
       },
@@ -7906,15 +7856,6 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/node-forge": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
-      "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 6.13.0"
-      }
-    },
     "node_modules/node-releases": {
       "version": "2.0.19",
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
@@ -9550,19 +9491,6 @@
         "loose-envify": "^1.1.0"
       }
     },
-    "node_modules/selfsigned": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz",
-      "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==",
-      "dev": true,
-      "dependencies": {
-        "@types/node-forge": "^1.3.0",
-        "node-forge": "^1"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/semver": {
       "version": "7.6.3",
       "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
@@ -10788,13 +10716,13 @@
       "dev": true
     },
     "node_modules/unenv": {
-      "name": "unenv-nightly",
-      "version": "2.0.0-20241024-111401-d4156ac",
-      "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-20241024-111401-d4156ac.tgz",
-      "integrity": "sha512-xJO1hfY+Te+/XnfCYrCbFbRcgu6XEODND1s5wnVbaBCkuQX7JXF7fHEXPrukFE2j8EOH848P8QN19VO47XN8hw==",
+      "version": "2.0.0-rc.0",
+      "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.0.tgz",
+      "integrity": "sha512-H0kl2w8jFL/FAk0xvjVing4bS3jd//mbg1QChDnn58l9Sc5RtduaKmLAL8n+eBw5jJo8ZjYV7CrEGage5LAOZQ==",
       "dev": true,
       "dependencies": {
         "defu": "^6.1.4",
+        "mlly": "^1.7.4",
         "ohash": "^1.1.4",
         "pathe": "^1.1.2",
         "ufo": "^1.5.4"
@@ -11776,9 +11704,9 @@
       }
     },
     "node_modules/workerd": {
-      "version": "1.20241022.0",
-      "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20241022.0.tgz",
-      "integrity": "sha512-jyGXsgO9DRcJyx6Ovv7gUyDPc3UYC2i/E0p9GFUg6GUzpldw4Y93y9kOmdfsOnKZ3+lY53veSiUniiBPE6Q2NQ==",
+      "version": "1.20241230.0",
+      "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20241230.0.tgz",
+      "integrity": "sha512-EgixXP0JGXGq6J9lz17TKIZtfNDUvJNG+cl9paPMfZuYWT920fFpBx+K04YmnbQRLnglsivF1GT9pxh1yrlWhg==",
       "dev": true,
       "hasInstallScript": true,
       "bin": {
@@ -11788,38 +11716,28 @@
         "node": ">=16"
       },
       "optionalDependencies": {
-        "@cloudflare/workerd-darwin-64": "1.20241022.0",
-        "@cloudflare/workerd-darwin-arm64": "1.20241022.0",
-        "@cloudflare/workerd-linux-64": "1.20241022.0",
-        "@cloudflare/workerd-linux-arm64": "1.20241022.0",
-        "@cloudflare/workerd-windows-64": "1.20241022.0"
+        "@cloudflare/workerd-darwin-64": "1.20241230.0",
+        "@cloudflare/workerd-darwin-arm64": "1.20241230.0",
+        "@cloudflare/workerd-linux-64": "1.20241230.0",
+        "@cloudflare/workerd-linux-arm64": "1.20241230.0",
+        "@cloudflare/workerd-windows-64": "1.20241230.0"
       }
     },
     "node_modules/wrangler": {
-      "version": "3.84.0",
-      "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.84.0.tgz",
-      "integrity": "sha512-EA8oh7YQmZ3kD+a5MId9reHKGgXpodmsPWMLriE5gT5YmG9is66n0AA2tyLzQZKZXmgbo6JyGxvCDPcLeb/X0w==",
+      "version": "3.105.0",
+      "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.105.0.tgz",
+      "integrity": "sha512-NX10iuUXtgiVRG9YJ7dwwEUuhQ38hu4stcxMWq4dbKCnfcOj7fLFh+HwaWudqOr1jDCPrnSOQVkgfAfG3ZH9Lw==",
       "dev": true,
       "dependencies": {
         "@cloudflare/kv-asset-handler": "0.3.4",
-        "@cloudflare/workers-shared": "0.7.0",
-        "@esbuild-plugins/node-globals-polyfill": "^0.2.3",
-        "@esbuild-plugins/node-modules-polyfill": "^0.2.2",
-        "blake3-wasm": "^2.1.5",
-        "chokidar": "^3.5.3",
-        "date-fns": "^4.1.0",
+        "@esbuild-plugins/node-globals-polyfill": "0.2.3",
+        "@esbuild-plugins/node-modules-polyfill": "0.2.2",
+        "blake3-wasm": "2.1.5",
         "esbuild": "0.17.19",
-        "itty-time": "^1.0.6",
-        "miniflare": "3.20241022.0",
-        "nanoid": "^3.3.3",
-        "path-to-regexp": "^6.3.0",
-        "resolve": "^1.22.8",
-        "resolve.exports": "^2.0.2",
-        "selfsigned": "^2.0.1",
-        "source-map": "^0.6.1",
-        "unenv": "npm:unenv-nightly@2.0.0-20241024-111401-d4156ac",
-        "workerd": "1.20241022.0",
-        "xxhash-wasm": "^1.0.1"
+        "miniflare": "3.20241230.2",
+        "path-to-regexp": "6.3.0",
+        "unenv": "2.0.0-rc.0",
+        "workerd": "1.20241230.0"
       },
       "bin": {
         "wrangler": "bin/wrangler.js",
@@ -11832,7 +11750,7 @@
         "fsevents": "~2.3.2"
       },
       "peerDependencies": {
-        "@cloudflare/workers-types": "^4.20241022.0"
+        "@cloudflare/workers-types": "^4.20241230.0"
       },
       "peerDependenciesMeta": {
         "@cloudflare/workers-types": {
@@ -12259,15 +12177,6 @@
       "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==",
       "dev": true
     },
-    "node_modules/wrangler/node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/wrap-ansi": {
       "version": "8.1.0",
       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
@@ -12398,12 +12307,6 @@
         "node": ">=0.4"
       }
     },
-    "node_modules/xxhash-wasm": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz",
-      "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==",
-      "dev": true
-    },
     "node_modules/yallist": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
diff --git a/package.json b/package.json
index 8250f61..a1d2a11 100644
--- a/package.json
+++ b/package.json
@@ -5,12 +5,14 @@
   "type": "module",
   "scripts": {
     "build": "remix vite:build",
-    "deploy": "wrangler deploy",
+    "deploy": "npm run build && wrangler deploy",
     "dev": "remix vite:dev",
     "lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
     "start": "wrangler dev",
     "typecheck": "tsc",
-    "typegen": "wrangler types"
+    "typegen": "wrangler types",
+    "preview": "npm run build && wrangler dev",
+    "cf-typegen": "wrangler types"
   },
   "dependencies": {
     "@remix-run/cloudflare": "^2.15.2",
@@ -21,7 +23,7 @@
     "react-dom": "^18.2.0"
   },
   "devDependencies": {
-    "@cloudflare/workers-types": "^4.20241022.0",
+    "@cloudflare/workers-types": "^4.20250121.0",
     "@remix-run/dev": "^2.15.2",
     "@types/react": "^18.2.20",
     "@types/react-dom": "^18.2.7",
@@ -39,7 +41,7 @@
     "typescript": "^5.1.6",
     "vite": "^5.1.0",
     "vite-tsconfig-paths": "^4.2.1",
-    "wrangler": "3.84.0"
+    "wrangler": "^3.105.0"
   },
   "engines": {
     "node": ">=20.0.0"
diff --git a/public/.assetsignore b/public/.assetsignore
new file mode 100644
index 0000000..e69de29
diff --git a/tsconfig.json b/tsconfig.json
index 964fa4b..888e2b5 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -12,9 +12,9 @@
   "compilerOptions": {
     "lib": ["DOM", "DOM.Iterable", "ES2022"],
     "types": [
-      "@remix-run/cloudflare",
-      "@cloudflare/workers-types",
-      "vite/client"
+        "@remix-run/cloudflare",
+        "vite/client",
+        "@cloudflare/workers-types/2023-07-01"
     ],
     "isolatedModules": true,
     "esModuleInterop": true,
diff --git a/worker-configuration.d.ts b/worker-configuration.d.ts
index 2a6ba0c..5b2319b 100644
--- a/worker-configuration.d.ts
+++ b/worker-configuration.d.ts
@@ -1,3 +1,4 @@
-// Generated by Wrangler by running `wrangler types`
-
-interface Env {}
+// Generated by Wrangler
+// After adding bindings to `wrangler.toml`, regenerate this interface via `npm run cf-typegen`
+interface Env {
+}
diff --git a/wrangler.toml b/wrangler.toml
index ec0feea..2ed903f 100644
--- a/wrangler.toml
+++ b/wrangler.toml
@@ -1,14 +1,44 @@
 #:schema node_modules/wrangler/config-schema.json
-name = "remix-cloudflare-workers-template"
-
+# For more details on how to configure Wrangler, refer to:
+# https://developers.cloudflare.com/workers/wrangler/configuration/
+name = "my-remix-app"
+compatibility_date = "2025-01-21"
 main = "./server.ts"
-workers_dev = true
-# https://developers.cloudflare.com/workers/platform/compatibility-dates
-compatibility_date = "2024-09-26"
 
 [assets]
-# https://developers.cloudflare.com/workers/static-assets/binding/
 directory = "./build/client"
 
-[build]
-command = "npm run build"
+[observability]
+enabled = true
+
+# Smart Placement
+# Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement
+# [placement]
+# mode = "smart"
+
+###
+# Bindings
+# Bindings allow your Worker to interact with resources on the Cloudflare Developer Platform, including
+# databases, object storage, AI inference, real-time communication and more.
+# https://developers.cloudflare.com/workers/runtime-apis/bindings/
+###
+
+# Environment Variables
+# https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables
+# [vars]
+# MY_VARIABLE = "production_value"
+
+# Note: Use secrets to store sensitive data.
+# https://developers.cloudflare.com/workers/configuration/secrets/
+
+# Static Assets
+# https://developers.cloudflare.com/workers/static-assets/binding/
+# [assets]
+# directory = "./public/"
+# binding = "ASSETS"
+
+# Service Bindings (communicate between multiple Workers)
+# https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings
+# [[services]]
+# binding = "MY_SERVICE"
+# service = "my-service"
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Git の diff 確認

コマンド
cd my-create-cloudflare
git diff HEAD~1
差分
diff --git a/load-context.ts b/load-context.ts
index 2777ca1..94ca2e1 100644
--- a/load-context.ts
+++ b/load-context.ts
@@ -1,17 +1,9 @@
 import { type PlatformProxy } from "wrangler";
 
-// When using `wrangler.toml` to configure bindings,
-// `wrangler types` will generate types for those bindings
-// into the global `Env` interface.
-// Need this empty interface so that typechecking passes
-// even if no `wrangler.toml` exists.
-// eslint-disable-next-line @typescript-eslint/no-empty-interface
-interface Env {}
-
 type Cloudflare = Omit<PlatformProxy<Env>, "dispose">;
 
 declare module "@remix-run/cloudflare" {
   interface AppLoadContext {
     cloudflare: Cloudflare;
   }
-}
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 50b0c4b..a83aff3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,7 +14,7 @@
         "react-dom": "^18.2.0"
       },
       "devDependencies": {
-        "@cloudflare/workers-types": "^4.20240512.0",
+        "@cloudflare/workers-types": "^4.20250121.0",
         "@remix-run/dev": "^2.15.2",
         "@types/react": "^18.2.20",
         "@types/react-dom": "^18.2.7",
@@ -32,7 +32,7 @@
         "typescript": "^5.1.6",
         "vite": "^5.1.0",
         "vite-tsconfig-paths": "^4.2.1",
-        "wrangler": "3.57.1"
+        "wrangler": "^3.105.0"
       },
       "engines": {
         "node": ">=20.0.0"
@@ -522,9 +522,9 @@
       }
     },
     "node_modules/@cloudflare/workerd-darwin-64": {
-      "version": "1.20240512.0",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240512.0.tgz",
-      "integrity": "sha512-VMp+CsSHFALQiBzPdQ5dDI4T1qwLu0mQ0aeKVNDosXjueN0f3zj/lf+mFil5/9jBbG3t4mG0y+6MMnalP9Lobw==",
+      "version": "1.20241230.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20241230.0.tgz",
+      "integrity": "sha512-BZHLg4bbhNQoaY1Uan81O3FV/zcmWueC55juhnaI7NAobiQth9RppadPNpxNAmS9fK2mR5z8xrwMQSQrHmztyQ==",
       "cpu": [
         "x64"
       ],
@@ -538,9 +538,9 @@
       }
     },
     "node_modules/@cloudflare/workerd-darwin-arm64": {
-      "version": "1.20240512.0",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240512.0.tgz",
-      "integrity": "sha512-lZktXGmzMrB5rJqY9+PmnNfv1HKlj/YLZwMjPfF0WVKHUFdvQbAHsi7NlKv6mW9uIvlZnS+K4sIkWc0MDXcRnA==",
+      "version": "1.20241230.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20241230.0.tgz",
+      "integrity": "sha512-lllxycj7EzYoJ0VOJh8M3palUgoonVrILnzGrgsworgWlIpgjfXGS7b41tEGCw6AxSxL9prmTIGtfSPUvn/rjg==",
       "cpu": [
         "arm64"
       ],
@@ -554,9 +554,9 @@
       }
     },
     "node_modules/@cloudflare/workerd-linux-64": {
-      "version": "1.20240512.0",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240512.0.tgz",
-      "integrity": "sha512-wrHvqCZZqXz6Y3MUTn/9pQNsvaoNjbJpuA6vcXsXu8iCzJi911iVW2WUEBX+MpUWD+mBIP0oXni5tTlhkokOPw==",
+      "version": "1.20241230.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20241230.0.tgz",
+      "integrity": "sha512-Y3mHcW0KghOmWdNZyHYpEOG4Ba/ga8tht5vj1a+WXfagEjMO8Y98XhZUlCaYa9yB7Wh5jVcK5LM2jlO/BLgqpA==",
       "cpu": [
         "x64"
       ],
@@ -570,9 +570,9 @@
       }
     },
     "node_modules/@cloudflare/workerd-linux-arm64": {
-      "version": "1.20240512.0",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240512.0.tgz",
-      "integrity": "sha512-YPezHMySL9J9tFdzxz390eBswQ//QJNYcZolz9Dgvb3FEfdpK345cE/bsWbMOqw5ws2f82l388epoenghtYvAg==",
+      "version": "1.20241230.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20241230.0.tgz",
+      "integrity": "sha512-IAjhsWPlHzhhkJ6I49sDG6XfMnhPvv0szKGXxTWQK/IWMrbGdHm4RSfNKBSoLQm67jGMIzbmcrX9UIkms27Y1g==",
       "cpu": [
         "arm64"
       ],
@@ -586,9 +586,9 @@
       }
     },
     "node_modules/@cloudflare/workerd-windows-64": {
-      "version": "1.20240512.0",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240512.0.tgz",
-      "integrity": "sha512-SxKapDrIYSscMR7lGIp/av0l6vokjH4xQ9ACxHgXh+OdOus9azppSmjaPyw4/ePvg7yqpkaNjf9o258IxWtvKQ==",
+      "version": "1.20241230.0",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20241230.0.tgz",
+      "integrity": "sha512-y5SPIk9iOb2gz+yWtHxoeMnjPnkYQswiCJ480oHC6zexnJLlKTpcmBCjDH1nWCT4pQi8F25gaH8thgElf4NvXQ==",
       "cpu": [
         "x64"
       ],
@@ -2050,15 +2050,6 @@
         "undici-types": "~6.20.0"
       }
     },
-    "node_modules/@types/node-forge": {
-      "version": "1.3.11",
-      "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz",
-      "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
     "node_modules/@types/prop-types": {
       "version": "15.7.14",
       "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
@@ -3616,6 +3607,12 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/defu": {
+      "version": "6.1.4",
+      "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
+      "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
+      "dev": true
+    },
     "node_modules/depd": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -7554,9 +7551,9 @@
       }
     },
     "node_modules/miniflare": {
-      "version": "3.20240512.0",
-      "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240512.0.tgz",
-      "integrity": "sha512-X0PlKR0AROKpxFoJNmRtCMIuJxj+ngEcyTOlEokj2rAQ0TBwUhB4/1uiPvdI6ofW5NugPOD1uomAv+gLjwsLDQ==",
+      "version": "3.20241230.2",
+      "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20241230.2.tgz",
+      "integrity": "sha512-gFC3IaUKrLGdtA6y6PLpC/QE5YAjB5ITCfBZHkosRyFZ9ApaCHKcHRvrEFMc/R19QxxtHD+G3tExEHp7MmtsYQ==",
       "dev": true,
       "dependencies": {
         "@cspotcode/source-map-support": "0.8.1",
@@ -7566,11 +7563,11 @@
         "exit-hook": "^2.2.1",
         "glob-to-regexp": "^0.4.1",
         "stoppable": "^1.1.0",
-        "undici": "^5.28.2",
-        "workerd": "1.20240512.0",
-        "ws": "^8.11.0",
+        "undici": "^5.28.4",
+        "workerd": "1.20241230.0",
+        "ws": "^8.18.0",
         "youch": "^3.2.2",
-        "zod": "^3.20.6"
+        "zod": "^3.22.3"
       },
       "bin": {
         "miniflare": "bootstrap.js"
@@ -7879,15 +7876,6 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/node-forge": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
-      "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 6.13.0"
-      }
-    },
     "node_modules/node-releases": {
       "version": "2.0.19",
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
@@ -8113,6 +8101,12 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/ohash": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz",
+      "integrity": "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==",
+      "dev": true
+    },
     "node_modules/on-finished": {
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@@ -9517,19 +9511,6 @@
         "loose-envify": "^1.1.0"
       }
     },
-    "node_modules/selfsigned": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz",
-      "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==",
-      "dev": true,
-      "dependencies": {
-        "@types/node-forge": "^1.3.0",
-        "node-forge": "^1"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/semver": {
       "version": "7.6.3",
       "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
@@ -10754,6 +10735,25 @@
       "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
       "dev": true
     },
+    "node_modules/unenv": {
+      "version": "2.0.0-rc.0",
+      "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.0.tgz",
+      "integrity": "sha512-H0kl2w8jFL/FAk0xvjVing4bS3jd//mbg1QChDnn58l9Sc5RtduaKmLAL8n+eBw5jJo8ZjYV7CrEGage5LAOZQ==",
+      "dev": true,
+      "dependencies": {
+        "defu": "^6.1.4",
+        "mlly": "^1.7.4",
+        "ohash": "^1.1.4",
+        "pathe": "^1.1.2",
+        "ufo": "^1.5.4"
+      }
+    },
+    "node_modules/unenv/node_modules/pathe": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
+      "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
+      "dev": true
+    },
     "node_modules/unified": {
       "version": "10.1.2",
       "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz",
@@ -11724,9 +11724,9 @@
       }
     },
     "node_modules/workerd": {
-      "version": "1.20240512.0",
-      "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240512.0.tgz",
-      "integrity": "sha512-VUBmR1PscAPHEE0OF/G2K7/H1gnr9aDWWZzdkIgWfNKkv8dKFCT75H+GJtUHjfwqz3rYCzaNZmatSXOpLGpF8A==",
+      "version": "1.20241230.0",
+      "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20241230.0.tgz",
+      "integrity": "sha512-EgixXP0JGXGq6J9lz17TKIZtfNDUvJNG+cl9paPMfZuYWT920fFpBx+K04YmnbQRLnglsivF1GT9pxh1yrlWhg==",
       "dev": true,
       "hasInstallScript": true,
       "bin": {
@@ -11736,33 +11736,28 @@
         "node": ">=16"
       },
       "optionalDependencies": {
-        "@cloudflare/workerd-darwin-64": "1.20240512.0",
-        "@cloudflare/workerd-darwin-arm64": "1.20240512.0",
-        "@cloudflare/workerd-linux-64": "1.20240512.0",
-        "@cloudflare/workerd-linux-arm64": "1.20240512.0",
-        "@cloudflare/workerd-windows-64": "1.20240512.0"
+        "@cloudflare/workerd-darwin-64": "1.20241230.0",
+        "@cloudflare/workerd-darwin-arm64": "1.20241230.0",
+        "@cloudflare/workerd-linux-64": "1.20241230.0",
+        "@cloudflare/workerd-linux-arm64": "1.20241230.0",
+        "@cloudflare/workerd-windows-64": "1.20241230.0"
       }
     },
     "node_modules/wrangler": {
-      "version": "3.57.1",
-      "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.57.1.tgz",
-      "integrity": "sha512-M8YnWUwdrb8AFiRePtVnzlDn02OX4osWvdl8oVh6eyZqqkqXYg7lwlYBr14Qj92pMN4JvMBmDZoukkYHvwpJRg==",
+      "version": "3.105.0",
+      "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.105.0.tgz",
+      "integrity": "sha512-NX10iuUXtgiVRG9YJ7dwwEUuhQ38hu4stcxMWq4dbKCnfcOj7fLFh+HwaWudqOr1jDCPrnSOQVkgfAfG3ZH9Lw==",
       "dev": true,
       "dependencies": {
-        "@cloudflare/kv-asset-handler": "0.3.2",
-        "@esbuild-plugins/node-globals-polyfill": "^0.2.3",
-        "@esbuild-plugins/node-modules-polyfill": "^0.2.2",
-        "blake3-wasm": "^2.1.5",
-        "chokidar": "^3.5.3",
+        "@cloudflare/kv-asset-handler": "0.3.4",
+        "@esbuild-plugins/node-globals-polyfill": "0.2.3",
+        "@esbuild-plugins/node-modules-polyfill": "0.2.2",
+        "blake3-wasm": "2.1.5",
         "esbuild": "0.17.19",
-        "miniflare": "3.20240512.0",
-        "nanoid": "^3.3.3",
-        "path-to-regexp": "^6.2.0",
-        "resolve": "^1.22.8",
-        "resolve.exports": "^2.0.2",
-        "selfsigned": "^2.0.1",
-        "source-map": "0.6.1",
-        "xxhash-wasm": "^1.0.1"
+        "miniflare": "3.20241230.2",
+        "path-to-regexp": "6.3.0",
+        "unenv": "2.0.0-rc.0",
+        "workerd": "1.20241230.0"
       },
       "bin": {
         "wrangler": "bin/wrangler.js",
@@ -11775,7 +11770,7 @@
         "fsevents": "~2.3.2"
       },
       "peerDependencies": {
-        "@cloudflare/workers-types": "^4.20240512.0"
+        "@cloudflare/workers-types": "^4.20241230.0"
       },
       "peerDependenciesMeta": {
         "@cloudflare/workers-types": {
@@ -11784,9 +11779,9 @@
       }
     },
     "node_modules/wrangler/node_modules/@cloudflare/kv-asset-handler": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.3.2.tgz",
-      "integrity": "sha512-EeEjMobfuJrwoctj7FA1y1KEbM0+Q1xSjobIEyie9k4haVEBB7vkDvsasw1pM3rO39mL2akxIAzLMUAtrMHZhA==",
+      "version": "0.3.4",
+      "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.3.4.tgz",
+      "integrity": "sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==",
       "dev": true,
       "dependencies": {
         "mime": "^3.0.0"
@@ -12202,15 +12197,6 @@
       "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==",
       "dev": true
     },
-    "node_modules/wrangler/node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/wrap-ansi": {
       "version": "8.1.0",
       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
@@ -12341,12 +12327,6 @@
         "node": ">=0.4"
       }
     },
-    "node_modules/xxhash-wasm": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz",
-      "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==",
-      "dev": true
-    },
     "node_modules/yallist": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
diff --git a/package.json b/package.json
index 7040ed0..2d1d55d 100644
--- a/package.json
+++ b/package.json
@@ -5,12 +5,14 @@
   "type": "module",
   "scripts": {
     "build": "remix vite:build",
-    "deploy": "wrangler pages deploy ./build/client",
+    "deploy": "npm run build && wrangler pages deploy",
     "dev": "remix vite:dev",
     "lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
     "start": "wrangler pages dev ./build/client",
     "typecheck": "tsc",
-    "typegen": "wrangler types"
+    "typegen": "wrangler types",
+    "preview": "npm run build && wrangler pages dev",
+    "cf-typegen": "wrangler types"
   },
   "dependencies": {
     "@remix-run/cloudflare": "^2.15.2",
@@ -21,7 +23,7 @@
     "react-dom": "^18.2.0"
   },
   "devDependencies": {
-    "@cloudflare/workers-types": "^4.20240512.0",
+    "@cloudflare/workers-types": "^4.20250121.0",
     "@remix-run/dev": "^2.15.2",
     "@types/react": "^18.2.20",
     "@types/react-dom": "^18.2.7",
@@ -39,7 +41,7 @@
     "typescript": "^5.1.6",
     "vite": "^5.1.0",
     "vite-tsconfig-paths": "^4.2.1",
-    "wrangler": "3.57.1"
+    "wrangler": "^3.105.0"
   },
   "engines": {
     "node": ">=20.0.0"
diff --git a/tsconfig.json b/tsconfig.json
index a61e663..857ca9d 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -9,7 +9,11 @@
   ],
   "compilerOptions": {
     "lib": ["DOM", "DOM.Iterable", "ES2022"],
-    "types": ["@remix-run/cloudflare", "vite/client"],
+    "types": [
+        "@remix-run/cloudflare",
+        "vite/client",
+        "@cloudflare/workers-types/2023-07-01"
+    ],
     "isolatedModules": true,
     "esModuleInterop": true,
     "jsx": "react-jsx",
diff --git a/worker-configuration.d.ts b/worker-configuration.d.ts
new file mode 100644
index 0000000..7edf06f
--- /dev/null
+++ b/worker-configuration.d.ts
@@ -0,0 +1,4 @@
+// Generated by Wrangler
+// After adding bindings to `wrangler.json`, regenerate this interface via `npm run cf-typegen`
+interface Env {
+}
diff --git a/wrangler.json b/wrangler.json
new file mode 100644
index 0000000..2748e9b
--- /dev/null
+++ b/wrangler.json
@@ -0,0 +1,47 @@
+/**
+ * For more details on how to configure Wrangler, refer to:
+ * https://developers.cloudflare.com/workers/wrangler/configuration/
+ */
+{
+  "$schema": "node_modules/wrangler/config-schema.json",
+  "name": "my-create-cloudflare",
+  "compatibility_date": "2025-01-21",
+  "pages_build_output_dir": "./build/client",
+  "observability": {
+    "enabled": true
+  }
+  /**
+   * Smart Placement
+   * Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement
+   */
+  // "placement": { "mode": "smart" },
+
+  /**
+   * Bindings
+   * Bindings allow your Worker to interact with resources on the Cloudflare Developer Platform, including
+   * databases, object storage, AI inference, real-time communication and more.
+   * https://developers.cloudflare.com/workers/runtime-apis/bindings/
+   */
+
+  /**
+   * Environment Variables
+   * https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables
+   */
+  // "vars": { "MY_VARIABLE": "production_value" },
+  /**
+   * Note: Use secrets to store sensitive data.
+   * https://developers.cloudflare.com/workers/configuration/secrets/
+   */
+
+  /**
+   * Static Assets
+   * https://developers.cloudflare.com/workers/static-assets/binding/
+   */
+  // "assets": { "directory": "./public/", "binding": "ASSETS" },
+
+  /**
+   * Service Bindings (communicate between multiple Workers)
+   * https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings
+   */
+  // "services": [{ "binding": "MY_SERVICE", "service": "my-service" }]
+}
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

ビルド&デプロイしてみる

コマンd
npm run build
npm run deploy

デプロイしたがアクセスしても接続できません画面が表示される。

と思ったが、しばらく待ったら表示された。

エッジに配信されるまでに少し時間がかかるのだろうか?

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

SPA モードのテンプレートを使ってみる

コマンド
npx create-remix@latest --template remix-run/remix/templates/spa my-create-remix-spa
cd my-create-remix-spa
npm run dev
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

SPA モードのテンプレートには entry.server.tsx がない


entry.client.tsx の違いも気になる

entry.client.tsx の内容は同じだった。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

SPA モードでビルドしたら何ができる?

コマンド
npm run build
npm run preview

build に index.html が含まれるようになった。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

my-create-cloudflare に戻る

entry.server.ts を削除して実行すれば良いのかな? → 関係なかった。

見比べてみると pakcage.json に違いがあった。

my-create-cloudflare は @remix-run/cloudflare と @remix-run/cloudflare-pages になっていて、my-create-remix-spa は @remix-run/node になっていた。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Workers を第 1 候補にして良さそう

自分で試行錯誤した訳ではないし、Static Assets もまだ Beta だが、少なくとも遊びで試す分には Workers を第 1 候補にして良さそう。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

まとめ

Cloudflare Workers に SSR 対応の Web アプリをデプロイするつもりなら下記コマンドを使えば良さそう。

コマンド
npm create cloudflare@latest my-remix-app -- --framework=remix --experimental

Cloudflare Pages に SPA をデプロイするつもりなら、SPA テンプレートを使った方が良さそう。

コマンド
npx create-remix@latest --template remix-run/remix/templates/spa my-remix-spa

その上で下記の Cloudflare Pages のテンプレートを参考にして wrangler.toml 作成や package.json の編集を行えば良さそう。

https://github.com/remix-run/remix/tree/main/templates/cloudflare

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

せっかくなのでコスト検討

  • Workers Free は 1 日 10 万リクエストまでは無料
  • Workers Paid は 1 月 1,000 万リクエストまでは 5 ドル、それ以降は 100 万リクエスト当り 0.3 ドル
  • Cloudflare Free (Pages) は無料だが月間 500 ビルドまで、デプロイはビルドに含まれないのかな?

Cloudflare Pages も結局 Workers リクエストとして課金されるので結局同じか。

Requests to your Functions are billed as Cloudflare Workers requests.

Cloudflare Workers の Static Assets は無料のようだ、太っ腹!

https://developers.cloudflare.com/workers/static-assets/#pricing

Requests to static assets are free and unlimited.

このスクラップは2025/01/24にクローズされました