Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect Web Workers environment #12

Open
grz0zrg opened this issue Feb 2, 2020 · 3 comments
Open

Detect Web Workers environment #12

grz0zrg opened this issue Feb 2, 2020 · 3 comments

Comments

@grz0zrg
Copy link

grz0zrg commented Feb 2, 2020

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;
}
@ygoe
Copy link
Owner

ygoe commented Jun 21, 2020

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.

@ShenTengTu
Copy link

In the script of Web Workers, the self property returns WorkerGlobalScope object (the Worker global scope).

WorkerGlobalScope - Web APIs | MDN

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;
  }

@darcyparker
Copy link

darcyparker commented Jan 6, 2021

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 are self || window
    • There are edge cases where self || window is undefined... or someone could have done var self=something so first fallback is this.
    • 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...
  • Finally, if this was undefined from the context msgpack.js was imported, the fallbacks self || window will work if some unexpected value wasn't bound to them. It's a risk that someone may have defined var self=something in the context of the import, but it would be unusual; especially if the previous globalThis and this 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants