workers-sdk icon indicating copy to clipboard operation
workers-sdk copied to clipboard

🐛 BUG: Usage of "typeof module" causes error "The uploaded script has no registered event handlers. [code: 10068]"

Open paul-go opened this issue 3 years ago • 2 comments

What version of Wrangler are you using?

2.0.25

What operating system are you using?

Mac

Describe the Bug

Attempting to deploy the following code causes the error: "The uploaded script has no registered event handlers. [code: 10068]"

"use strict";
addEventListener("fetch", () => { });
typeof module;

Commenting out the last line causes the deployment to function as expected:

"use strict";
addEventListener("fetch", () => { });
//typeof module;

EDIT: Seems the same thing is happening if I change the variable after typeof to exports. Is this thing specifically trying to prevent me from detecting Node.js vs Cloudflare?

paul-go avatar Aug 12 '22 13:08 paul-go

I got the same issue after integrated @apollo/client into my project.

It seems due to typeof module statement. https://github.com/benlesh/symbol-observable/blob/master/es/index.js#L12

// node_modules/symbol-observable/es/index.js
var root;
typeof self < "u" ? root = self : typeof window < "u" ? root = window : typeof globalThis < "u" ? root = globalThis : typeof module < "u" ? root = module : root = Function("return this")();
var result = symbolObservablePonyfill(root);

I can use wrangler to deploy my project successfully if I replaced typeof module < "u" to false:

// Deploy successfully
// node_modules/symbol-observable/es/index.js
var root;
typeof self < "u" ? root = self : typeof window < "u" ? root = window : typeof globalThis < "u" ? root = globalThis : false ? root = module : root = Function("return this")();
var result = symbolObservablePonyfill(root);

kimyvgy avatar Aug 16 '22 02:08 kimyvgy

This is due to the way we handle the two types of worker formats. Currently we "guess" which type of worker we have - and if we find exports we assume it is a modules worker.

From packages/wrangler/src/entry.ts line 133:

/**
 * A function to "guess" the type of worker.
 * We do this by running a lightweight build of the actual script,
 * and looking at the metafile generated by esbuild. If it has a default
 * export (or really, any exports), that means it's a "modules" worker.
 * Else, it's a "service-worker" worker. This seems hacky, but works remarkably
 * well in practice.
 */

For now you can bypass this "guessing" by using the command line flag --no-bundle.

Will discuss with the team about a potentially "better" way of detecting the type of worker to handle situations like this.

cameron-robey avatar Aug 22 '22 11:08 cameron-robey

Is there any update on this issue? Encountering it using toucan-js and @cfworker/sentry, using the --no-bundle flag does not seem to make a difference.

0x15f avatar Oct 02 '22 21:10 0x15f

I'm also experiencing this issue, and it seems to be a bug in Wrangler itself.

By inspecting the outputs of esbuild.build in guessWorkerFormat, it seems like esbuild is appending the following:

export default require_build();

Thus, wrangler detects that I have a default export, and incorrectly assumes that I am using module worker syntax.

I believe this is happening, because esbuild is being run with format: "esm", so it wraps the bundle in a __commonJS({ ... }) interop wrapper, and exports that as default:

var __getOwnPropNames = Object.getOwnPropertyNames;
var __commonJS = (cb2, mod) => function __require() {
  return mod || (0, cb2[__getOwnPropNames(cb2)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var require_build = __commonJS({
  "build/index.js"(exports, module) {

    // ... my bundled code here ...
    
  }
});
export default require_build();

jimmed avatar Dec 12 '22 14:12 jimmed

I'm also seeing this failure, but only in NODE_ENV=development builds of our remix project. wrangler dev works fine but NODE_ENV=development wrangler dev fails.

We're using the [build.command] in wrangler.toml to run remix build which creates a single build/index.js entrypoint.

It's a bit hard to debug where the issue's coming from but I do see a typeof module in the failing dev builds that's not in the passing builds

> ack 'typeof module' path/to/build/index.js
      typeof exports == "object" && typeof module < "u" ? r2(exports) : typeof define == "function" && define.amd ? define(["exports"], r2) : (e2 = e2 || self, r2(e2.stylis = {}));

We first ran into this a few months ago while upgrading from remix 1.6.8 to remix 1.7.2. We could reliably trigger the issue by switching those versions, but couldn't figure out the source of the issue.

Since remix can only run the service-worker format at the moment https://github.com/cloudflare/wrangler2/issues/1668, and because we need to create dev builds (e.g. for profiling), we used this patch to bypass the issue until it's resolved

diff --git a/node_modules/wrangler/wrangler-dist/cli.js b/node_modules/wrangler/wrangler-dist/cli.js
index c999f82..fd9d75d 100644
--- a/node_modules/wrangler/wrangler-dist/cli.js
+++ b/node_modules/wrangler/wrangler-dist/cli.js
@@ -141752,7 +141752,7 @@ async function guessWorkerFormat(entryFile, entryWorkingDirectory, hint, tsconfi
     absWorkingDir: entryWorkingDirectory,
     metafile: true,
     bundle: false,
-    format: "esm",
+    /* format: "esm", // see https://github.com/cloudflare/wrangler2/issues/1668 https://github.com/cloudflare/wrangler2/pull/2396#issuecomment-1346940067 https://github.com/cloudflare/wrangler2/pull/2396#issuecomment-1347312494 */
     target: "es2020",
     write: false,
     loader: {
original patch before we saw https://github.com/cloudflare/wrangler2/pull/2396#issuecomment-1346940067
diff --git a/node_modules/wrangler/wrangler-dist/cli.js b/node_modules/wrangler/wrangler-dist/cli.js
index c999f82..a596b06 100644
--- a/node_modules/wrangler/wrangler-dist/cli.js
+++ b/node_modules/wrangler/wrangler-dist/cli.js
@@ -141778,7 +141778,7 @@ async function guessWorkerFormat(entryFile, entryWorkingDirectory, hint, tsconfi
   const scriptExports = entryPoints[0][1].exports;
   if (scriptExports.length > 0) {
     if (scriptExports.includes("default")) {
-      guessedWorkerFormat = "modules";
+      guessedWorkerFormat = "service-worker"; console.log("patch to force 'service-worker' format"); /* Remix can *only* ship service-workers on Cloudflare https://github.com/cloudflare/wrangler2/issues/1668 & https://github.com/remix-run/remix/issues/764 */
     } else {
       logger.warn(
         `The entrypoint ${import_node_path10.default.relative(

failing-remix-development.js.zip working-remix-production.js.zip

jfsiii avatar Dec 12 '22 18:12 jfsiii

Following up to say we updated to 2.11 and everything works as expected without any patching.

jfsiii avatar Feb 28 '23 14:02 jfsiii