msgpack.js
msgpack.js copied to clipboard
Detect Web Workers environment
When the library is used in a web worker there is an issue with undefined window
so i suggest adding Web Workers detection such as :
// Environment detection
if (typeof module === "object" && module && typeof module.exports === "object") {
// Node.js
module.exports = msgpack;
}
else if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
// Global object
self[self.msgpackJsName || "msgpack"] = msgpack;
} else {
// Global object
window[window.msgpackJsName || "msgpack"] = msgpack;
}
Unfortunately I have no idea about web workers. This answer suggests that your suggested code change won't work very well. And I couldn't find out what that self
is. I'll leave this open until somebody provides a reliable alternative.
In the script of Web Workers, the self
property returns WorkerGlobalScope
object (the Worker
global scope).
I reference the solution from the other library:
// Environment detection
if (
typeof module === "object" && module && typeof module.exports === "object"
) {
// Node.js
module.exports = msgpack;
} else {
// Global object
var g;
if (typeof window !== "undefined") {
g = window;
} else if (typeof global !== "undefined") {
g = global;
} else if (typeof self !== "undefined") {
g = self;
} else {
g = this;
}
g[g.msgpackJsName || "msgpack"] = msgpack;
}
https://caniuse.com/?search=globalThis https://mathiasbynens.be/notes/globalthis has discussion on polyfills
Based on the above, pass the globalThis into your IIFE like this:
(function (_global) { //bind globalThis to _global
...
// Environment detection
if (typeof module === "object" && module && typeof module.exports === "object") {
// Node.js
module.exports = msgpack;
}
else if (_global) {
// Global object
_global[_global.msgpackJsName || "msgpack"] = msgpack;
}
)(globalThis || this || self || window);
Notes:
- Assumes no one bound something unexpected to
globalThis
from the context you call the IIFE. - In most modern JS environments
globalThis
will be defined and that's what will be used - If the JS environment is older, first fallback is
this
.- There are edge cases where
this
is not defined, so the next fallbacks areself || window
- There are edge cases where
self || window
is undefined... or someone could have donevar self=something
so first fallback isthis
. - It is possible someone imported or called your IIFE from something other than the global context. But is this likely? I can't imagine any use case where someone would do this...
- There are edge cases where
- Finally, if
this
was undefined from the context msgpack.js was imported, the fallbacksself || window
will work if some unexpected value wasn't bound to them. It's a risk that someone may have definedvar self=something
in the context of the import, but it would be unusual; especially if the previousglobalThis
andthis
were not defined.
There won't be any perfect solution to polyfill globalThis
... but this is decent I think.
Another option is to not define global.mspack
. and instead just support commonJS and expect browsers to use an applicable module loader that supports commonjs.