简体   繁体   中英

How can I use the regenerator-runtime polyfill conditionally?

This article inspired me to externalise the polyfills that I'm loading for my React app and only load them for browsers that need them. A simple test:

function browserSupportsAllFeatures() {
  return window.Promise && window.fetch && window.regeneratorRuntime
}

Will then determine if polyfills should be loaded:

if (browserSupportsAllFeatures()) {
  // Browsers that support all features run `main()` immediately.
  main()
} else {
  // All other browsers loads polyfills and then run `main()`.
  loadScript('/path/to/polyfills.js', main)
}

function main(err) {
  // Initiate all other code paths.
  // If there's an error loading the polyfills, handle that
  // case gracefully and track that the error occurred.
}

However, I'm using generators in my code and that seems to be a bit of an edge-case. From what I understand babel transforms generators ( https://babeljs.io/docs/plugins/transform-regenerator/ ) and the transpiled code will then also need regeneratorRuntime to be defined (with this package ).

So my app fails because regeneratorRuntime is not defined when App is imported (which contains code that uses generators). So my polyfills are too late:

// import dependencies
import React from 'react'
import { render } from 'react-dom'
import { App } from './components/app'

const renderApp = () => {
  render(<App />, document.getElementById('app'))
}

function browserSupportsAllFeatures() {
  return window.Promise && window.fetch && window.regeneratorRuntime
}

if (browserSupportsAllFeatures()) {
  renderApp()
} else {
  loadScript('/path/to/polyfills.js', renderApp);
}

I know I could fix this by importing regenerator at the the top, but the intention here is to externalise polyfills and make them conditional.

So my question is; how can I keep using generators, but still keep my polyfills contained to the loadScript call?

You can check the property using:

if (window.hasOwnProperty("regeneratorRuntime")) ...

There is npm package polyfill-io-feature-detection which does exactly the same, take a look to this solution to see how it handle the feature detection: https://github.com/jquintozamora/polyfill-io-feature-detection

Async functions / generators are supported in most modern browsers. It's not supported in IE though.

From what I understand, it's not possible to add a polyfill purely dynamically. So you would have to generate another bundle of your app for browsers that don't support it (in general that don't support es6).

There is an article that explains really well how to do that. https://philipwalton.com/articles/deploying-es2015-code-in-production-today/

Basically it relies on <script type="module">

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM