In an Angular app, I want to check client's browser native support to optional chaining (es2020) in order to load a library which have a modern ES version and a legacy one.
The problem is: Angular compiler (I believe it's actually tsc genera behaviour) transpiles everything to targeted ES version (es6 in my case), breaking the code I would use to check for optional chaining support (breaking in the sense that it won't work to check optional chaining support during runtime):
export function isOpChainingSupported(): boolean {
const opChainingChecker = {
support: true
};
try {
// CODE BEFORE TRANSPILING:
// return opChainingChecker?.support;
//
// TURNS INTO
return
opChainingChecker === null || opChainingChecker === void 0 ?
void 0 :
opChainingChecker.support;
} catch {
return false;
}
}
I tried using moving this code to a function in a plain JS file, using the 'allowJs' TS config in order to import it without errors...no go: tsc ends up transpiling it too.
Now I can see three options I don't really like:
What I wanted to ask is: is there something I'm not seeing? A simpler solution that I've missed?
Sorry in advance if this is a bad question, but I feel like when we "tinker" too much with a problem, it's always better to ask people with a fresh view of the picture!
Cheers!
As I've already went with one of the options described in the question, I thought it would be good to answer it.
In my first attempt, I've tried the "third party library" solution, but it didn't work: when there's a syntax error (which is the case if we use optional chaining in a browser without support), the exception happens before the browser actually runs that code, leading to two results:
So, I needed a way to run the "checker code" in a separate context, in order to keep my main thread (and consequently, my app) from dying. Also, I needed a way to check if the code ran successfully or not.
The final solution I've come up with is a mix between two of the options: I've created a library which loads a simple script testing for optional chaining support, returning a Promise with a boolean indicating the browser's support.
The script is loaded dinamically, by adding a temporary script tag (which isolates the execution from the main context, preventing the SyntaxError from killing the app). In order to improve security, I've used the integrity attribute.
If anyone is going through the same issue, you can use my solution by installing the npm library optional-chaining-checker and following the instructions. I've tried to make it as customizable as I could, but if it doesn't attend your needs, feel free to check out my repository and adapt the code at will!