lundi 13 juin 2022

Add Intl.Locale polyfill only when needed (How to block script tag with async functions)

I am trying to add Intl polyfill to an ember app, but have run into the issue that I need to add a script tag that executes async functions before evaluating other script tags.

In ember I can add a new <script> tag to index.html, that is placed before the emberjs tags:

<body>
  <script src="assets/polyfills.js"></script>   
  <script src="assets/vendor.js"></script> <-- this throws an exception if polyfill is not loaded for iOS < 14
</body>

Everything works fine when assets/polyfills.js looks like this:

import '@formatjs/intl-locale/polyfill';

However, the issue then is that the polyfill is loaded for all devices - no matter if needed or not. But according to the docs there is way to check wether the polyfill is actually needed https://formatjs.io/docs/polyfills/intl-locale/:

import {shouldPolyfill} from '@formatjs/intl-locale/should-polyfill'
async function polyfill() {
  // This platform already supports Intl.Locale
  if (shouldPolyfill()) {
    await import('@formatjs/intl-locale/polyfill')
  }
}

The problem now is, that I am dealing with an async function and I can't find a way to load the polyfill before any other js code is executed.

I have tried to modify polyfills.js to use top level awaits and enabled the experimental webpack feature topLevelAwait: true, but subsequent code is executed before the polyfill is loaded:

await import('@formatjs/intl-getcanonicallocales/polyfill');

I also tried to wrap it in a function, but that also didn't change anything:

async function load() {
  await import('@formatjs/intl-locale/polyfill');
};
await load();

I also tried things like this, which had exactly the same effect:

(async () => {
  await import('@formatjs/intl-locale/polyfill');
})();

Pretty much the thing that I need would look like this:

if (shouldPolyfill) {
  import '@formatjs/intl-locale/polyfill';
}

However, that is not valid and leads to this error: An import declaration can only be used at the top level of a module.

How do I solve that issue?




Aucun commentaire:

Enregistrer un commentaire