Void は import を見て Cloudflare のリソースを作り、作った物は消さない
Vite と Vitest を作っている VoidZero から Void が出ました。コードを読んで、使っている D1・KV・R2 などを Cloudflare のアカウントに自動で作り、Workers にデプロイする SDK と CLI です。Astro 製の CMS「EmDash」のサイトは wrangler.jsonc に D1・R2・KV のバインディングを手で書いて動かしているので、Void に替えれば ID を作って貼る作業が無くなるのか確かめてみました。
試したのは次の 3 つです。
- 2 通りでデプロイする: KV にノートを置く同じ Astro のアプリを、Void と、wrangler.jsonc を手で書く @astrojs/cloudflare の 2 通りでデプロイする
- 使っていないファイルを置く: Void の方のアプリに、どこからも import しないファイルを 1 つ置いてデプロイし、そのファイルを消してもう一度デプロイする
- 置き場所と書き方を変える: Astro を使わない Void のテンプレートのアプリで、ファイルの置き場所と書き方を 7 通り変え、どのバインディングが付くかを見る
バージョンは void 1.1.11、astro 7.3.8、@astrojs/cloudflare 14.3.4、wrangler 4.151.0 です。
結果、KV を使うノートアプリでは、ID を貼る作業が Void で無くなりました。Astro+Void のノートアプリは、wrangler.jsonc も ID も書かずに void deploy を 1回打つだけで KV が作られ、アプリがデプロイされて、ノートの一覧と書き込みが動きました。
ただ、どのページからも呼ばれていないファイルでも、Void の R2 用のモジュール void/storage を import する行があるだけで、デプロイのときに R2 のバケットが作られました。Void は、コードが実際に動くかではなく、ファイルに書かれた import を見て作るリソースを決めるためです。デプロイの前に何を作るかの一覧は出ず、後でそのファイルを消してデプロイし直しても、バケットは残りました。
Void は作るリソースをファイルの置き場所と import・参照から決める
Resource Inference の文書によると、Void は決まったディレクトリのファイルを読み、void/db・void/kv・void/storage のような Void の SDK のモジュールの import と、env.DB のような参照を構文として拾います。Void のテンプレートで読むのは src や routes などのディレクトリで、void.config.ts の inference.scanDirs で変えられます。
Astro を使わない Void のテンプレートで KV を使うアプリを作り、ファイルの置き場所と書き方を変えて、build が出す wrangler.json にどのバインディングが入るかを見ると次のようになり、付くかどうかはそのコードが実行されるかでは決まりませんでした。
- KV を使う関数を src の外の `lib/memos.ts` に置き、ページから呼ぶ: KV が付かず、手元の dev サーバーでバインディングが無いというエラーになってトップが 500
- 同じ関数を `src/lib/memos.ts` に置く: KV が付く
- どこからも import されない `src/unused-upload.ts` で `void/storage` を import する: R2 が付く
- コメントの `// env.AI` と文字列の `"env.STORAGE"`: 何も付かない
- 呼ばれない関数の中の `if (false) return c.env.AI`: AI が付く
- どこからも使わない `db/schema.ts` だけ: 何も付かない
- `db/migrations/` のファイルだけ: D1 が付く
作る前に一覧は出ず、作った R2 はファイルを消しても残る
Astro+Void のノートアプリの src/lib/ に、void/storage を import するだけの 3行のファイルをどこからも import せずに置いて void deploy しました。デプロイの後に Cloudflare のアカウントを見ると、R2 バケットが作られ、Worker に STORAGE のバインディングが付いていました。デプロイの出力には、リソースを作ったという行はありませんでした。
void deploy は作る前に一覧を出さず、前もって出す dry-run や plan のようなオプションもありません(void deploy の文書)。ただ、build が出す wrangler.json を見れば、どのバインディングが付くかはデプロイの前に分かります。
Void は最初のデプロイの後に、作ったリソースの名前と ID を void.lock.json に書きます。その 3行のファイルを消して void deploy し直しても、STORAGE は次の 4か所に残りました。
- アカウント: R2 バケットが残る
- Worker: STORAGE のバインディングが外れない
- Void が書き出す wrangler の設定ファイル: STORAGE が残る
- void.lock.json: STORAGE が残り、
r2_bucketsにバケットが増えたまま
void project の文書によると、Void が自動で作ったリソースは他のアプリと共有されている場合があるので、Void は自動では消しません。自分の Cloudflare アカウントにデプロイしたものには void project delete も動きません。
KV の ID を貼りたくないだけなら wrangler も作り、作る前に一覧を出す
wrangler.jsonc を手で書く方で KV を試すと、バインディングに ID を書かずに次の 1行を打つだけで、wrangler の自動プロビジョニングが KV を作ってからデプロイしました。
astro build && wrangler deploy
wrangler の方は、作る前に「The following bindings need to be provisioned:」と出し、図の右のとおり、私が ID を書かなかった MEMOS と、@astrojs/cloudflare がアプリで使っていなくても足す SESSION の 2 つの KV を一覧に並べてから作りました。もう 1 度デプロイすると「inherited」と出て、新しくは作りませんでした。wrangler の方で ID を書かずにおいた D1 や R2 も作られるか、既存のサイトで書いてある ID を消すとどうなるかは試していないので、D1 や R2 の ID を貼る作業まで wrangler の方で無くせるかは、この結果からは言えません。
既にある wrangler.jsonc に KV を足すだけなら、wrangler の方で ID を書かずにデプロイすれば済みます。wrangler は作る前に一覧を出します。
wrangler.jsonc 自体を書かずに始めたいなら Void で、そのときはデプロイの前に build が出す wrangler.json のバインディングを見て、デプロイの後に void.lock.json の差分を見ます。要らないリソースは、どのアプリが使っているかを確かめてから、Cloudflare のダッシュボードか wrangler で手で消します。