cf migrateは何を変換し、何を手で直すのか。Wrangler移行の線引き

gen
gen

@gennnn ・ 38本

サムネイル

Wranglerの後継cfがオープンベータになり、cf migrateを1回叩けばwrangler.jsoncがcloudflare.config.tsに変わると聞いて、Claude Codeに丸投げしたくなっていませんか? cf migrateの動きは、変換されるもの、TODOとして残るもの、何も言わずに消えるものの3つに分けると見通しが立ちます。いちばんの罠は、何も言わずに消えるものです。

ここに書くのは公式ドキュメントとGitHubの公開issueで確かめられることで、僕が本番のWorkerで回した結果ではありません。cf自体もベータなので、コマンドや設定の形は安定版までに変わりえます。

Wranglerの18か月は、まだ数え始まっていない

Cloudflareの公式ブログによると、オープンベータが終わった時点でWranglerの最終メジャー版が出て、cfを使うよう案内するようになります。保守サポートが続くのは、そこから18か月です。起点はベータの終了で、その日付はまだ発表されていません。

「あと1年半でWranglerが終わる」と読むと焦りますが、時計はまだ動いていません。ブログには、esbuildでビルドし続けたいJavaScriptのWorkerと、Python・RustのWorkerについては、cfがdevとデプロイをWranglerに委ねるとも書かれています。後継と呼ばれていても、Wranglerはcfの裏で当面使われ続けます。

急いで移す理由は薄い、というのが僕の判断です。

cf migrateがcloudflare.config.tsへ移すもの

移行ガイドによると、cf migrateはWranglerの設定を読み、同じ場所にcloudflare.config.tsを書き出します。移るのはWorker名、アカウントID、互換性の日付とフラグ、エントリポイント、トリガー、環境変数、D1・Queue・Durable Object・サービスの各バインディングです。Wranglerのenvブロックはswitch (ctx.mode)の分岐になり、環境の切り替えも--envから--modeに変わります。

走らせる前に、未追跡ファイルも含めて変更をコミットかstashし、依存をインストールしておきます。Wranglerは4.136.0以上が条件です。--dry-runを付ければファイルを書かずに結果だけ見られて、公式の手順もここから始まります。

元のwrangler.jsoncは残りますが、cloudflare.config.tsができた時点でcfはWranglerの設定を読まなくなります。手元のWorker、いま挙げた設定だけで完結していますか? そうでなければ、次の表のどこかに引っかかります。

cf migrateが変換しない設定は、ビルドを止めてくれる

移行ガイドで「自動では移らない」とされているのは次の設定です。

設定
ガイド上の扱い
Durable Objectのmigrations
非対応。exportsのライフサイクル宣言に書き換える
D1のmigrations_dir、migrations_pattern、migrations_table
変換されない
Workflowのバインディング
変換されず、required項目として報告される
Containersの設定
変換されず、required項目として報告される
Viteでビルドする場合のbuild、minify、alias、upload_source_maps
移されず、vite.config.tsへ手で移す
Workers Sites(site)
非対応。Workers Static Assetsへ移す
preview_idなどのプレビュー用リソース
手作業で対応する

ここからがcf migrateのよくできているところです。生成されたcloudflare.config.tsには、未解決の箇所にTODO(@cloudflare)のコメントとthrow文が入ります。ガイドによれば、throwを消すまでcf devもcf buildもcf deployも「Migration incomplete」のエラーで止まります。変換漏れを抱えたまま本番へ出る道が、設計の段階でふさがれているわけです。

ガイドには、自動化されたエージェントはTODOを読み、未解決の選択はユーザーに尋ねるべきだ、という一文まであります。エージェントに任せる前提で書かれたCLIだと分かって、ここはマジで好感が持てました。

Workflowだけは事情が動いています。取りこぼしを報告したworkers-sdkのissue #15925に対し、修正のPRが10月1日にマージされました。手元のcfに届いているかはリリース次第なので、--dry-runの一覧にWorkflowが出るかで確かめるのが早いです。

裏を返すと、throwの1行を消せばビルドは通ります。止める仕組みをエージェントが自分で外せてしまうので、ここは指示で縛る場所だと僕は見ています。

wrangler.jsoncのコメントは、一覧に出ないまま消える

ここがいちばんの罠です。cloudflare/cfのissue #91(9月29日起票、執筆時点でオープン)によると、cf migrateはwrangler.jsoncのコメントをすべて捨てたうえで「Migration complete」と表示します。TODOにもthrowにもならないので、ビルドは普通に通ります。

報告者の本番設定は558行あり、そのうち403行がコメントでした。互換性フラグを入れた理由やレート制限の根拠といった、あとから読む人のためのメモが新しい設定に1行も移らなかった、という報告です。issueの受け入れ条件にはTOMLの#コメントも含まれているので、wrangler.toml派も他人事ではなさそうです。

元のwrangler.jsoncは残るので、その場でコメントが失われるわけではありません。危ないのは、移行が終わったと思って元ファイルを消したときです。元ファイルは書き換わらないため、git diffを見ても「コメントが消えた」差分としては現れません。

あなたのwrangler.jsonc、なぜそのフラグを入れたのかをコメントで残していませんか? 残しているなら、新しいcloudflare.config.tsと並べて見比べるまで、元ファイルは消さないでおくのが確実です。

Claude Codeにcf migrateを任せるなら、止める場所を指示に書く

エージェントに渡すときに縛りたいのは、throwを勝手に消させないことと、元の設定ファイルを残させることです。そこにコメントの引き継ぎ漏れを洗い出す手順を足すと、次のような指示になります。

このWorkerをWranglerからcfへ移行したい。指定した箇所では必ず止まること。

1. cf migrate --dry-run を実行し、出力をそのまま見せて止まる。--force は付けない
2. 私が了承したら cf migrate を実行する
3. TODO(@cloudflare) と [required] の項目を全件一覧にして止まる。throw 文は私の確認なしに消さない
4. wrangler.jsonc のコメントのうち、cloudflare.config.ts に引き継がれていないものを一覧にする
5. package.json の scripts と "type": "module"、.gitignore の .cloudflare/、tsconfig.json の .cloudflare/types を更新する
6. cf build と cf deploy --dry-run の結果を見せる。cf deploy は実行しない
7. wrangler.jsonc は削除しない

--forceは、gitの作業ツリーがクリーンかどうかの確認を飛ばすフラグなので、エージェントには使わせません。5番目は移行ガイドが移行後の作業として挙げている項目です。

デプロイの手前で止めているのは、cf auth loginがWranglerのログインとは別物だからでもあります。wrangler login済みでもcf側では改めてログインが要ります。CIのほうはCLOUDFLARE_API_TOKENとCLOUDFLARE_ACCOUNT_IDをcfも読むので、そのまま使えます。

いまエージェントに渡している指示、デプロイの手前で止まる書き方になっていますか?

cf CLIへの移行を見送ってよい案件

Wranglerとの対応表を見ると、今日のcfでは足りない場面がはっきりしています。次のどれかに当てはまるなら、待って損はありません。

  • wrangler tailでライブログを見るのが日課。cfはまだライブログを流せない
  • シークレットをwrangler secret putで1つずつ入れている。cfはまだ単体のシークレットを設定できない
  • WorkflowやContainersに乗っている。手作業の範囲が広い
  • esbuild前提のビルドや、Python・RustのWorker。移しても裏でWranglerが動く
  • wrangler.jsoncのコメントが設定の説明書になっている

どれにも当てはまらない小さなWorkerなら、cf migrate --dry-runを1回流して一覧を眺めるだけでも収穫があります。ファイルは書き換わりません。待つ側は、ベータ終了の告知と、issue #91とWorkflow修正の行方を追っておけば十分です。