I'm making changes to an existing Angular SPA which is sometimes viewed within an application's in-product browser. The application exposes several functions on window.external.Handle to allow pages to interact with certain features in the application or pull details from the application (think application version, license details, etc).
I have the following code (which works on another site that doesn't use grunt-contrib-uglify):
function isInProduct() {
if (typeof window.external !== undefined && typeof window.external !== "undefined") {
if (typeof window.external.Handle !== undefined && typeof window.external.Handle !== "undefined") {
alert('in-product')
return true;
} else {
return false;
}
} else {
return false;
}
}
If I grunt serve
the files locally, the pages work as expected. When I serve the dist or UAT builds (both of which include the uglify task), areas of the site that call the above function fail to render correctly.
I've tracked this down to the uglified version below:
function e(e,t){return{isInProduct:function(){return void 0!==window.external&&void 0!==typeof window.external&&void 0!==window.external.Handle&&void 0!==typeof window.external.Handle}
Changing 'void 0!==window.external'
and 'void 0!==window.external.Handle'
to '"undefined"!==typeof window.external'
and '"undefined"!==typeof window.external.Handle'
respectively solves the problem and the pages render correctly in all instances.
I can see why uglify is attempting to simplify the code in this way but believe it's incorrect in doing so - it does not treat the string "undefined" as a string in its output (the application has some quirks and will return strings instead of keywords/booleans) and thus breaks the code. How do I prevent it from doing this?
After doing some more research, I came across this question, which provided a more succinct way of checking for the existence of in-product functions.
Using the suggested check resulted not only in cleaner code but also uglified without issues. Adapted to my problem, the code is as follows:
function isIsProduct() {
return ('Handle' in window.external);
}