From c38ae3dd36464522e13f32813123fd7b4deb6be3 Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Thu, 31 Mar 2022 20:51:33 +0530 Subject: [PATCH] `text_blobs`/Text module support for service worker format in local mode (#735) This adds support for `text_blobs`/Text module support in local mode. Now that https://github.com/cloudflare/miniflare/pull/228 has landed in miniflare (thanks @caass!), we can use that in wrangler as well. Fixes https://github.com/cloudflare/wrangler2/issues/416 --- .changeset/short-cougars-approve.md | 7 +++++++ packages/wrangler/src/__tests__/configuration.test.ts | 2 +- packages/wrangler/src/__tests__/publish.test.ts | 6 +++--- packages/wrangler/src/config/validation.ts | 2 +- packages/wrangler/src/create-worker-upload-form.ts | 6 +----- packages/wrangler/src/dev/dev.tsx | 2 +- packages/wrangler/src/dev/local.tsx | 10 ++++++++++ packages/wrangler/src/entry.ts | 2 +- packages/wrangler/src/module-collection.ts | 7 ++++++- packages/wrangler/src/publish.ts | 2 +- packages/wrangler/src/worker.ts | 4 ++-- packages/wrangler/templates/static-asset-facade.js | 2 +- 12 files changed, 35 insertions(+), 17 deletions(-) create mode 100644 .changeset/short-cougars-approve.md diff --git a/.changeset/short-cougars-approve.md b/.changeset/short-cougars-approve.md new file mode 100644 index 000000000000..73a093420f75 --- /dev/null +++ b/.changeset/short-cougars-approve.md @@ -0,0 +1,7 @@ +--- +"wrangler": patch +--- + +`text_blobs`/Text module support for service worker format in local mode + +This adds support for `text_blobs`/Text module support in local mode. Now that https://github.com/cloudflare/miniflare/pull/228 has landed in miniflare (thanks @caass!), we can use that in wrangler as well. diff --git a/packages/wrangler/src/__tests__/configuration.test.ts b/packages/wrangler/src/__tests__/configuration.test.ts index ec5d5b8219ad..4a2dec033220 100644 --- a/packages/wrangler/src/__tests__/configuration.test.ts +++ b/packages/wrangler/src/__tests__/configuration.test.ts @@ -354,7 +354,7 @@ describe("normalizeAndValidateConfig()", () => { expect(diagnostics.hasWarnings()).toBe(false); }); - it("should error on invalid `wasm_module` paths", () => { + it("should error on invalid `wasm_modules` paths", () => { const expectedConfig = { wasm_modules: { MODULE_1: 111, diff --git a/packages/wrangler/src/__tests__/publish.test.ts b/packages/wrangler/src/__tests__/publish.test.ts index 56447530737c..afa6adc33d39 100644 --- a/packages/wrangler/src/__tests__/publish.test.ts +++ b/packages/wrangler/src/__tests__/publish.test.ts @@ -732,7 +732,7 @@ export default{ expect(std.err).toMatchInlineSnapshot(`""`); }); - it("when using a service worker type, it should add an asset manifest as a text_blob, and bind to a namespace", async () => { + it("when using a service-worker type, it should add an asset manifest as a text_blob, and bind to a namespace", async () => { const assets = [ { filePath: "assets/file-1.txt", content: "Content of file-1" }, { filePath: "assets/file-2.txt", content: "Content of file-2" }, @@ -2902,7 +2902,7 @@ export default{ expect(std.warn).toMatchInlineSnapshot(`""`); }); - it("should error when detecting service workers implementing durable objects", async () => { + it("should error when detecting a service-worker worker implementing durable objects", async () => { writeWranglerToml({ durable_objects: { bindings: [ @@ -2918,7 +2918,7 @@ export default{ await expect(runWrangler("publish index.js")).rejects .toThrowErrorMatchingInlineSnapshot(` - "You seem to be trying to use Durable Objects in a Worker written with Service Worker syntax. + "You seem to be trying to use Durable Objects in a Worker written as a service-worker. You can use Durable Objects defined in other Workers by specifying a \`script_name\` in your wrangler.toml, where \`script_name\` is the name of the Worker that implements that Durable Object. For example: { name = EXAMPLE_DO_BINDING, class_name = ExampleDurableObject } ==> { name = EXAMPLE_DO_BINDING, class_name = ExampleDurableObject, script_name = example-do-binding-worker } Alternatively, migrate your worker to ES Module syntax to implement a Durable Object in this Worker: diff --git a/packages/wrangler/src/config/validation.ts b/packages/wrangler/src/config/validation.ts index 9d50612fe270..ba20bdf42007 100644 --- a/packages/wrangler/src/config/validation.ts +++ b/packages/wrangler/src/config/validation.ts @@ -1140,7 +1140,7 @@ const validateR2Binding: ValidatorFn = (diagnostics, field, value) => { * * We don't want to have, for example, a KV namespace named "DATA" * and a Durable Object also named "DATA". Then it would be ambiguous - * what exactly would live at `env.DATA` (or in the case of service workers, + * what exactly would live at `env.DATA` (or in the case of service-workers, * the `DATA` global). */ const validateBindingsHaveUniqueNames = ( diff --git a/packages/wrangler/src/create-worker-upload-form.ts b/packages/wrangler/src/create-worker-upload-form.ts index 53f0bc2f40f5..978c06200b01 100644 --- a/packages/wrangler/src/create-worker-upload-form.ts +++ b/packages/wrangler/src/create-worker-upload-form.ts @@ -26,7 +26,7 @@ export function toMimeType(type: CfModuleType): string { export interface WorkerMetadata { /** The name of the entry point module. Only exists when the worker is in the ES module format */ main_module?: string; - /** The name of the entry point module. Only exists when the worker is in the Service Worker format */ + /** The name of the entry point module. Only exists when the worker is in the service-worker format */ body_part?: string; compatibility_date?: string; compatibility_flags?: string[]; @@ -172,10 +172,6 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData { ); // And then remove it from the modules collection modules = modules?.filter((m) => m !== module); - } else if (module.type === "buffer") { - throw new Error( - 'The "buffer" module type is not yet supported in service worker format workers' - ); } } } diff --git a/packages/wrangler/src/dev/dev.tsx b/packages/wrangler/src/dev/dev.tsx index e02e8278e48d..528266fdcd85 100644 --- a/packages/wrangler/src/dev/dev.tsx +++ b/packages/wrangler/src/dev/dev.tsx @@ -65,7 +65,7 @@ export function DevImplementation(props: DevProps): JSX.Element { if (props.public && props.entry.format === "service-worker") { throw new Error( - "You cannot use the service worker format with a `public` directory." + "You cannot use the service-worker format with a `public` directory." ); } diff --git a/packages/wrangler/src/dev/local.tsx b/packages/wrangler/src/dev/local.tsx index 74d9ad884f59..359bb3123bf7 100644 --- a/packages/wrangler/src/dev/local.tsx +++ b/packages/wrangler/src/dev/local.tsx @@ -82,6 +82,7 @@ function useLocalWorker({ const scriptPath = realpathSync(bundle.path); const wasmBindings = { ...bindings.wasm_modules }; + const textBlobBindings = { ...bindings.text_blobs }; if (format === "service-worker") { for (const { type, name } of bundle.modules) { if (type === "compiled-wasm") { @@ -91,6 +92,13 @@ function useLocalWorker({ // characters with an underscore. const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_"); wasmBindings[identifier] = name; + } else if (type === "text") { + // In service-worker format, text modules are referenced by global identifiers, + // so we convert it here. + // This identifier has to be a valid JS identifier, so we replace all non alphanumeric + // characters with an underscore. + const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_"); + textBlobBindings[identifier] = name; } } } @@ -130,6 +138,7 @@ function useLocalWorker({ : undefined, bindings: bindings.vars, wasmBindings, + textBlobBindings, sourceMap: true, logUnhandledRejections: true, }; @@ -227,6 +236,7 @@ function useLocalWorker({ publicDirectory, rules, bindings.wasm_modules, + bindings.text_blobs, ]); return { inspectorUrl }; } diff --git a/packages/wrangler/src/entry.ts b/packages/wrangler/src/entry.ts index 6d327329c28e..4f78c06cd39a 100644 --- a/packages/wrangler/src/entry.ts +++ b/packages/wrangler/src/entry.ts @@ -64,7 +64,7 @@ export async function getEntry( if (format === "service-worker" && localBindings.length > 0) { const errorMessage = - "You seem to be trying to use Durable Objects in a Worker written with Service Worker syntax."; + "You seem to be trying to use Durable Objects in a Worker written as a service-worker."; const addScriptName = "You can use Durable Objects defined in other Workers by specifying a `script_name` in your wrangler.toml, where `script_name` is the name of the Worker that implements that Durable Object. For example:"; const addScriptNameExamples = generateAddScriptNameExamples(localBindings); diff --git a/packages/wrangler/src/module-collection.ts b/packages/wrangler/src/module-collection.ts index 00fff432c593..491777df4c66 100644 --- a/packages/wrangler/src/module-collection.ts +++ b/packages/wrangler/src/module-collection.ts @@ -102,7 +102,7 @@ export default function createModuleCollector(props: { modules.splice(0); }); - // ~ start legacy module specifier support ~ + // ~ start legacy module specifier support ~ // This section detects usage of "legacy" 1.x style module specifiers // and modifies them so they "work" in wrangler v2, but with a warning @@ -218,6 +218,11 @@ export default function createModuleCollector(props: { build.onLoad( { filter: globToRegExp(glob) }, async (args: esbuild.OnLoadArgs) => { + if (rule.type === "Data") { + throw new Error( + "Data modules are not supported in the service-worker format" + ); + } return { // We replace the the module with an identifier // that we'll separately add to the form upload diff --git a/packages/wrangler/src/publish.ts b/packages/wrangler/src/publish.ts index ebb6c0cc3e27..f36b804de559 100644 --- a/packages/wrangler/src/publish.ts +++ b/packages/wrangler/src/publish.ts @@ -74,7 +74,7 @@ export default async function publish(props: Props): Promise { if (props.experimentalPublic && format === "service-worker") { // TODO: check config too throw new Error( - "You cannot publish in the service worker format with a public directory." + "You cannot publish in the service-worker format with a public directory." ); } diff --git a/packages/wrangler/src/worker.ts b/packages/wrangler/src/worker.ts index 022bf6e4debe..419708ee3734 100644 --- a/packages/wrangler/src/worker.ts +++ b/packages/wrangler/src/worker.ts @@ -75,7 +75,7 @@ interface CfKvNamespace { } /** - * A binding to a wasm module (in service worker format) + * A binding to a wasm module (in service-worker format) */ interface CfWasmModuleBindings { @@ -83,7 +83,7 @@ interface CfWasmModuleBindings { } /** - * A binding to a text blob (in service worker format) + * A binding to a text blob (in service-worker format) */ interface CfTextBlobBindings { diff --git a/packages/wrangler/templates/static-asset-facade.js b/packages/wrangler/templates/static-asset-facade.js index f5a808c6b921..fb865c74aeec 100644 --- a/packages/wrangler/templates/static-asset-facade.js +++ b/packages/wrangler/templates/static-asset-facade.js @@ -41,7 +41,7 @@ export default { // if an error is thrown then serve from actual worker return worker.fetch(request); // TODO: throw here if worker is not available - // (which implies it may be a service worker) + // (which implies it may be a service-worker) } }, };