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

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

プロジェクトの作成方法
色々とある。
npm create cloudflare@latest -- my-remix-app --framework=remix
npm create cloudflare@latest my-remix-app -- --framework=remix --experimental
npx create-remix@latest --template remix-run/remix/templates/cloudflare
npx create-remix@latest --template remix-run/remix/templates/cloudflare-workers

現在は --experimental
ではなく --platform workers
に変わったようだ。

参考になる記事
まずは Workers で試してみようかな。

こちらも参考になりそう

プロジェクト作成
npm create cloudflare@latest my-remix-app -- --framework=remix --experimental
ログを見ていると結局 https://github.com/remix-run/remix/tree/main/templates/cloudflare-workers のテンプレートが使用されているようだ。

とりあえずデプロイしてみる
npm run deploy
何の苦もなくデプロイできた。

Remix 版も試してみる
npx create-remix@latest --template remix-run/remix/templates/cloudflare-workers my-create-remix-workers

違いは何だろう?
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"

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"

create-cloudflare の方が良いかも
create-remix の方でも問題なくデプロイできた。
ただ、より良いのは create-cloudflare の方かもしれない。

次は Pages を試してみよう
こちらもまずは create cloudflare
から。
npm create cloudflare@latest -- my-create-cloudflare --framework=remix
こちらもテンプレートとしては下記が使用されているようだ。

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" }]
+}

ビルド&デプロイしてみる
npm run build
npm run deploy
デプロイしたがアクセスしても接続できません画面が表示される。
と思ったが、しばらく待ったら表示された。
エッジに配信されるまでに少し時間がかかるのだろうか?

create remix は割愛
多分、create remix でも動くのだろうが create cloudflare で事足りそうだ。

SPA モードにした場合
ssr
を false にしてビルドすると失敗する。

SPA モードのテンプレートを使ってみる
npx create-remix@latest --template remix-run/remix/templates/spa my-create-remix-spa
cd my-create-remix-spa
npm run dev

SPA モードのテンプレートには entry.server.tsx がない
entry.client.tsx の違いも気になる
entry.client.tsx の内容は同じだった。

SPA モードでビルドしたら何ができる?
npm run build
npm run preview
build に index.html が含まれるようになった。

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 になっていた。

Cloudflare Workers のランタイム
@remix-run/server-runtime になっている。

Pages と Workers のどちらを使えば良いんだろう
Workers のような気もするが確証が持てない。

参考になりそうな記事

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

まとめ
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 の編集を行えば良さそう。

せっかくなのでコスト検討
- 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 は無料のようだ、太っ腹!
Requests to static assets are free and unlimited.