postMessage is 'undefined' and throws 'setImmediate is not defined' error
Opened this issue · 7 comments
We are using setImmediate through a Promise polyfill (https://github.com/taylorhakes/promise-polyfill) and for the most part it is working perfectly. However, on a few sites, it is throwing a "setImmediate is not defined" error. I have traced the problem down to where it looks for postMessage
(https://github.com/YuzuJS/setImmediate/blob/master/setImmediate.js#L87)
It is not getting through that if statement because postMessage
is returning as undefined.
However, when I type postMessage
in the console, it shows up as a function.
Is there a way that we can check to see if postMessage
is available in the window object as well as in the global?
Am I missing something here?
We have two sites this is happening on and hundreds of sites where there is no issue (including all our dev sites).
I've done some additional digging and it looks like the conflict arises when another script sets self
as a global. This force setImmediate
to use that variable instead of the true global: https://github.com/YuzuJS/setImmediate/blob/master/setImmediate.js#L186
For example, one of the sites has this code:
function TradeShowROICalculator() {
(selector = ".tradeshow-container"),
(self = this),
$(selector)
.on("blur", "input", function() {
readInputField(self, this);
})
.find("input")
.each(function() {
readInputField(self, this);
});
}
So then when I output self before setImmediate
runs, this is what I get:
Any thoughts on how to resolve this?
It sounds like you nailed the origin of the problem by noticing that a global variable self
was set by another library. Since setImmediate uses self
on its last line of code, you can change it from this:
}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));
To something like this:
}(typeof global === "undefined" ? typeof window === "undefined" ? this : window : global));
Any thoughts on how to resolve this?
Fix the broken code on the site. It should not be setting a global self
.
@shuckster after further debugging I realized that webpack was directly adding in setImmediate
(not the other polyfill). In order to fix this, I had to set setImmediate: false
in my webpack config. I then manually added setImmediate
and modified it by passing in window
to get it to work. Works for now, but not ideal. Would love to use setImmediate
right out of the box.
Fix the broken code on the site. It should not be setting a global self.
Our code is running on clients sites, just like setImmediate is running in our code. We have no control over those global variables.
https://developer.mozilla.org/en-US/docs/Web/API/Window/self. No code should be setting the global self
. Even so, setImmediate
should probably prefer window
to self
.
Agreed. I have relayed to the site owners the need to fix that, but it's out of my hands at this point. I agree that setImmediate
should prefer window
though.