From 01b80f1d670e54eadd13337f3e2674e33805ff80 Mon Sep 17 00:00:00 2001 From: emily-shen <69125074+emily-shen@users.noreply.github.com> Date: Thu, 27 Mar 2025 11:14:15 +0000 Subject: [PATCH 01/14] pass name to getplatformproxy --- .../src/api/integrations/platform/index.ts | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/wrangler/src/api/integrations/platform/index.ts b/packages/wrangler/src/api/integrations/platform/index.ts index 8a1cc9e91e59..cb898e88a3e4 100644 --- a/packages/wrangler/src/api/integrations/platform/index.ts +++ b/packages/wrangler/src/api/integrations/platform/index.ts @@ -1,6 +1,6 @@ import { kCurrentWorker, Miniflare } from "miniflare"; import { getAssetsOptions } from "../../../assets"; -import { readConfig } from "../../../config"; +import { formatConfigSnippet, readConfig } from "../../../config"; import { DEFAULT_MODULE_RULES } from "../../../deployment-bundle/rules"; import { getBindings } from "../../../dev"; import { getBoundRegisteredWorkers } from "../../../dev-registry"; @@ -12,6 +12,8 @@ import { } from "../../../dev/miniflare"; import { run } from "../../../experimental-flags"; import { getLegacyAssetPaths, getSiteAssetPaths } from "../../../sites"; +import { logger } from "../../../logger"; +import { dedent } from "../../../utils/dedent"; import { CacheStorage } from "./caches"; import { ExecutionContext } from "./executionContext"; import { getServiceBindings } from "./services"; @@ -113,6 +115,7 @@ export async function getPlatformProxy< const mf = new Miniflare({ script: "", modules: true, + name: "worker", ...(miniflareOptions as Record), }); @@ -137,6 +140,18 @@ async function getMiniflareOptionsFromConfig( ): Promise> { const bindings = getBindings(rawConfig, env, true, {}); + if (bindings.durable_objects) { + logger.warn(dedent` + You have defined an internal Durable Object (ie the binding does not have a script_name field). + You will not be able to develop it locally, but it should work in production. + + Alternatively, you can define your DO "externally" in another worker. + To do this, create another Worker + Wrangler config file. Export your DO from there. + Then, set the script_name field in your original DO binding to equal the name field from your new external DO config. + You will be able to develop this locally by running: + npx wrangler dev -c path/to/original/wrangler.toml -c path/to/external-do/wrangler.toml + `); + } const workerDefinitions = await getBoundRegisteredWorkers({ name: rawConfig.name, services: bindings.services, @@ -144,7 +159,7 @@ async function getMiniflareOptionsFromConfig( }); const { bindingOptions, externalWorkers } = buildMiniflareBindingOptions({ - name: undefined, + name: rawConfig.name, bindings, workerDefinitions, queueConsumers: undefined, @@ -163,6 +178,7 @@ async function getMiniflareOptionsFromConfig( { script: "", modules: true, + name: rawConfig.name, ...bindingOptions, serviceBindings: { ...serviceBindings, From e9eb25d58479f5e9fe9ac4fe7dbec31440bb26d6 Mon Sep 17 00:00:00 2001 From: emily-shen <69125074+emily-shen@users.noreply.github.com> Date: Thu, 27 Mar 2025 11:15:36 +0000 Subject: [PATCH 02/14] fixup --- packages/wrangler/src/api/integrations/platform/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/wrangler/src/api/integrations/platform/index.ts b/packages/wrangler/src/api/integrations/platform/index.ts index cb898e88a3e4..694a13b21e14 100644 --- a/packages/wrangler/src/api/integrations/platform/index.ts +++ b/packages/wrangler/src/api/integrations/platform/index.ts @@ -115,7 +115,6 @@ export async function getPlatformProxy< const mf = new Miniflare({ script: "", modules: true, - name: "worker", ...(miniflareOptions as Record), }); From 9f2d088e55f48ab54f17ca762dd638abcb4b75b7 Mon Sep 17 00:00:00 2001 From: emily-shen <69125074+emily-shen@users.noreply.github.com> Date: Thu, 27 Mar 2025 14:01:03 +0000 Subject: [PATCH 03/14] remove out of date warning --- packages/wrangler/src/__tests__/dev.test.ts | 9 --------- packages/wrangler/src/deployment-bundle/entry.ts | 12 +----------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/packages/wrangler/src/__tests__/dev.test.ts b/packages/wrangler/src/__tests__/dev.test.ts index 150b186b6bf4..0a6c00b7f81c 100644 --- a/packages/wrangler/src/__tests__/dev.test.ts +++ b/packages/wrangler/src/__tests__/dev.test.ts @@ -1288,15 +1288,6 @@ describe.sequential("wrangler dev", () => { https://developers.cloudflare.com/durable-objects/reference/durable-objects-migrations/ for more details. - - ▲ [WARNING] WARNING: You have Durable Object bindings that are not defined locally in the worker being developed. - - Be aware that changes to the data stored in these Durable Objects will be permanent and affect the - live instances. - Remote Durable Objects that are affected: - - {\\"name\\":\\"NAME_2\\",\\"class_name\\":\\"CLASS_2\\",\\"script_name\\":\\"SCRIPT_A\\"} - - {\\"name\\":\\"NAME_4\\",\\"class_name\\":\\"CLASS_4\\",\\"script_name\\":\\"SCRIPT_B\\"} - " `); }); diff --git a/packages/wrangler/src/deployment-bundle/entry.ts b/packages/wrangler/src/deployment-bundle/entry.ts index 9969ce93cdab..5ab40cc364c7 100644 --- a/packages/wrangler/src/deployment-bundle/entry.ts +++ b/packages/wrangler/src/deployment-bundle/entry.ts @@ -138,17 +138,7 @@ export async function getEntry( config.tsconfig ); - const { localBindings, remoteBindings } = - partitionDurableObjectBindings(config); - - if (command === "dev" && remoteBindings.length > 0) { - logger.warn( - "WARNING: You have Durable Object bindings that are not defined locally in the worker being developed.\n" + - "Be aware that changes to the data stored in these Durable Objects will be permanent and affect the live instances.\n" + - "Remote Durable Objects that are affected:\n" + - remoteBindings.map((b) => `- ${JSON.stringify(b)}`).join("\n") - ); - } + const { localBindings } = partitionDurableObjectBindings(config); if (format === "service-worker" && localBindings.length > 0) { const errorMessage = From 157a9b5f1f978e68b4c59afa85ca1c12ef0f2e4f Mon Sep 17 00:00:00 2001 From: emily-shen <69125074+emily-shen@users.noreply.github.com> Date: Thu, 27 Mar 2025 14:01:17 +0000 Subject: [PATCH 04/14] stop gpp crashing with internal DOs --- .../tests/get-platform-proxy.env.test.ts | 59 ++++++++++++++++++- .../wrangler_external_do.jsonc | 20 +++++++ .../wrangler_internal_do.jsonc | 19 ++++++ .../src/api/integrations/platform/index.ts | 31 ++++++---- .../wrangler/src/deployment-bundle/entry.ts | 3 +- 5 files changed, 117 insertions(+), 15 deletions(-) create mode 100644 fixtures/get-platform-proxy/wrangler_external_do.jsonc create mode 100644 fixtures/get-platform-proxy/wrangler_internal_do.jsonc diff --git a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts index 4fb22fb13e35..beb5ff60b3cc 100644 --- a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts +++ b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts @@ -1,6 +1,14 @@ import path from "path"; import { D1Database, R2Bucket } from "@cloudflare/workers-types"; -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { + afterEach, + beforeEach, + describe, + expect, + it, + MockInstance, + vi, +} from "vitest"; import { getPlatformProxy } from "./shared"; import type { Hyperdrive, KVNamespace } from "@cloudflare/workers-types"; import type { Unstable_DevWorker } from "wrangler"; @@ -197,6 +205,55 @@ describe("getPlatformProxy - env", () => { } }); + describe("DO warnings", () => { + let warn = {} as MockInstance; + beforeEach(() => { + warn = vi.spyOn(console, "warn").mockImplementation(() => {}); + }); + afterEach(() => { + warn.mockRestore(); + }); + + it("warns about internal DOs and doesn't crash", async () => { + await getPlatformProxy({ + configPath: path.join(__dirname, "..", "wrangler_internal_do.jsonc"), + }); + expect(warn).toMatchInlineSnapshot(` + [MockFunction warn] { + "calls": [ + [ + "▲ [WARNING]  You have defined bindings to the following internal Durable Objects: + + - {"class_name":"MyDurableObject","name":"MY_DURABLE_OBJECT"} + These will not work in local development, but they should work in production. + + If you want to develop these locally, you can define your DO "externally" in another worker. + To do this, create another Worker and Wrangler config file. Export your DO from there. + Then, set the \`script_name\` field in your original DO binding to equal the \`name\` field from your new external DO config. + + You will be able to develop this locally by running: + npx wrangler dev -c path/to/original/wrangler.json -c path/to/external-do/wrangler.json + + ", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + ], + } + `); + }); + it("doesn't warn about external DOs and doesn't crash", async () => { + await getPlatformProxy({ + configPath: path.join(__dirname, "..", "wrangler_external_do.jsonc"), + }); + expect(warn).not.toHaveBeenCalled(); + }); + }); + describe("with a target environment", () => { it("should provide bindings targeting a specified environment and also inherit top-level ones", async () => { const { env, dispose } = await getPlatformProxy({ diff --git a/fixtures/get-platform-proxy/wrangler_external_do.jsonc b/fixtures/get-platform-proxy/wrangler_external_do.jsonc new file mode 100644 index 000000000000..77b57344cc6d --- /dev/null +++ b/fixtures/get-platform-proxy/wrangler_external_do.jsonc @@ -0,0 +1,20 @@ +{ + "name": "external_do", + "main": "src/index.ts", + // external durable object - has script name + "durable_objects": { + "bindings": [ + { + "class_name": "MyDurableObject", + "name": "MY_DURABLE_OBJECT", + "script_name": "internal-do", + }, + ], + }, + "migrations": [ + { + "new_sqlite_classes": ["MyDurableObject"], + "tag": "v1", + }, + ], +} diff --git a/fixtures/get-platform-proxy/wrangler_internal_do.jsonc b/fixtures/get-platform-proxy/wrangler_internal_do.jsonc new file mode 100644 index 000000000000..2d11ab267cf1 --- /dev/null +++ b/fixtures/get-platform-proxy/wrangler_internal_do.jsonc @@ -0,0 +1,19 @@ +{ + "name": "internal_do", + "main": "src/index.ts", + // internal durable object + "durable_objects": { + "bindings": [ + { + "class_name": "MyDurableObject", + "name": "MY_DURABLE_OBJECT", + }, + ], + }, + "migrations": [ + { + "new_sqlite_classes": ["MyDurableObject"], + "tag": "v1", + }, + ], +} diff --git a/packages/wrangler/src/api/integrations/platform/index.ts b/packages/wrangler/src/api/integrations/platform/index.ts index 694a13b21e14..72e2b81a3f14 100644 --- a/packages/wrangler/src/api/integrations/platform/index.ts +++ b/packages/wrangler/src/api/integrations/platform/index.ts @@ -1,6 +1,7 @@ import { kCurrentWorker, Miniflare } from "miniflare"; import { getAssetsOptions } from "../../../assets"; -import { formatConfigSnippet, readConfig } from "../../../config"; +import { readConfig } from "../../../config"; +import { partitionDurableObjectBindings } from "../../../deployment-bundle/entry"; import { DEFAULT_MODULE_RULES } from "../../../deployment-bundle/rules"; import { getBindings } from "../../../dev"; import { getBoundRegisteredWorkers } from "../../../dev-registry"; @@ -132,6 +133,7 @@ export async function getPlatformProxy< }; } +// this is only used by getPlatformProxy async function getMiniflareOptionsFromConfig( rawConfig: Config, env: string | undefined, @@ -139,17 +141,22 @@ async function getMiniflareOptionsFromConfig( ): Promise> { const bindings = getBindings(rawConfig, env, true, {}); - if (bindings.durable_objects) { - logger.warn(dedent` - You have defined an internal Durable Object (ie the binding does not have a script_name field). - You will not be able to develop it locally, but it should work in production. - - Alternatively, you can define your DO "externally" in another worker. - To do this, create another Worker + Wrangler config file. Export your DO from there. - Then, set the script_name field in your original DO binding to equal the name field from your new external DO config. - You will be able to develop this locally by running: - npx wrangler dev -c path/to/original/wrangler.toml -c path/to/external-do/wrangler.toml - `); + if (rawConfig["durable_objects"]) { + const { localBindings } = partitionDurableObjectBindings(rawConfig); + if (localBindings.length > 0) { + logger.warn(dedent` + You have defined bindings to the following internal Durable Objects: + ${localBindings.map((b) => `- ${JSON.stringify(b)}`).join("\n")} + These will not work in local development, but they should work in production. + + If you want to develop these locally, you can define your DO "externally" in another worker. + To do this, create another Worker and Wrangler config file. Export your DO from there. + Then, set the \`script_name\` field in your original DO binding to equal the \`name\` field from your new external DO config. + + You will be able to develop this locally by running: + npx wrangler dev -c path/to/original/wrangler.json -c path/to/external-do/wrangler.json + `); + } } const workerDefinitions = await getBoundRegisteredWorkers({ name: rawConfig.name, diff --git a/packages/wrangler/src/deployment-bundle/entry.ts b/packages/wrangler/src/deployment-bundle/entry.ts index 5ab40cc364c7..677787a98f94 100644 --- a/packages/wrangler/src/deployment-bundle/entry.ts +++ b/packages/wrangler/src/deployment-bundle/entry.ts @@ -2,7 +2,6 @@ import path from "node:path"; import dedent from "ts-dedent"; import { configFileName, formatConfigSnippet } from "../config"; import { UserError } from "../errors"; -import { logger } from "../logger"; import { sniffUserAgent } from "../package-manager"; import guessWorkerFormat from "./guess-worker-format"; import { @@ -169,7 +168,7 @@ export async function getEntry( * Groups the durable object bindings into two lists: * those that are defined locally and those that refer to a durable object defined in another script. */ -function partitionDurableObjectBindings(config: Config): { +export function partitionDurableObjectBindings(config: Config): { localBindings: DurableObjectBindings; remoteBindings: DurableObjectBindings; } { From 94718ef958cb26bde3f9f0ed326448a1cb481d0d Mon Sep 17 00:00:00 2001 From: emily-shen <69125074+emily-shen@users.noreply.github.com> Date: Thu, 27 Mar 2025 14:02:39 +0000 Subject: [PATCH 05/14] changeset --- .changeset/shiny-ghosts-flash.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/shiny-ghosts-flash.md diff --git a/.changeset/shiny-ghosts-flash.md b/.changeset/shiny-ghosts-flash.md new file mode 100644 index 000000000000..ce3b6a2bc522 --- /dev/null +++ b/.changeset/shiny-ghosts-flash.md @@ -0,0 +1,7 @@ +--- +"wrangler": patch +--- + +fix: stop getPlatformProxy crashing when internal DOs are present + +Internal DOs still do not work with getPlatformProxy, but warn instead of crashing. From 4ea8cb09c6f59c9227945a156c8b0a02557d5bce Mon Sep 17 00:00:00 2001 From: emily-shen <69125074+emily-shen@users.noreply.github.com> Date: Thu, 27 Mar 2025 14:51:02 +0000 Subject: [PATCH 06/14] fix e2e --- packages/wrangler/e2e/__snapshots__/pages-dev.test.ts.snap | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/wrangler/e2e/__snapshots__/pages-dev.test.ts.snap b/packages/wrangler/e2e/__snapshots__/pages-dev.test.ts.snap index 16e127c1b285..69f29cf5a467 100644 --- a/packages/wrangler/e2e/__snapshots__/pages-dev.test.ts.snap +++ b/packages/wrangler/e2e/__snapshots__/pages-dev.test.ts.snap @@ -2,11 +2,6 @@ exports[`Pages 'wrangler pages dev' > should merge (with override) \`wrangler.toml\` configuration with configuration provided via the command line, with command line args taking precedence 1`] = ` "✨ Compiled Worker successfully -▲ [WARNING] WARNING: You have Durable Object bindings that are not defined locally in the worker being developed. - Be aware that changes to the data stored in these Durable Objects will be permanent and affect the live instances. - Remote Durable Objects that are affected: - - {"name":"DO_BINDING_1_TOML","class_name":"DO_1_TOML","script_name":"DO_SCRIPT_1_TOML"} - - {"name":"DO_BINDING_2_TOML","class_name":"DO_2_TOML","script_name":"DO_SCRIPT_2_TOML"} Your Worker and resources are simulated locally via Miniflare. For more information, see: https://developers.cloudflare.com/workers/testing/local-development. Your worker has access to the following bindings: - Durable Objects: From 14d2b2509de9933821082a563f3dd73dbe759fde Mon Sep 17 00:00:00 2001 From: emily-shen <69125074+emily-shen@users.noreply.github.com> Date: Thu, 27 Mar 2025 15:36:15 +0000 Subject: [PATCH 07/14] pr feedback --- fixtures/get-platform-proxy/wrangler_external_do.jsonc | 10 +++++++--- fixtures/get-platform-proxy/wrangler_internal_do.jsonc | 8 ++++++-- .../wrangler/src/api/integrations/platform/index.ts | 4 ++-- packages/wrangler/src/deployment-bundle/entry.ts | 5 ++++- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/fixtures/get-platform-proxy/wrangler_external_do.jsonc b/fixtures/get-platform-proxy/wrangler_external_do.jsonc index 77b57344cc6d..597fd3bc7087 100644 --- a/fixtures/get-platform-proxy/wrangler_external_do.jsonc +++ b/fixtures/get-platform-proxy/wrangler_external_do.jsonc @@ -1,13 +1,17 @@ { - "name": "external_do", + "name": "external-do", "main": "src/index.ts", - // external durable object - has script name + // external durable object = binding has script_name. This indicates that + // the DO is exported in a separate Worker called `do-worker`. For the + // purposes of testing, we don't need to set that up because + // getPlatformProxy would not be involved in running that Worker. + "durable_objects": { "bindings": [ { "class_name": "MyDurableObject", "name": "MY_DURABLE_OBJECT", - "script_name": "internal-do", + "script_name": "do-worker", }, ], }, diff --git a/fixtures/get-platform-proxy/wrangler_internal_do.jsonc b/fixtures/get-platform-proxy/wrangler_internal_do.jsonc index 2d11ab267cf1..f36328c7adb2 100644 --- a/fixtures/get-platform-proxy/wrangler_internal_do.jsonc +++ b/fixtures/get-platform-proxy/wrangler_internal_do.jsonc @@ -1,7 +1,11 @@ { - "name": "internal_do", + "name": "internal-do", "main": "src/index.ts", - // internal durable object + // Internal durable object = the binding does not specify a script name. + // This implies the DO is exported alongside this worker in `index.ts`, + // which it isn't actually. However we don't care about this here because + // getPlatformProxy will discard all user code anyway. We are simply making + // sure the warning shows up. "durable_objects": { "bindings": [ { diff --git a/packages/wrangler/src/api/integrations/platform/index.ts b/packages/wrangler/src/api/integrations/platform/index.ts index 72e2b81a3f14..334052c8485b 100644 --- a/packages/wrangler/src/api/integrations/platform/index.ts +++ b/packages/wrangler/src/api/integrations/platform/index.ts @@ -149,12 +149,12 @@ async function getMiniflareOptionsFromConfig( ${localBindings.map((b) => `- ${JSON.stringify(b)}`).join("\n")} These will not work in local development, but they should work in production. - If you want to develop these locally, you can define your DO "externally" in another worker. + If you want to develop these locally, you can define your DO "externally" in another Worker. To do this, create another Worker and Wrangler config file. Export your DO from there. Then, set the \`script_name\` field in your original DO binding to equal the \`name\` field from your new external DO config. You will be able to develop this locally by running: - npx wrangler dev -c path/to/original/wrangler.json -c path/to/external-do/wrangler.json + npx wrangler dev -c path/to/original/wrangler.jsonc -c path/to/external-do/wrangler.jsonc `); } } diff --git a/packages/wrangler/src/deployment-bundle/entry.ts b/packages/wrangler/src/deployment-bundle/entry.ts index 677787a98f94..67ca949019b2 100644 --- a/packages/wrangler/src/deployment-bundle/entry.ts +++ b/packages/wrangler/src/deployment-bundle/entry.ts @@ -175,7 +175,10 @@ export function partitionDurableObjectBindings(config: Config): { const localBindings: DurableObjectBindings = []; const remoteBindings: DurableObjectBindings = []; for (const binding of config.durable_objects.bindings) { - if (binding.script_name === undefined) { + if ( + binding.script_name === undefined || + binding.script_name === config.name + ) { localBindings.push(binding); } else { remoteBindings.push(binding); From c96e5eeee6ebf01b09ea542d2e9769653da22338 Mon Sep 17 00:00:00 2001 From: emily-shen <69125074+emily-shen@users.noreply.github.com> Date: Thu, 27 Mar 2025 15:42:17 +0000 Subject: [PATCH 08/14] elaborate on error message --- .../tests/get-platform-proxy.env.test.ts | 37 +++++++++++++++-- .../src/api/integrations/platform/index.ts | 40 ++++++++++++++++--- 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts index beb5ff60b3cc..7d4c7787383d 100644 --- a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts +++ b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts @@ -227,12 +227,41 @@ describe("getPlatformProxy - env", () => { - {"class_name":"MyDurableObject","name":"MY_DURABLE_OBJECT"} These will not work in local development, but they should work in production. - If you want to develop these locally, you can define your DO "externally" in another worker. - To do this, create another Worker and Wrangler config file. Export your DO from there. - Then, set the \`script_name\` field in your original DO binding to equal the \`name\` field from your new external DO config. + If you want to develop these locally, you can define your DO "externally" in another Worker. + To do this, create another Worker, e.g. + + export class MyDurableObject extends DurableObject { + // DO code goes here + } + export default { + fetch() { + // doesn't have to do anything, but DO cannot be the default export + } + } + + Also create a new Wrangler config file for this Worker, e.g. + + { + "name": "external-do-worker", + "main": "src/index.ts", + "compatibility_date": "XXXX-XX-XX" + } + + Then, update your original DO bindings to include the script_name field, e.g. + { + "durable_objects": { + "bindings": [ + { + "name": "BINDING", + "class_name": "MyDurableObject", + "script_name": "external-do-worker" + } + ] + } + } You will be able to develop this locally by running: - npx wrangler dev -c path/to/original/wrangler.json -c path/to/external-do/wrangler.json + npx wrangler dev -c path/to/original/wrangler.jsonc -c path/to/external-do/wrangler.jsonc ", ], diff --git a/packages/wrangler/src/api/integrations/platform/index.ts b/packages/wrangler/src/api/integrations/platform/index.ts index 334052c8485b..7b49a8cc5f75 100644 --- a/packages/wrangler/src/api/integrations/platform/index.ts +++ b/packages/wrangler/src/api/integrations/platform/index.ts @@ -1,6 +1,6 @@ import { kCurrentWorker, Miniflare } from "miniflare"; import { getAssetsOptions } from "../../../assets"; -import { readConfig } from "../../../config"; +import { formatConfigSnippet, readConfig } from "../../../config"; import { partitionDurableObjectBindings } from "../../../deployment-bundle/entry"; import { DEFAULT_MODULE_RULES } from "../../../deployment-bundle/rules"; import { getBindings } from "../../../dev"; @@ -110,7 +110,8 @@ export async function getPlatformProxy< RESOURCES_PROVISION: false, ASSETS_RPC: false, }, - () => getMiniflareOptionsFromConfig(rawConfig, env, options) + () => + getMiniflareOptionsFromConfig(rawConfig, env, options, options.configPath) ); const mf = new Miniflare({ @@ -137,7 +138,8 @@ export async function getPlatformProxy< async function getMiniflareOptionsFromConfig( rawConfig: Config, env: string | undefined, - options: GetPlatformProxyOptions + options: GetPlatformProxyOptions, + configPath: string | undefined ): Promise> { const bindings = getBindings(rawConfig, env, true, {}); @@ -150,8 +152,36 @@ async function getMiniflareOptionsFromConfig( These will not work in local development, but they should work in production. If you want to develop these locally, you can define your DO "externally" in another Worker. - To do this, create another Worker and Wrangler config file. Export your DO from there. - Then, set the \`script_name\` field in your original DO binding to equal the \`name\` field from your new external DO config. + To do this, create another Worker, e.g. + + export class MyDurableObject extends DurableObject { + // DO code goes here + } + export default { + fetch() { + // doesn't have to do anything, but DO cannot be the default export + } + } + + Also create a new Wrangler config file for this Worker, e.g. + + ${formatConfigSnippet({ name: "external-do-worker", main: "src/index.ts", compatibility_date: "XXXX-XX-XX" }, configPath)} + + Then, update your original DO bindings to include the script_name field, e.g. + ${formatConfigSnippet( + { + durable_objects: { + bindings: [ + { + name: "BINDING", + class_name: "MyDurableObject", + script_name: "external-do-worker", + }, + ], + }, + }, + configPath + )} You will be able to develop this locally by running: npx wrangler dev -c path/to/original/wrangler.jsonc -c path/to/external-do/wrangler.jsonc From e626dc987d354838c5b6ad95cd516605da02dd74 Mon Sep 17 00:00:00 2001 From: emily-shen <69125074+emily-shen@users.noreply.github.com> Date: Thu, 27 Mar 2025 17:30:46 +0000 Subject: [PATCH 09/14] move to a docs link --- .../tests/get-platform-proxy.env.test.ts | 38 ++--------------- .../src/api/integrations/platform/index.ts | 42 ++----------------- 2 files changed, 7 insertions(+), 73 deletions(-) diff --git a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts index 7d4c7787383d..53e973cf7c59 100644 --- a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts +++ b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts @@ -226,42 +226,9 @@ describe("getPlatformProxy - env", () => { - {"class_name":"MyDurableObject","name":"MY_DURABLE_OBJECT"} These will not work in local development, but they should work in production. - + If you want to develop these locally, you can define your DO "externally" in another Worker. - To do this, create another Worker, e.g. - - export class MyDurableObject extends DurableObject { - // DO code goes here - } - export default { - fetch() { - // doesn't have to do anything, but DO cannot be the default export - } - } - - Also create a new Wrangler config file for this Worker, e.g. - - { - "name": "external-do-worker", - "main": "src/index.ts", - "compatibility_date": "XXXX-XX-XX" - } - - Then, update your original DO bindings to include the script_name field, e.g. - { - "durable_objects": { - "bindings": [ - { - "name": "BINDING", - "class_name": "MyDurableObject", - "script_name": "external-do-worker" - } - ] - } - } - - You will be able to develop this locally by running: - npx wrangler dev -c path/to/original/wrangler.jsonc -c path/to/external-do/wrangler.jsonc + Refer to https://developers.cloudflare.com/durable-objects/platform/known-issues/#local-development-with-web-frameworks for guidance on how to do this. ", ], @@ -275,6 +242,7 @@ describe("getPlatformProxy - env", () => { } `); }); + it("doesn't warn about external DOs and doesn't crash", async () => { await getPlatformProxy({ configPath: path.join(__dirname, "..", "wrangler_external_do.jsonc"), diff --git a/packages/wrangler/src/api/integrations/platform/index.ts b/packages/wrangler/src/api/integrations/platform/index.ts index 7b49a8cc5f75..cc3c2fdb1231 100644 --- a/packages/wrangler/src/api/integrations/platform/index.ts +++ b/packages/wrangler/src/api/integrations/platform/index.ts @@ -1,6 +1,6 @@ import { kCurrentWorker, Miniflare } from "miniflare"; import { getAssetsOptions } from "../../../assets"; -import { formatConfigSnippet, readConfig } from "../../../config"; +import { readConfig } from "../../../config"; import { partitionDurableObjectBindings } from "../../../deployment-bundle/entry"; import { DEFAULT_MODULE_RULES } from "../../../deployment-bundle/rules"; import { getBindings } from "../../../dev"; @@ -110,8 +110,7 @@ export async function getPlatformProxy< RESOURCES_PROVISION: false, ASSETS_RPC: false, }, - () => - getMiniflareOptionsFromConfig(rawConfig, env, options, options.configPath) + () => getMiniflareOptionsFromConfig(rawConfig, env, options) ); const mf = new Miniflare({ @@ -138,8 +137,7 @@ export async function getPlatformProxy< async function getMiniflareOptionsFromConfig( rawConfig: Config, env: string | undefined, - options: GetPlatformProxyOptions, - configPath: string | undefined + options: GetPlatformProxyOptions ): Promise> { const bindings = getBindings(rawConfig, env, true, {}); @@ -152,39 +150,7 @@ async function getMiniflareOptionsFromConfig( These will not work in local development, but they should work in production. If you want to develop these locally, you can define your DO "externally" in another Worker. - To do this, create another Worker, e.g. - - export class MyDurableObject extends DurableObject { - // DO code goes here - } - export default { - fetch() { - // doesn't have to do anything, but DO cannot be the default export - } - } - - Also create a new Wrangler config file for this Worker, e.g. - - ${formatConfigSnippet({ name: "external-do-worker", main: "src/index.ts", compatibility_date: "XXXX-XX-XX" }, configPath)} - - Then, update your original DO bindings to include the script_name field, e.g. - ${formatConfigSnippet( - { - durable_objects: { - bindings: [ - { - name: "BINDING", - class_name: "MyDurableObject", - script_name: "external-do-worker", - }, - ], - }, - }, - configPath - )} - - You will be able to develop this locally by running: - npx wrangler dev -c path/to/original/wrangler.jsonc -c path/to/external-do/wrangler.jsonc + Refer to https://developers.cloudflare.com/durable-objects/platform/known-issues/#local-development-with-web-frameworks for guidance on how to do this. `); } } From 0fa605e33dca8d05a1e09fe575e57b5d54b906f2 Mon Sep 17 00:00:00 2001 From: Carmen Popoviciu Date: Fri, 28 Mar 2025 12:08:25 +0100 Subject: [PATCH 10/14] fix failing test --- .../get-platform-proxy/tests/get-platform-proxy.env.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts index 53e973cf7c59..8d7eb8fad9fc 100644 --- a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts +++ b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts @@ -226,7 +226,7 @@ describe("getPlatformProxy - env", () => { - {"class_name":"MyDurableObject","name":"MY_DURABLE_OBJECT"} These will not work in local development, but they should work in production. - + If you want to develop these locally, you can define your DO "externally" in another Worker. Refer to https://developers.cloudflare.com/durable-objects/platform/known-issues/#local-development-with-web-frameworks for guidance on how to do this. From ded401e843b04ded55d317608375c6eee38d6e26 Mon Sep 17 00:00:00 2001 From: Carmen Popoviciu Date: Fri, 28 Mar 2025 12:57:10 +0100 Subject: [PATCH 11/14] copy improvement --- .../get-platform-proxy/tests/get-platform-proxy.env.test.ts | 2 +- packages/wrangler/src/api/integrations/platform/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts index 8d7eb8fad9fc..8e929ed953ac 100644 --- a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts +++ b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts @@ -227,7 +227,7 @@ describe("getPlatformProxy - env", () => { - {"class_name":"MyDurableObject","name":"MY_DURABLE_OBJECT"} These will not work in local development, but they should work in production. - If you want to develop these locally, you can define your DO "externally" in another Worker. + If you want to develop these locally, you can define your DO in a separate Worker, specified by a separate configuration file. Refer to https://developers.cloudflare.com/durable-objects/platform/known-issues/#local-development-with-web-frameworks for guidance on how to do this. ", diff --git a/packages/wrangler/src/api/integrations/platform/index.ts b/packages/wrangler/src/api/integrations/platform/index.ts index cc3c2fdb1231..bed44978517f 100644 --- a/packages/wrangler/src/api/integrations/platform/index.ts +++ b/packages/wrangler/src/api/integrations/platform/index.ts @@ -149,7 +149,7 @@ async function getMiniflareOptionsFromConfig( ${localBindings.map((b) => `- ${JSON.stringify(b)}`).join("\n")} These will not work in local development, but they should work in production. - If you want to develop these locally, you can define your DO "externally" in another Worker. + If you want to develop these locally, you can define your DO in a separate Worker, specified by a separate configuration file. Refer to https://developers.cloudflare.com/durable-objects/platform/known-issues/#local-development-with-web-frameworks for guidance on how to do this. `); } From 0f0799e3cd9f1b657c90a0e4a6f30c6ced6c98a3 Mon Sep 17 00:00:00 2001 From: Carmen Popoviciu Date: Fri, 28 Mar 2025 13:20:06 +0100 Subject: [PATCH 12/14] fix --- packages/wrangler/src/api/integrations/platform/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wrangler/src/api/integrations/platform/index.ts b/packages/wrangler/src/api/integrations/platform/index.ts index bed44978517f..72d5b4931fba 100644 --- a/packages/wrangler/src/api/integrations/platform/index.ts +++ b/packages/wrangler/src/api/integrations/platform/index.ts @@ -12,8 +12,8 @@ import { buildSitesOptions, } from "../../../dev/miniflare"; import { run } from "../../../experimental-flags"; -import { getLegacyAssetPaths, getSiteAssetPaths } from "../../../sites"; import { logger } from "../../../logger"; +import { getLegacyAssetPaths, getSiteAssetPaths } from "../../../sites"; import { dedent } from "../../../utils/dedent"; import { CacheStorage } from "./caches"; import { ExecutionContext } from "./executionContext"; From cdfb13f5f29b11ce2e4438e08844cbfcf9ee65d1 Mon Sep 17 00:00:00 2001 From: emily-shen <69125074+emily-shen@users.noreply.github.com> Date: Fri, 28 Mar 2025 12:40:33 +0000 Subject: [PATCH 13/14] update docs link --- .../get-platform-proxy/tests/get-platform-proxy.env.test.ts | 2 +- packages/wrangler/src/api/integrations/platform/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts index 8e929ed953ac..99e2a9aa6e0e 100644 --- a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts +++ b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts @@ -228,7 +228,7 @@ describe("getPlatformProxy - env", () => { These will not work in local development, but they should work in production. If you want to develop these locally, you can define your DO in a separate Worker, specified by a separate configuration file. - Refer to https://developers.cloudflare.com/durable-objects/platform/known-issues/#local-development-with-web-frameworks for guidance on how to do this. + Refer to https://developers.cloudflare.com/workers/wrangler/api#durable-objects for guidance on how to do this. ", ], diff --git a/packages/wrangler/src/api/integrations/platform/index.ts b/packages/wrangler/src/api/integrations/platform/index.ts index 72d5b4931fba..3510fec8069a 100644 --- a/packages/wrangler/src/api/integrations/platform/index.ts +++ b/packages/wrangler/src/api/integrations/platform/index.ts @@ -150,7 +150,7 @@ async function getMiniflareOptionsFromConfig( These will not work in local development, but they should work in production. If you want to develop these locally, you can define your DO in a separate Worker, specified by a separate configuration file. - Refer to https://developers.cloudflare.com/durable-objects/platform/known-issues/#local-development-with-web-frameworks for guidance on how to do this. + Refer to https://developers.cloudflare.com/workers/wrangler/api#durable-objects for guidance on how to do this. `); } } From ecae6dd140a4fa1ede061061a37c2ef0306def80 Mon Sep 17 00:00:00 2001 From: emily-shen <69125074+emily-shen@users.noreply.github.com> Date: Mon, 31 Mar 2025 13:32:07 +0100 Subject: [PATCH 14/14] update link --- .../get-platform-proxy/tests/get-platform-proxy.env.test.ts | 4 ++-- packages/wrangler/src/api/integrations/platform/index.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts index 99e2a9aa6e0e..ac243cef576e 100644 --- a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts +++ b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts @@ -227,8 +227,8 @@ describe("getPlatformProxy - env", () => { - {"class_name":"MyDurableObject","name":"MY_DURABLE_OBJECT"} These will not work in local development, but they should work in production. - If you want to develop these locally, you can define your DO in a separate Worker, specified by a separate configuration file. - Refer to https://developers.cloudflare.com/workers/wrangler/api#durable-objects for guidance on how to do this. + If you want to develop these locally, you can define your DO in a separate Worker, with a separate configuration file. + For detailed instructions, refer to the Durable Objects section here: https://developers.cloudflare.com/workers/wrangler/api#supported-bindings ", ], diff --git a/packages/wrangler/src/api/integrations/platform/index.ts b/packages/wrangler/src/api/integrations/platform/index.ts index 3510fec8069a..a3232441d267 100644 --- a/packages/wrangler/src/api/integrations/platform/index.ts +++ b/packages/wrangler/src/api/integrations/platform/index.ts @@ -149,8 +149,8 @@ async function getMiniflareOptionsFromConfig( ${localBindings.map((b) => `- ${JSON.stringify(b)}`).join("\n")} These will not work in local development, but they should work in production. - If you want to develop these locally, you can define your DO in a separate Worker, specified by a separate configuration file. - Refer to https://developers.cloudflare.com/workers/wrangler/api#durable-objects for guidance on how to do this. + If you want to develop these locally, you can define your DO in a separate Worker, with a separate configuration file. + For detailed instructions, refer to the Durable Objects section here: https://developers.cloudflare.com/workers/wrangler/api#supported-bindings `); } }