# Durable Objects のマイグレーションタグ、exports 宣言方式でサヨナラだよ！

こんにちは、しぃちゃんだよ！今日は Cloudflare の Changelog で見つけた、Durable Objects まわりの地味だけど嬉しいアップデートを紹介するね。設定ファイルがちょっとスッキリするお話だよ！

## なにが発表されたの？

Cloudflare の Changelog で発表されたのは、Wrangler の設定ファイルに新しく追加された `exports` フィールド。Durable Object クラスのライフサイクル管理を、今までの命令型（imperative）の `migrations` 配列に代わって、宣言型（declarative）で行えるようになったんだって。

Worker が公開している Durable Object クラスをそれぞれ宣言しておくと、Cloudflare がその内容とすでにデプロイ済みの状態を比較して、どのクラスを作成・改名・削除すればいいかを自動で判断してくれる仕組みなの。

## 今までどうだったの？

これまで Durable Object クラスのライフサイクルを管理するには、`migrations` 配列に、`tag` を振った手順を順番に積み重ねていく必要があったの。

例えば `ChatRoom` というクラス名を `Room` に変えたいときは、こんな感じで 2 つのタグ付きステップを両方とも残しておかないといけなかったんだって。

```json
{
  "migrations": [
    { "tag": "v1", "new_sqlite_classes": ["ChatRoom"] },
    {
      "tag": "v2",
      "renamed_classes": [{ "from": "ChatRoom", "to": "Room" }]
    }
  ]
}
```

`v1`、`v2`、`v3` ……と履歴のチェーンをずっと維持していく必要があって、設定ファイルがどんどん長く、追いづらくなっていくのが悩みどころだったの。

## これで何が変わるの？

`exports` を使うと、履歴チェーンを積み上げるんじゃなくて、**今の状態だけ**を宣言すればよくなるよ。さっきの改名の例なら、こう書けるの。

```json
{
  "exports": {
    "ChatRoom": {
      "type": "durable-object",
      "state": "renamed",
      "renamed_to": "Room"
    },
    "Room": { "type": "durable-object", "storage": "sqlite" }
  }
}
```

`exports` マップが唯一の正解（source of truth）になるから、`v1` や `v2` みたいな古いタグをずっと引きずらなくてよくなるの。しかも Wrangler がデプロイのたびに、どのクラスを作成・更新・削除・改名・転送したかを構造化された形で報告してくれるから、今どういう変更が起きたのか一目で分かりやすくなるんだって。

## 深く潜ってみよう

`exports` の各エントリはクラス名がキーになっていて、`state` フィールドでライフサイクルの状態を表すよ。

- `created`（デフォルト）: 今動いている現役のクラス
- `deleted`: 削除された（トゥームストーンになった）クラス
- `renamed`: 別のクラス名に改名されたクラス
- `transferred`: 別の Worker に転送されたクラス
- `expecting-transfer`: クロス Worker の転送を受け取る側の状態

改名や削除、転送といった「もう使われていない」状態がソースコード上のクラスと共存できるのがポイントで、ロールアウトの途中でランタイムエラーが起きるのを避けながら、ダウンタイムゼロで改名・転送ができる設計になっているの。

さらに安全機能もあって、あるクラスを削除・改名しようとすると、Cloudflare がそのアカウント内で同じネームスペースをまだ参照している他の Worker をすべて洗い出してくれるんだって。うっかり参照が残ったままの Worker を壊しちゃう、みたいな事故を防げるのはありがたいね。

なお、既存の `migrations` 配列を使っている Worker はそのまま動き続けるから、慌てて移行する必要はないよ。`exports` に切り替えたいときのために公式の移行ガイドも用意されているみたい。ただし `exports` と `migrations` は同じ Worker の中では併用できない（相互排他的）ので、そこだけ注意だね。

## まとめ

- Durable Object クラスのライフサイクル管理が、命令型の `migrations` 配列から宣言型の `exports` フィールドに進化したよ
- タグの履歴チェーンを積み上げなくてよくなって、`exports` マップが唯一の情報源になる
- `state` は `created` / `deleted` / `renamed` / `transferred` / `expecting-transfer` の 5 種類
- 改名・転送はダウンタイムゼロで実施でき、参照が残っている他の Worker も自動で洗い出してくれる
- 既存の `migrations` はそのまま動作し続け、移行は任意。ただし `exports` と `migrations` の併用はできない

Durable Objects を使っていて、クラスの改名やマイグレーション管理が面倒だなって感じていた開発者さんに、ぜひ試してほしいアップデートだよ！
