Consider adding `self.location` to the worker global scope.
johnspurlock opened this issue · comments
A common way for Cloudflare-unaware JS libraries to check if they are running in a web worker is: typeof importScripts == 'function'
.
Once this passes, they assume other web-standard API like self.location
is defined.
Perhaps workerd could use a blob url as the location
here instead of leaving it undefined?
Not sure there's really sufficient use case justification for this. How would you expect to use it? I'll note that none of the other primary non-browser runtimes (node.js, deno, bun, etc) implement self.location
.
I ran into emscripten js boilerplate that does a "am I running in a web worker" check using typeof importScripts = 'function'
. That actually passes on CF workers, but later on when it attempts to use self.location
(unchecked, assuming it's there since importScripts
was), it crashes. It just uses the .href
for some default location probing logic.
I have a PR out for that on their side - honestly I was surprised importScripts
was defined at all in CF workers. Does anyone use it? Removing importScripts
would also fix this particular issue.
For Emscripten feature detection I've been doing:
// Force Emscripten to feature detect the way we want
// They used to have an `environment` setting that did this but it has been
// removed =(
globalThis.window = {}; // makes ENVIRONMENT_IS_WEB = true
globalThis.importScripts = 1; // makes ENVIRONMENT_IS_WORKER = false
const p = createEmscriptenModule(emscriptenSettings);
delete globalThis.window;
delete globalThis.importScripts;
const emscriptenModule = await p;
Here's the PR over there in case anyone wants to +1: emscripten-core/emscripten#21010
For workerd tho, I'm still curious why importScripts
exists - never seen a single cloudflare worker example where it is utilized
It's also not implemented:
jsg::Unimplemented importScripts(kj::String s) { return {}; };
Use Unimplemented as the return type of a method to mark the whole method unimplemented.
Attempts to use the API will throw an exception.
So removing it should be pretty harmless...
I'd be fine with removing importScripts(...)
/cc @kentonv
Landed the PR that removes importScripts
with a compatibility flag.
FWIW, the most reliable means of determining if code is running within the workers environment is to check the value of navigator.userAgent
. Given that we've landed the PR removing importScripts
under a compatibility flag, I'm going to go ahead and close this. The change likely would not hit production for another week or two.
@jasnell, I'm getting ReferenceError: navigator is not defined
when trying to access navigator.userAgent
on Cloudflare Workers - am I missing something?
@johnspurlock I'm guessing you don't have the global_navigator
compatibility flag enabled?
@mrbbot ah right, that new worker had no compatibility flag/date at all
{
placement: {},
compatibility_date: "",
compatibility_flags: [],
usage_model: "unbound",
tags: [],
tail_consumers: [],
logpush: false,
bindings: [
...
]
}
After redeploying with a compat date >= 2022-03-21
, navigator.userAgent
is defined, thanks!