Files
next-ai-draw-io/docs/ja/cloudflare-deploy.md
T
Dayuan Jiang 60105ddb51 refactor: remove dead code and over-engineering found by two audits (#986)
## Problem

Two audits of the repository (a workflow of finder, dedup and per-file verifier agents, run on 2026-10-11 against 1f4141e and again against 07f3e3c after a first round of refactoring) found dead code and features that were more machinery than the app needs: an Electron configuration-preset system with its own settings window, three copies of the about page, a hand-written `.env` parser, an "extended" system prompt nobody selected, two data migrations for formats from 2025-12 and 2026-01, a server-side example cache, type-to-confirm provider deletion, 81 unused dictionary keys, wrapper components around single call sites, and a long tail of unused exports, props, options and tests.

## Change

Every item below was either approved one by one or covered by "fix all of the others".

- **Electron:** the configuration-preset system is gone (settings window, preload, IPC, menu entry, dev watcher); `config-manager.ts` keeps only `userLocale`; `.env` files are parsed with `dotenv`. Entitlements file and a duplicate CI workflow removed; `test.yml` gets a type check and concurrency.
- **Server:** no extended prompt, no example cache, no `ENABLE_HISTORY_XML_REPLACE`, no message metadata or `hasConfig`; the connection test is one shared helper; EdgeOne loses its mock branch and model aliases; `DEBUG_LLM_PAYLOAD` logs message structure instead of payloads; Langfuse scoring helper; `apiKeyEnv` arrays kept and documented in `env.example` and the provider docs.
- **Pages:** one about page per language from a single component (old `/cn` and `/ja` URLs redirect with 308); layout uses `hasLocale`; the GitHub icon is a local component instead of `react-icons`; Cloudflare deploys without an R2 cache by default.
- **Chat and canvas:** the legacy `diagramHistory` conversion, the localStorage chat migration and the templates storage are gone; `chat-engine` reads the diagram through the context's refs; the diagram context has one tagged export path (`requestTaggedExport` / `fetchDiagramXml`); the screenshot check uses fetch + JSON and `generateText` with `Output.object`; `load-diagram` accepts `<svg:svg>` and strips the XML prolog.
- **Settings UI:** `model-selector` inlines its Dialog, Command and Tooltip; `ai-elements/model-selector`, `button-with-tooltip`, `error-toast` removed; no type-to-confirm, no footer, no `bedrockApiKey`; `use-model-config` loses the old-format migration; one reasoning component; the shimmer is CSS (no `motion`, no `@radix-ui/react-use-controllable-state`); 81 dictionary keys removed in all four languages.
- **MCP server:** `registerTool` / `ok` / `fail` replace per-tool try/catch; `syncFromBrowser`, `commitDocument`, `describePages`; the hand-written XML syntax check, unused result fields, `pickPageSelector`, `expandStyles` and the `host` attribute handling are gone; tests get a shared `setup.ts` and drive the server through the SDK client.
- **Prompt:** the web app's style rules come from the MCP drawing guide (`styleRules`), byte-identical to before.
- **Tests:** shared e2e helpers (`openApp`, `sse`, `toolCallEvents`, `chunkedReplies`); placeholder specs dropped; `settings-review-fixes` split by topic; unit tests use `vi.stubEnv`.
- **Dependencies removed:** `@xmldom/xmldom`, `remark-gfm`, `@anthropic-ai/tokenizer`, `@testing-library/user-event`, `concurrently`, `wait-on`, `eslint`, `eslint-config-next`, `@vitest/coverage-v8`, `shx`, `motion`, `@radix-ui/react-use-controllable-state`, `react-icons`.

Source lines: 74,983 before, 67,418 after (excluding lockfiles).

The last commit merges #984 (the canvas shell). Where the shell, the classic page or their tests depend on a wire format or signature this branch had changed, main's version wins (export fields of the poll response, `addHistory` signature); where main only extended code this branch restructured, main's change is carried into the new structure (`start_session`, `get_selection`, `prepareNewDiagram`, the diagram context's `requestExport`).

## Testing

- `tsc --noEmit` for the web app, `packages/mcp-server`, its shell and `electron`: clean
- `biome ci`: 0 errors (37 pre-existing warnings)
- Root `vitest run`: 719 passed; `packages/mcp-server` `vitest run`: 372 passed
- `next build`: clean
- Playwright, whole web suite on the dev server (4 workers): 280 tests, 279 passed; `language.spec.ts` "a stale offer to switch without saving does nothing once a message is being sent" failed under parallel load and passed alone, as it does on main
2026-10-12 12:35:55 +09:00

238 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Cloudflare Workers へのデプロイ
このプロジェクトは **OpenNext アダプター** を使用して **Cloudflare Worker** としてデプロイすることができ、以下のメリットがあります:
- グローバルエッジへのデプロイ
- 超低レイテンシー
- 無料の `workers.dev` ホスティング
- R2 を介した完全な Next.js ISR サポート(オプション)
> **Windows ユーザー向けの重要な注意:** OpenNext と Wrangler は、**ネイティブ Windows 環境では完全には信頼できません**。以下の方法を推奨します:
>
> - **GitHub Codespaces** を使用する(完全に動作します)
> - または **WSL (Linux)** を使用する
>
> 純粋な Windows 環境でのビルドは、WASM ファイルパスの問題により失敗する可能性があります。
---
## 前提条件
1. **Cloudflare アカウント**(基本的なデプロイには無料プランで十分です)
2. **Node.js 18以上**
3. **Wrangler CLI** のインストール(開発依存関係で問題ありません):
```bash
npm install -D wrangler
```
4. Cloudflare へのログイン:
```bash
npx wrangler login
```
> **注意:** 支払い方法の登録が必要なのは、ISR キャッシュのために R2 を有効にする場合のみです。基本的な Workers へのデプロイは無料です。
---
## ステップ 1 — 依存関係のインストール
```bash
npm install
```
---
## ステップ 2 — 環境変数の設定
Cloudflare はローカルテスト用に別のファイルを使用します。
### 1) `.dev.vars` の作成(Cloudflare ローカルおよびデプロイ用)
```bash
cp env.example .dev.vars
```
API キーと設定を入力してください。
### 2) `.env.local` も存在することを確認(通常の Next.js 開発用)
```bash
cp env.example .env.local
```
同じ値を入力してください。
---
## ステップ 3 — デプロイタイプの選択
### オプション A: R2 なしでのデプロイ(デフォルト、無料)
リポジトリはこの構成のままです。`open-next.config.ts` は `defineCloudflareConfig({})` で、`wrangler.jsonc` に `r2_buckets` はありません。ファイルを変更する必要はないので、**ステップ 4** へ進んでください。
---
### オプション B: R2 ありでのデプロイ(オプション、ISR キャッシュ用)
R2 は OpenNext が **Incremental Static Regeneration (ISR)** ページを保存する場所になります。このアプリには現在 ISR ページがないため、自分で ISR ページを追加した場合にだけ必要です。Cloudflare アカウントに支払い方法の登録が必要です。
**1. R2 バケットの作成**(Cloudflare ダッシュボードにて):
- **Storage & Databases → R2** へ移動
- **Create bucket** をクリック
- 名前を入力: `next-inc-cache`
**2. `open-next.config.ts` の設定:**
```ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare/config"
import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache"
export default defineCloudflareConfig({
incrementalCache: r2IncrementalCache,
})
```
**3. `wrangler.jsonc` に `r2_buckets` を追加:**
```jsonc
{
"$schema": "node_modules/wrangler/config-schema.json",
"main": ".open-next/worker.js",
"name": "next-ai-draw-io-worker",
"compatibility_date": "2025-12-08",
"compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
"assets": {
"directory": ".open-next/assets",
"binding": "ASSETS"
},
"r2_buckets": [
{
"binding": "NEXT_INC_CACHE_R2_BUCKET",
"bucket_name": "next-inc-cache"
}
],
"services": [
{
"binding": "WORKER_SELF_REFERENCE",
"service": "next-ai-draw-io-worker"
}
]
}
```
> **重要:** `bucket_name` は Cloudflare ダッシュボードで作成した名前と完全に一致させる必要があります。
> **注意:** 時間ベースの再検証(ページや fetch の `revalidate`)には、`open-next.config.ts` で `queue` の設定も必要です。OpenNext の Cloudflare キャッシュドキュメントを参照してください。
---
## ステップ 4 — workers.dev サブドメインの登録(初回のみ)
初回デプロイの前に、workers.dev サブドメインが必要です。
**オプション 1: Cloudflare ダッシュボード経由(推奨)**
アクセス先: https://dash.cloudflare.com → Workers & Pages → Overview → Set up a subdomain
**オプション 2: デプロイ時**
`npm run deploy` を実行した際、Wrangler が以下のように尋ねてくる場合があります:
```
Would you like to register a workers.dev subdomain? (Y/n)
```
`Y` を入力し、サブドメイン名を選択してください。
> **注意:** CI/CD や非対話型環境では、このプロンプトは表示されません。事前にダッシュボードで登録してください。
---
## ステップ 5 — Cloudflare へのデプロイ
```bash
npm run deploy
```
スクリプトの処理内容:
- Next.js アプリのビルド
- OpenNext を介した Cloudflare Worker への変換
- 静的アセットのアップロード
- Worker の公開
アプリは以下の URL で利用可能になります:
```
https://<worker-name>.<your-subdomain>.workers.dev
```
---
## よくある問題と解決策
### `You need to register a workers.dev subdomain`
**原因:** アカウントに workers.dev サブドメインが登録されていません。
**解決策:** https://dash.cloudflare.com → Workers & Pages → Set up a subdomain から登録してください。
---
### `Please enable R2 through the Cloudflare Dashboard`
**原因:** `wrangler.jsonc` で R2 が設定されていますが、アカウントで R2 が有効になっていません。
**解決策:** R2 を有効にする(支払い方法が必要)か、オプション A(R2 なしでデプロイ)を使用してください。
---
### `No R2 binding "NEXT_INC_CACHE_R2_BUCKET" found`
**原因:** `wrangler.jsonc` に `r2_buckets` がありません。
**解決策:** `r2_buckets` セクションを追加するか、オプション A(R2 なし)に切り替えてください。
---
### `Can't set compatibility date in the future`
**原因:** wrangler 設定の `compatibility_date` が未来の日付に設定されています。
**解決策:** `compatibility_date` を今日またはそれ以前の日付に変更してください。
---
### Windows エラー: `resvg.wasm?module` (ENOENT)
**原因:** Windows のファイル名には `?` を含めることができませんが、wasm アセットのファイル名に `?module` が使用されているためです。
**解決策:** Linux 環境(WSL、Codespaces、または CI)でビルド/デプロイしてください。
---
## オプション: ローカルでのプレビュー
デプロイ前に Worker をローカルでプレビューできます:
```bash
npm run preview
```
---
## まとめ
| 機能 | R2 なし | R2 あり |
|---------|------------|---------|
| コスト | 無料 | 支払い方法が必要 |
| ISR キャッシュ | なし | あり |
| 静的ページ | あり | あり |
| API ルート | あり | あり |
| 設定の複雑さ | シンプル | 普通 |
リポジトリのデフォルトは **R2 なし** です。ISR キャッシュが必要なページを追加した場合にだけ **R2 あり** を選んでください。