In JavaScript running in a browser, to get the current script URI, one can write like in https://stackoverflow.com/a/57364525/3102264:
let currentPath = import.meta.url.substring(
0, import.meta.url.lastIndexOf("/"));
This works fine in a modern browser, however in an old browser it raises a SyntaxError.
I would like to detect if import.meta is supported in order to use location.href when it is not available.
I tried using try catch like
let currentPath;
try {
currentPath = import.meta.url.substring(
0, import.meta.url.lastIndexOf("/"));
}
catch(e) {
currentPath = location.href.substring(
0, location.href.lastIndexOf("/"));
}
But this is not working, it still throws
Uncaught SyntaxError Unexpected token import
Is there a way to make conditional code depending on import.meta support?
Note: using location.href is an acceptable fallback when served from same based url (even it did not solve what allow import.meta)
As noted in the comments, if you want a fallback for browsers not supporting
import.meta, it’s not going to be as simple as replacingimport.meta.urlwithlocation.href. One will return the URI of the executing script, but the other will return the address of the page on which it runs, which may even be on a completely different domain.That said, I managed to come up with a feature-detector that relies neither on user-agent sniffing, nor on dynamic
import()expressions:How it works: the detector attempts to execute two scripts. If
import.metais supported, the first script executes and resolves the promise with atruevalue; ifimport.metais not supported, the first script triggers a syntax error and does not execute. The second script always executes and attempts to resolve the promise with afalsevalue; if the first script had already executed, this has no effect. I do use a few other advanced features, but those should be much easier to replace or polyfill thanimport.metaitself.It’s a bit finicky: it relies on module scripts being executed in the order they are injected, which I am not sure is actually guaranteed. If you worry about that, you can insert a couple of
setTimeouts and let sleepsort deal with it.