Skip to content

Commit c38ae3d

Browse files
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 cloudflare/miniflare#228 has landed in miniflare (thanks @caass!), we can use that in wrangler as well. Fixes #416
1 parent a1dadac commit c38ae3d

12 files changed

+35
-17
lines changed

.changeset/short-cougars-approve.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
`text_blobs`/Text module support for service worker format in local mode
6+
7+
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.

packages/wrangler/src/__tests__/configuration.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ describe("normalizeAndValidateConfig()", () => {
354354
expect(diagnostics.hasWarnings()).toBe(false);
355355
});
356356

357-
it("should error on invalid `wasm_module` paths", () => {
357+
it("should error on invalid `wasm_modules` paths", () => {
358358
const expectedConfig = {
359359
wasm_modules: {
360360
MODULE_1: 111,

packages/wrangler/src/__tests__/publish.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ export default{
732732
expect(std.err).toMatchInlineSnapshot(`""`);
733733
});
734734

735-
it("when using a service worker type, it should add an asset manifest as a text_blob, and bind to a namespace", async () => {
735+
it("when using a service-worker type, it should add an asset manifest as a text_blob, and bind to a namespace", async () => {
736736
const assets = [
737737
{ filePath: "assets/file-1.txt", content: "Content of file-1" },
738738
{ filePath: "assets/file-2.txt", content: "Content of file-2" },
@@ -2902,7 +2902,7 @@ export default{
29022902
expect(std.warn).toMatchInlineSnapshot(`""`);
29032903
});
29042904

2905-
it("should error when detecting service workers implementing durable objects", async () => {
2905+
it("should error when detecting a service-worker worker implementing durable objects", async () => {
29062906
writeWranglerToml({
29072907
durable_objects: {
29082908
bindings: [
@@ -2918,7 +2918,7 @@ export default{
29182918

29192919
await expect(runWrangler("publish index.js")).rejects
29202920
.toThrowErrorMatchingInlineSnapshot(`
2921-
"You seem to be trying to use Durable Objects in a Worker written with Service Worker syntax.
2921+
"You seem to be trying to use Durable Objects in a Worker written as a service-worker.
29222922
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:
29232923
{ name = EXAMPLE_DO_BINDING, class_name = ExampleDurableObject } ==> { name = EXAMPLE_DO_BINDING, class_name = ExampleDurableObject, script_name = example-do-binding-worker }
29242924
Alternatively, migrate your worker to ES Module syntax to implement a Durable Object in this Worker:

packages/wrangler/src/config/validation.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1140,7 +1140,7 @@ const validateR2Binding: ValidatorFn = (diagnostics, field, value) => {
11401140
*
11411141
* We don't want to have, for example, a KV namespace named "DATA"
11421142
* and a Durable Object also named "DATA". Then it would be ambiguous
1143-
* what exactly would live at `env.DATA` (or in the case of service workers,
1143+
* what exactly would live at `env.DATA` (or in the case of service-workers,
11441144
* the `DATA` global).
11451145
*/
11461146
const validateBindingsHaveUniqueNames = (

packages/wrangler/src/create-worker-upload-form.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function toMimeType(type: CfModuleType): string {
2626
export interface WorkerMetadata {
2727
/** The name of the entry point module. Only exists when the worker is in the ES module format */
2828
main_module?: string;
29-
/** The name of the entry point module. Only exists when the worker is in the Service Worker format */
29+
/** The name of the entry point module. Only exists when the worker is in the service-worker format */
3030
body_part?: string;
3131
compatibility_date?: string;
3232
compatibility_flags?: string[];
@@ -172,10 +172,6 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData {
172172
);
173173
// And then remove it from the modules collection
174174
modules = modules?.filter((m) => m !== module);
175-
} else if (module.type === "buffer") {
176-
throw new Error(
177-
'The "buffer" module type is not yet supported in service worker format workers'
178-
);
179175
}
180176
}
181177
}

packages/wrangler/src/dev/dev.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export function DevImplementation(props: DevProps): JSX.Element {
6565

6666
if (props.public && props.entry.format === "service-worker") {
6767
throw new Error(
68-
"You cannot use the service worker format with a `public` directory."
68+
"You cannot use the service-worker format with a `public` directory."
6969
);
7070
}
7171

packages/wrangler/src/dev/local.tsx

+10
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ function useLocalWorker({
8282
const scriptPath = realpathSync(bundle.path);
8383

8484
const wasmBindings = { ...bindings.wasm_modules };
85+
const textBlobBindings = { ...bindings.text_blobs };
8586
if (format === "service-worker") {
8687
for (const { type, name } of bundle.modules) {
8788
if (type === "compiled-wasm") {
@@ -91,6 +92,13 @@ function useLocalWorker({
9192
// characters with an underscore.
9293
const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
9394
wasmBindings[identifier] = name;
95+
} else if (type === "text") {
96+
// In service-worker format, text modules are referenced by global identifiers,
97+
// so we convert it here.
98+
// This identifier has to be a valid JS identifier, so we replace all non alphanumeric
99+
// characters with an underscore.
100+
const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_");
101+
textBlobBindings[identifier] = name;
94102
}
95103
}
96104
}
@@ -130,6 +138,7 @@ function useLocalWorker({
130138
: undefined,
131139
bindings: bindings.vars,
132140
wasmBindings,
141+
textBlobBindings,
133142
sourceMap: true,
134143
logUnhandledRejections: true,
135144
};
@@ -227,6 +236,7 @@ function useLocalWorker({
227236
publicDirectory,
228237
rules,
229238
bindings.wasm_modules,
239+
bindings.text_blobs,
230240
]);
231241
return { inspectorUrl };
232242
}

packages/wrangler/src/entry.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export async function getEntry(
6464

6565
if (format === "service-worker" && localBindings.length > 0) {
6666
const errorMessage =
67-
"You seem to be trying to use Durable Objects in a Worker written with Service Worker syntax.";
67+
"You seem to be trying to use Durable Objects in a Worker written as a service-worker.";
6868
const addScriptName =
6969
"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:";
7070
const addScriptNameExamples = generateAddScriptNameExamples(localBindings);

packages/wrangler/src/module-collection.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export default function createModuleCollector(props: {
102102
modules.splice(0);
103103
});
104104

105-
// ~ start legacy module specifier support ~
105+
// ~ start legacy module specifier support ~
106106

107107
// This section detects usage of "legacy" 1.x style module specifiers
108108
// and modifies them so they "work" in wrangler v2, but with a warning
@@ -218,6 +218,11 @@ export default function createModuleCollector(props: {
218218
build.onLoad(
219219
{ filter: globToRegExp(glob) },
220220
async (args: esbuild.OnLoadArgs) => {
221+
if (rule.type === "Data") {
222+
throw new Error(
223+
"Data modules are not supported in the service-worker format"
224+
);
225+
}
221226
return {
222227
// We replace the the module with an identifier
223228
// that we'll separately add to the form upload

packages/wrangler/src/publish.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export default async function publish(props: Props): Promise<void> {
7474
if (props.experimentalPublic && format === "service-worker") {
7575
// TODO: check config too
7676
throw new Error(
77-
"You cannot publish in the service worker format with a public directory."
77+
"You cannot publish in the service-worker format with a public directory."
7878
);
7979
}
8080

packages/wrangler/src/worker.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,15 @@ interface CfKvNamespace {
7575
}
7676

7777
/**
78-
* A binding to a wasm module (in service worker format)
78+
* A binding to a wasm module (in service-worker format)
7979
*/
8080

8181
interface CfWasmModuleBindings {
8282
[key: string]: string;
8383
}
8484

8585
/**
86-
* A binding to a text blob (in service worker format)
86+
* A binding to a text blob (in service-worker format)
8787
*/
8888

8989
interface CfTextBlobBindings {

packages/wrangler/templates/static-asset-facade.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export default {
4141
// if an error is thrown then serve from actual worker
4242
return worker.fetch(request);
4343
// TODO: throw here if worker is not available
44-
// (which implies it may be a service worker)
44+
// (which implies it may be a service-worker)
4545
}
4646
},
4747
};

0 commit comments

Comments
 (0)