Wrangler 配置文件 中的 exports 字段是管理 Durable Object 类 生命周期的声明式方式。您声明 Worker 导出的每个 Durable Object 类——及其是 live、deleted、renamed 还是 transferred——Cloudflare 会将您的声明与已为 Worker 配置的 namespace 进行协调。
本页涵盖如何:
- 创建 新的 Durable Object 类。
- 删除 Durable Object 类及其数据。
- 重命名 Durable Object 类。
- 在 Worker 之间转移 Durable Object 类。
当您部署声明 exports 的 Worker 时,Cloudflare 比较三个真实来源:
- 您的代码 — Worker 实际导出的 Durable Object 类集合。
- 您的
exports配置 — 您对每个类的声明。 - 已配置状态 — 此 Worker 已存在的 Durable Object namespace。
仅出现在代码中的类在 exports 中声明之前会被忽略;Cloudflare 不会隐式配置 namespace。其他不一致(例如 live 条目缺少代码中的类,或已配置 namespace 无匹配条目)会作为结构化错误显示,或在意图明确时由 Cloudflare 自动应用操作。
一个最小的 exports 块将每个 Durable Object 类声明为一个活动 (live) 条目:
{
"durable_objects": {
"bindings": [
{
"name": "MY_DURABLE_OBJECT",
"class_name": "MyDurableObject",
},
],
},
"exports": {
"MyDurableObject": {
"type": "durable-object",
"storage": "sqlite",
},
},
}[[durable_objects.bindings]]
name = "MY_DURABLE_OBJECT"
class_name = "MyDurableObject"
[exports.MyDurableObject]
type = "durable-object"
storage = "sqlite"要声明破坏性操作(删除、重命名或转移类),您需要将条目的 state 更改为墓碑 (tombstone) 变体。类名保持不变;该值告诉 Cloudflare 如何处理现有的命名空间。
| 操作 | state |
必需字段 |
|---|---|---|
| 定义新类(默认值) | "created" (或省略) |
storage |
| 删除类 | "deleted" |
(无) |
| 重命名类 | "renamed" |
renamed_to |
| 将类转移到另一个 Worker | "transferred" |
transferred_to |
| 接收来自另一个 Worker 的转移 | "expecting-transfer" |
storage, transfer_from |
本页的其余部分将详细介绍每种操作,并提供了完整架构的 exports 配置参考链接。
要定义新的 Durable Object 类,请在 exports 中添加一个以该类名为键的条目,并将 storage 设置为 "sqlite"。
-
将该类添加到您的 Worker 代码中并将其导出:
src/index.tsts import { DurableObject } from "cloudflare:workers"; export class MyDurableObject extends DurableObject { // ... } -
为该类添加绑定(如果您的 Worker 需要通过
env访问它)并在exports中声明该类:{ "durable_objects": { "bindings": [ { "name": "MY_DURABLE_OBJECT", "class_name": "MyDurableObject" } ] }, "exports": { "MyDurableObject": { "type": "durable-object", "storage": "sqlite" } } }[[durable_objects.bindings]] name = "MY_DURABLE_OBJECT" class_name = "MyDurableObject" [exports.MyDurableObject] type = "durable-object" storage = "sqlite" -
部署 Worker:
npx wrangler deploy
在您首次部署时,Cloudflare 会为该类预配命名空间。在后续使用相同条目进行的部署中,不会对命名空间进行任何更改——该条目仅确认该类仍然处于活动 (live) 状态。
使用 deleted 墓碑 (tombstone) 替换活动 (live) 条目以停用 Durable Object 类。删除类会永久删除其命名空间及其所有存储的数据——这不是软删除。
-
从您的 Worker 代码中移除该类。
-
从
durable_objects.bindings中移除该类的绑定。 -
将该类在
exports中的条目更改为deleted墓碑 (tombstone):{ "exports": { "OldDurableObject": { "type": "durable-object", "state": "deleted" } } }[exports.OldDurableObject] type = "durable-object" state = "deleted" -
部署 Worker:
npx wrangler deploy
在部署时,deleted 墓碑 (tombstone) 强制满足两个先决条件:
- 类不能存在于您的 Worker 代码中。Cloudflare 不会删除其类仍在随代码交付的命名空间,因为运行时绑定会解析到已删除的命名空间。
- 您账户中的其他 Worker 都不能绑定到该命名空间。如果另一个 Worker 仍然绑定到该类,部署将被拒绝,并显示
tombstone_delete_blocked_by_external_bindings错误,同时返回引用脚本的列表。请先重新部署这些不带绑定的 Worker,然后重新运行部署。
一旦命名空间被删除,墓碑 (tombstone) 就会失效。Cloudflare 会在协调 (reconciliation) 输出中对此进行报告,并在 removable_entries 中列出该条目,以便您可以安全地将其从 exports 中移除。
重命名 Durable Object 类会将存储的数据在同一个 Worker 内从一个类移至另一个类。重命名需要:
- 一个以旧类名为键的
renamed墓碑 (tombstone),其renamed_to指向新类名。 - 在同一个
exports映射中为新类名提供一个活动 (live) 条目(以便数据有目的地)。
对于旧类不再存在于代码中的全新部署,只需一次部署即可:
{
"exports": {
"OldName": {
"type": "durable-object",
"state": "renamed",
"renamed_to": "NewName"
},
"NewName": {
"type": "durable-object",
"storage": "sqlite"
}
}
}[exports.OldName]
type = "durable-object"
state = "renamed"
renamed_to = "NewName"
[exports.NewName]
type = "durable-object"
storage = "sqlite"在重命名生效后,命名空间的类名将更新为 NewName,并且引用新类名的运行时绑定将解析为相同的数据。
重命名 Durable Object 类涉及两处更新,这两处更新在运行时层并非完全原子化:命名空间的类指针和导出该类的 Worker 代码。在部署逐步发布期间,其中一个更新可能会比另一个提前几秒钟可见。为了避免在此窗口期间出现运行时错误,请使用三次部署重命名流程:
-
将新名称别名化为旧类。 将新类名作为规范类添加到代码中,并以旧名称重新导出它,以便现有实例能够继续解析:
src/index.tsts import { DurableObject } from "cloudflare:workers"; export class NewName extends DurableObject { // ... } export { NewName as OldName };保持
exports不变。执行部署。 -
在别名仍保留时应用重命名。 更新
exports以添加renamed墓碑 (tombstone) 和新的活动 (live) 条目:{ "exports": { "OldName": { "type": "durable-object", "state": "renamed", "renamed_to": "NewName" }, "NewName": { "type": "durable-object", "storage": "sqlite" } } }[exports.OldName] type = "durable-object" state = "renamed" renamed_to = "NewName" [exports.NewName] type = "durable-object" storage = "sqlite"执行部署。Cloudflare 将应用重命名并显示
tombstone_class_still_in_code信息通知——这是符合预期的,并证实了这种安全的发布模式。 -
移除别名。 上一次部署完全发布后,从代码中移除
OldName别名:src/index.tsts import { DurableObject } from "cloudflare:workers"; export class NewName extends DurableObject { // ... }保持
exports不变。执行部署。OldName墓碑 (tombstone) 现在已失效,Cloudflare 将其列在removable_entries中——您可以在下一次修改配置时将该条目从exports中删除。
renamed_to 目标必须满足以下条件:
- 必须是有效的 JavaScript 标识符,且与源类名不同。
- 在同一个
exports映射中显示为活动 (live) 条目(state: "created"或省略)。如果renamed_to的值命名了另一个墓碑或完全缺失,Cloudflare 将予以拒绝。 - 不能与此 Worker 上同名的现有命名空间发生冲突。如果目标名称下已存在命名空间,请先在之前的部署中通过其自身的
deleted墓碑 (tombstone) 将其删除。
转移 (Transferring) 会将现有的 Durable Object 命名空间从同一个账户中的一个 Worker(源)移至另一个 Worker(目标)。由于需要两个 Worker 进行协调,因此转移是一个多次部署流程。
目标 Worker 声明一个命名源 Worker 的 expecting-transfer 条目。源 Worker 声明一个命名目标 Worker 的 transferred 墓碑 (tombstone)。当源 Worker 的部署完成时,将提交实际的交接。
推荐的流程包含四次部署:
-
源 Worker——初始状态。 源将
MyDO声明为活动 (live) 类。其他什么都还没变。{ "exports": { "MyDO": { "type": "durable-object", "storage": "sqlite" } } }[exports.MyDO] type = "durable-object" storage = "sqlite" -
目标 Worker——接收转移。 目标将
MyDO添加到其代码中,并声明一个命名源 Worker 的expecting-transfer条目。此时不要在目标上为MyDO添加durable_objects.bindings条目——在此阶段,Cloudflare 不会通过源的命名空间来路由自引用绑定。{ "exports": { "MyDO": { "type": "durable-object", "state": "expecting-transfer", "storage": "sqlite", "transfer_from": "source-worker" } } }[exports.MyDO] type = "durable-object" state = "expecting-transfer" storage = "sqlite" transfer_from = "source-worker"部署目标。Cloudflare 会记录一个待处理的转移,并在协调 (reconciliation) 输出中发出
Transfer pending通知。 -
源 Worker——提交转移。 将源的
MyDO条目更改为命名目标 Worker 的transferred墓碑 (tombstone)。暂时将该类保留在源头代码中:{ "exports": { "MyDO": { "type": "durable-object", "state": "transferred", "transferred_to": "target-worker" } } }[exports.MyDO] type = "durable-object" state = "transferred" transferred_to = "target-worker"部署源。Cloudflare 会匹配待处理的转移,并自动将命名空间重新分配给目标 Worker。协调 (reconciliation) 输出会报告
Transferred (committed): MyDO → target-worker。如果在提交转移后源 Worker 仍需要访问
MyDO,请更新其durable_objects.bindings条目,使其通过script_name指向目标 Worker:{ "durable_objects": { "bindings": [ { "name": "MY_DURABLE_OBJECT", "class_name": "MyDO", "script_name": "target-worker" } ] } }[[durable_objects.bindings]] name = "MY_DURABLE_OBJECT" class_name = "MyDO" script_name = "target-worker"如果源 Worker 不再需要访问
MyDO,请在从源 Worker 的代码中移除MyDO时一并移除该绑定。 -
目标 Worker——绑定类。 一旦源的部署完全发布,请使用针对
MyDO的durable_objects.bindings条目重新部署目标。此时,该绑定将解析为目标 Worker 上的命名空间。{ "durable_objects": { "bindings": [ { "name": "MY_DURABLE_OBJECT", "class_name": "MyDO" } ] }, "exports": { "MyDO": { "type": "durable-object", "storage": "sqlite" } } }[[durable_objects.bindings]] name = "MY_DURABLE_OBJECT" class_name = "MyDO" [exports.MyDO] type = "durable-object" storage = "sqlite"
在交接在所有地方都发布完毕后,您可以从源 Worker 的代码中移除 MyDO,并从源的 exports 映射中删除 transferred 墓碑 (tombstone)。如果该账户中的其他 Worker 仍绑定到源上的 MyDO,协调 (reconciliation) 输出会将其列在 referencing_scripts 中;在移除源墓碑 (tombstone) 之前,请重新部署这些 Worker,并将其绑定重新指向目标。
待处理的转移会一直存在,直到源 Worker 提交包含 transferred 墓碑 (tombstone) 的部署,或者目标 Worker 通过移除 expecting-transfer 条目来取消它。要取消转移,请重新部署不包含该条目的目标(或将其替换为正常的活动 (live) 条目)。Cloudflare 会删除待处理记录,且源 Worker 将保留其命名空间。
- 两个 Worker 必须位于同一个 Cloudflare 账户中。
- 不支持跨 dispatch-namespace 的转移。源 Worker 和目标 Worker 必须处于相同的 dispatch-namespace 上下文中(或两者都不在任何 dispatch-namespace 中)。
- 目标 Worker 每次只能为每个类保留一个待处理的阶段 1 (phase-1) 提示。要将待处理的转移重定向到不同的源,请先取消当前待处理的转移。
活动 (live) 条目(state: "created" 和 state: "expecting-transfer")必须声明 storage 值:
"sqlite"选择 SQLite 存储后端。这是推荐的且针对新命名空间的唯一路径。基于 SQLite 的命名空间支持 SQL、时间点恢复 (Point-in-Time Recovery) 以及更高的单个对象存储限制。"legacy-kv"选择键值 (key-value) 存储后端。Cloudflare 仅接受此值用于已预配了键值存储的命名空间(通常是那些在 SQLite 成为默认后端之前,使用旧版migrations数组启动的 Worker)。您无法通过exports创建新的基于键值存储的命名空间。
一旦命名空间存在,存储类型就不可更改。如果 exports 更改将已预配的命名空间从 sqlite 切换到 legacy-kv(或反之),Cloudflare 将拒绝该更改并显示 storage_type_mismatch 错误。要真正更改存储后端,必须先通过 deleted 墓碑 (tombstone) 删除命名空间,然后在新后端下重新预配(在此期间数据会完全丢失)。
当部署应用 Durable Object 类生命周期更改时,wrangler deploy 将打印 Durable Object exports reconciliation 块。当协调 (reconciliation) 产生警告、信息通知或可移除条目时,该块也会出现。当没有任何变化且没有通知时,Wrangler 会省略此块。
典型的输出如下所示:
Durable Object exports reconciliation:
Created: ChatRoom
Renamed: OldRoom → ChatRoom
Transferred (committed): Widget → target-worker
Transfer pending: Incoming ← source-worker
Info:
[tombstone_class_still_in_code] OldRoom: Tombstone of type 'renamed' applied. Class 'OldRoom' is still exported in code; this is the supported pattern for zero-downtime rename rollouts.
[stale_tombstone] OldGone: Tombstone of type 'deleted' for class 'OldGone' has no effect (no namespace exists with this class name). Safe to remove from `exports`.
Safe to remove from `exports`: OldGone该输出块有四个部分:
- 操作行 (Action lines) (
Created,Updated,Deleted,Renamed,Transferred,Transfer pending) 报告 Cloudflare 在此部署期间应用的更改。 - 警告 (Warnings)(黄色)标记应进行调查但不妨碍部署的情况。警告方案集保留供将来使用;当前的 Cloudflare 部署不会发出它们。
- 信息 (Info)(置灰)报告非阻塞通知:不再适用的失效墓碑 (tombstone),以及在源类仍在代码中时应用的墓碑(支持零停机时间发布的推荐模式)。
- 可以安全地从
exports中移除 (Safe to remove fromexports) 列出了已失效且账户中没有其他 Worker 绑定到源类的墓碑 (tombstone) 条目。您可以在下一次修改配置时从exports映射中删除这些条目。
信息条目可以包含 referencing_scripts 列表——账户中其绑定仍然解析为受影响命名空间的其他 Worker。在移除墓碑 (tombstone) 之前,请重新部署这些 Worker,并将绑定重新指向新类名,否则它们的绑定将被遗孤 (orphan)。
If the deploy fails, the output shows a structured error per class:
✘ [orphaned_provisioned_namespace] class 'Bar': A namespace exists for 'Bar' but no `exports` entry declares it.
Suggestion: add an `exports` entry for 'Bar', or add a `deleted` tombstone to remove the namespace.
Referencing scripts: worker-foo, worker-bar单次部署中的所有类级别错误都将统一报告,以便您一次性解决。有关所有错误场景的完整列表,请参阅错误参考。
当应用墓碑 (tombstone) 不产生状态更改时,它就会变得失效 (stale)——例如,针对其命名空间已被移除的类的 deleted 墓碑,或者重命名已经生效后的 renamed 墓碑。
在每次存在失效墓碑的部署中,Cloudflare 都会发出 stale_tombstone 信息通知,直到您从 exports 中移除该条目。该通知会故意重复出现,以免您忘记清理。
对于重命名和已转移的墓碑 (tombstone),Cloudflare 还会列出您账户中的其他 Worker,它们的 durable_objects.bindings 条目仍然引用源类名。这些会作为 referencing_scripts 显示在信息通知上。当 referencing_scripts 不为空时,移除墓碑可能会使这些绑定遗孤——请先重新部署引用的 Worker,将其绑定重新指向新类。
协调 (reconciliation) 输出中顶层的“Safe to remove from exports”行会命名每个 referencing_scripts 为空的失效墓碑 (tombstone)。请将该列表作为“您现在可以删除这些”的权威提示。
可以在 Wrangler 配置文件顶层指定 exports,并针对每个环境 (environment) 进行重写:
{
// top-level exports apply to the default environment
"exports": {
"MyDO": { "type": "durable-object", "storage": "sqlite" }
},
"env": {
"staging": {
// override for the staging environment
"exports": {
"MyDO": { "type": "durable-object", "storage": "sqlite" }
}
}
}
}[exports.MyDO]
type = "durable-object"
storage = "sqlite"
[env.staging.exports.MyDO]
type = "durable-object"
storage = "sqlite"如果仅在顶层声明了 exports,则命名的环境会继承相同的值。每个环境维护自己预配的命名空间,因此墓碑 (tombstone) 仅在声明它们的环境中生效。
预览部署 (Preview deployments) 和分发命名空间 (dispatch namespaces) 遵循相同的规则。不支持跨分发命名空间的转移——在 transferred / expecting-transfer 配对中的源 Worker 和目标 Worker 必须同时存在于相同的分发命名空间上下文中(或同时在任何分发命名空间之外)。
exports 字段是一个以 Durable Object 类名为键的映射。每个值都是一个对象,其字段取决于 state:
typestringrequired- 对于 Durable Object 类条目,请将其设置为
"durable-object"。
- 对于 Durable Object 类条目,请将其设置为
statestringoptional- 生命周期状态。为以下值之一:
"created"(默认值,若要使用可省略)、"deleted"、"renamed"、"transferred"或"expecting-transfer"。
- 生命周期状态。为以下值之一:
storagestringconditional- 当
state为"created"或"expecting-transfer"时必填。为以下值之一:"sqlite"(推荐,新命名空间的唯一有效值)或"legacy-kv"(仅用于现有的基于键值存储的命名空间)。在墓碑 (tombstone) 状态下禁用。
- 当
renamed_tostringconditional- 当
state为"renamed"时必填。目标类名。必须是有效的 JavaScript 标识符,与源类名不同,并且在同一个exports映射中作为活动 (live) 条目出现。
- 当
transferred_tostringconditional- 当
state为"transferred"时必填。将接收命名空间的目标 Worker 的名称。
- 当
transfer_fromstringconditional- 当
state为"expecting-transfer"时必填。命名空间所转移自的源 Worker 的名称。
- 当
下表列出了每个 state 允许和禁用的字段:
state |
必需 | 禁用 |
|---|---|---|
"created" (默认) |
storage |
renamed_to, transferred_to, transfer_from |
"deleted" |
(无) | storage, renamed_to, transferred_to, transfer_from |
"renamed" |
renamed_to |
storage, transferred_to, transfer_from |
"transferred" |
transferred_to |
storage, renamed_to, transfer_from |
"expecting-transfer" |
storage, transfer_from |
renamed_to, transferred_to |
当部署未能通过协调 (reconciliation) 时,Cloudflare 将为每个类返回一个错误,并附带结构化的 scenario 标签、人类可读的消息,以及(在适用时)suggestion(建议)和 referencing_scripts 列表:
| 场景 (Scenario) | 含义 | 如何修复 |
|---|---|---|
provisioned_class_missing_from_config |
某个类存在已预配的命名空间,且 Worker 代码仍在导出该类,但 exports 中没有该类的条目。 |
添加一个活动 (live) 条目(state: "created")以保留该命名空间,或者添加一个墓碑 (tombstone)(deleted、renamed 或 transferred)以停用它。 |
config_export_not_in_code |
活动 (live) 条目声明了 Worker 代码未导出的类。 | 将该类添加到您的代码中,或者用墓碑 (tombstone) 替换该条目。 |
config_references_nonexistent_class |
活动 (live) 条目声明了一个既不在代码中也未预配的类。 | 移除该条目,或者将该类添加到您的 Worker 代码中。 |
orphaned_provisioned_namespace |
某个类存在已预配的命名空间,但该类既不在代码中也没有被声明。 | 为该类添加一个墓碑 (tombstone),或者将该类重新添加至代码和 exports 中。 |
invalid_export |
exports 条目的结构无效——例如,为新命名空间请求 legacy-kv,或者一个类映射到多个已预配的命名空间。 |
纠正该条目:对于新命名空间使用 "storage": "sqlite",或者使用 deleted 或 renamed 墓碑 (tombstone) 解决重复问题。 |
tombstone_delete_class_still_in_code |
deleted 墓碑 (tombstone) 命名的类仍在代码中被导出。 |
先从代码中移除该类,然后再部署墓碑 (tombstone)。 |
tombstone_delete_blocked_by_external_bindings |
账户中的另一个 Worker 绑定到了正在被删除的命名空间。 | 重新部署不带该绑定的引用 Worker,然后重新运行您的部署。 |
tombstone_renamed_to_occupied |
renamed_to 目标与同名的现有命名空间冲突。 |
在先前的部署中,通过该冲突命名空间自身的 deleted 墓碑 (tombstone) 将其删除。 |
transferred_pending_not_found |
transferred 墓碑 (tombstone) 在目标 Worker 上没有匹配的 expecting-transfer 条目。 |
先部署目标 Worker,并声明命名该源 Worker 的 expecting-transfer 条目。 |
transferred_target_missing |
由 transferred_to 命名的目标 Worker 不再存在。 |
将 transferred_to 更新为有效的目标,或者移除该墓碑 (tombstone)。 |
transferred_target_mismatch |
transferred_to 的值与待处理转移记录的目标不匹配。 |
将 transferred_to 设置为待处理转移的目标,或者让目标在重定向之前取消其 expecting-transfer 条目。 |
transferred_source_in_dispatch_namespace |
声明 transferred 墓碑 (tombstone) 的源 Worker 处于分发命名空间 (dispatch namespace) 中;不支持跨分发命名空间转移。 |
在单个分发命名空间上下文中执行转移。 |
transferred_target_in_dispatch_namespace |
transferred 墓碑 (tombstone) 的目标处于分发命名空间 (dispatch namespace) 中;不支持跨分发命名空间转移。 |
让目标重新部署且不包含 expecting-transfer 以取消待处理的转移,或者让两个 Worker 保持在相同的上下文中。 |
phase_one_transfer_after_commit_mismatch |
目标的命名空间转移自与声明不符的源。 | 移除 expecting-transfer 条目——在提交后,转移无法被重定向。 |
phase_one_transfer_target_class_provisioned |
目标 Worker 已经拥有该类的命名空间。 | 用正常的活动 (live) 条目替换 expecting-transfer 条目,或者先删除现有的命名空间。 |
phase_one_transfer_duplicate |
针对相同类的另一个 expecting-transfer 提示已经在进行中。 |
先通过移除或替换其条目来取消现有的待处理转移。 |
phase_one_transfer_source_missing |
由 transfer_from 命名的源 Worker 不存在于该账户中。 |
纠正源 Worker 的名称。 |
phase_one_transfer_source_namespace_missing |
源 Worker 没有该类的命名空间。 | 确保在目标声明 expecting-transfer 之前,源 Worker 已经部署了该类。 |
phase_one_transfer_source_in_dispatch_namespace |
源 Worker 处于分发命名空间 (dispatch namespace) 中;不支持跨分发命名空间转移。 | 将转移移至单个分发命名空间上下文中进行。 |
phase_one_transfer_target_in_dispatch_namespace |
目标 Worker 处于分发命名空间 (dispatch namespace) 中;不支持跨分发命名空间转移。 | 将转移移至单个分发命名空间上下文中进行。 |
storage_type_mismatch |
声明的 storage 值与预配命名空间的存储后端不匹配。 |
存储后端无法就地更改。如果您确实需要切换,请删除该命名空间并在新后端下重新预配。 |
free_tier_requires_sqlite |
账户的计划仅支持基于 SQLite 的命名空间,但该条目请求了 legacy-kv。 |
使用 "storage": "sqlite"。 |
exports和migrations互斥。 包含这两个字段的 Worker 配置将在验证时被拒绝。一旦使用exports部署了 Worker,后续部署必须继续使用exports(或者两者都不使用,这会针对空配置进行协调,通常是一个错误)。wrangler versions upload不会应用生命周期更改。 就像旧版migrations数组一样,Durable Object 生命周期更改只能通过wrangler deploy应用。如果您的 Wrangler 配置包含exports条目,wrangler versions upload会快速失败并报错。请参阅部署管理 - Durable Object 迁移。exports不支持渐进式部署。 生命周期更改在 Cloudflare 控制平面是原子性的,无法渐进式地推出。请参阅具有 Durable Objects 的渐进式部署 - Durable Object 类生命周期更改。- 回滚无法跨越生命周期更改。 您无法回滚到在由
exports驱动的生命周期更改之前部署的版本。请参阅回滚 - 绑定。 - 存储后端一旦预配即不可变。 您不能就地更改命名空间的
storage值;请进行删除并重新预配。
使用 migrations 数组的现有 Worker 可以转而使用 exports,无需进行任何数据迁移。已预配的命名空间将保持原样;仅配置的形式发生变化。
要确定类现有的存储后端,请追溯到最初创建该类的迁移。通过 new_sqlite_classes 引入的类使用 sqlite,而通过 new_classes 引入的类使用 legacy-kv。
- 确定您的 Worker 当前导出的活动 (live) Durable Object 类。每个具有活动命名空间的类都会成为一个活动的
exports条目。 - 将
migrations数组替换为exports映射。对于每个现有类,添加一个以该类名为键的条目,且包含"type": "durable-object"。使用"storage": "sqlite"或"storage": "legacy-kv"与现有的存储后端相匹配。 - 从配置中移除
migrations数组。 - 部署。
对比来看,典型 migrations 历史记录的等价转换是:
{
"migrations": [
{ "tag": "v1", "new_sqlite_classes": ["ChatRoom"] }
]
}[[migrations]]
tag = "v1"
new_sqlite_classes = [ "ChatRoom" ]{
"exports": {
"ChatRoom": { "type": "durable-object", "storage": "sqlite" }
}
}[exports.ChatRoom]
type = "durable-object"
storage = "sqlite"未来的生命周期更改(删除、重命名、转移)完全通过 exports 进行——没有与 tag 字段等价的项,也无需保留历史条目。exports 映射的当前状态就是唯一真实来源。