1ライブデモ
下のボタンを押すと /api/d1 を実際に呼び出します。この Pages Function は D1
に接続し、テーブル作成 → 1 行 INSERT → 集計 SELECT を行った結果をそのまま JSON で返します。
つまりこの結果が表示されれば、Workers Functions + D1 が本番環境で実際に動いている証拠になります。
2このアプリの全ソース
このサイトを構成するファイルはこれだけです。そのままコピーして使えます。
name = "wrangler-d1-sample"
pages_build_output_dir = "public"
compatibility_date = "2026-07-01"
[[d1_databases]]
binding = "DB"
database_name = "showcase_db"
database_id = "10837764-4119-4b99-8e9c-6dc8d85e42f6"
export async function onRequestGet(context) {
const { env } = context;
const db = env.DB;
const corsHeaders = {
"content-type": "application/json",
"access-control-allow-origin": "*",
};
try {
await db
.prepare(
"CREATE TABLE IF NOT EXISTS sample_visits (id INTEGER PRIMARY KEY AUTOINCREMENT, ts TEXT)"
)
.run();
await db
.prepare("INSERT INTO sample_visits (ts) VALUES (datetime('now'))")
.run();
const nowResult = await db.prepare("SELECT datetime('now') AS now").first();
const countResult = await db
.prepare("SELECT COUNT(*) AS total FROM sample_visits")
.first();
const recentResult = await db
.prepare("SELECT id, ts FROM sample_visits ORDER BY id DESC LIMIT 5")
.all();
const body = {
ok: true,
now: nowResult ? nowResult.now : null,
total_visits: countResult ? countResult.total : 0,
recent: recentResult.results,
};
return new Response(JSON.stringify(body), {
status: 200,
headers: corsHeaders,
});
} catch (err) {
return new Response(
JSON.stringify({ ok: false, error: String(err && err.message ? err.message : err) }),
{ status: 500, headers: corsHeaders }
);
}
}
# D1 は既存の showcase_db を再利用(新規作成しない)
npx wrangler pages project create wrangler-d1-sample --production-branch=main
# public/ をビルド出力として Functions ごとデプロイ
npx wrangler pages deploy public --project-name=wrangler-d1-sample --branch=main --commit-dirty=true
3ローカル開発の手順
npx wrangler dev
D1 もローカルの SQLite(.wrangler/state 配下)に対して動作します。
本番データには一切触れないため、まず試すならこちら。
[[d1_databases]]
binding = "DB"
database_name = "showcase_db"
database_id = "10837764-4119-4b99-8e9c-6dc8d85e42f6"
experimental_remote = true
npx wrangler dev --x-remote-bindings
バインディングに experimental_remote = true を追加し、
--x-remote-bindings フラグを付けて起動すると、ローカルの Function コードから
本番の D1 データベースへ直接読み書きできます。本番データを扱う分、取り扱いは慎重に。
4write EOF / Failed to start ProxyWorker(Windows)の対処
前提知識: wrangler dev は --remote の有無にかかわらず、
ローカルで workerd.exe(ネイティブバイナリ)を起動して動きます。
Failed to start ProxyWorker ... write EOF というエラーは、
「起動直後に workerd プロセスが死に、wrangler がその stdin へ書き込んだ結果 EOF になった」ことを意味します。
これは Windows 環境で wrangler 3.15〜4.23 の間、長期にわたって報告され続けている既知のバグ群です
(workers-sdk#4412,
#6262,
#7013,
#8224,
#9900,
workerd#4668)。
- 最有力の修正: Microsoft Visual C++ 2015–2022 再頒布可能パッケージを
x64 と x86 の両方 インストールし、ターミナルを再起動してください。
この症状にズバリ効いたという修正報告があります(下記リンクの dev.to 記事参照)。winget install Microsoft.VCRedist.2015+.x64 winget install Microsoft.VCRedist.2015+.x86 - 切り分けコマンド:
workerd.exeを直接叩いて、 そもそも起動できるかを確認します。
DLL エラーが出る、または無言で終了する場合は workerd 自体が起動できていない =ランタイム(VC++ 再頒布可能パッケージ)の問題で確定です。バージョン文字列が表示される場合は別の要因を疑ってください。node_modules\@cloudflare\workerd-windows-64\bin\workerd.exe --version - 追加で試す: IPv6/localhost 名前解決が原因のケースの切り分けとして、
を設定してから起動してみてください(workers-sdk#12910)。 また、set NODE_OPTIONS=--dns-result-order=ipv4first--remoteフラグの代わりに、wrangler.toml の D1 バインディングにexperimental_remote = trueを追加しnpx wrangler dev --x-remote-bindingsを使う方法も、症状が出るパス自体を回避できる場合があります(本ページの「3. ローカル開発の手順」参照)。 - それでも解決しない場合: WSL2 上で開発するのが最も確実な回避策です。 workerd の Windows ネイティブ版には未修正の問題が複数残っていますが、 WSL2(Linux バイナリ)を使えばこれらは発生しません。VS Code の WSL 拡張を使えば、 開発体験はネイティブ Windows とほぼ変わりません。
参考リンク: workers-sdk#8224 ・ workerd#4668 ・ dev.to/mrtoxas: Wrangler write EOF on Windows — the actual fix