Polyfill services like polyfill.io seem to be delivering only small feature detects to the browser and then lazy-load only the polyfills that are actually needed.
As I understand the babel documentation on polyfilling, babel always include the full set of potentially needed polyfills: it will process a browserslist
and then include those polyfills from core-js that the weakest browsers need. A bundler like webpack would then probably merge all these polyfills into the application, but without runtime feature detects.
My application uses modern ES language features but also targets a wide range of browsers, including IE10 and IE11. That requires a lot of polyfills and will probably bloat the bundle, especially for modern browsers that may not need the most of the polyfills.
So I was wondering: can I tell either babel and/or webpack to only include feature detects, split the polyfills off into separate chunks (individually or into small bundles), and then, at runtime, only "lazy"-load what is actually needed?
Babel includes a polyfill that includes a custom regenerator runtime and core-js. This will emulate a full ES2015+ environment (no < Stage 4 proposals) and is intended to be used in an application rather than a library/tool. (this polyfill is automatically loaded when using babel-node ).
So long story short, just using babel is not enough for your application to work because all the latest Javascript features are not supported in all browsers. So to fix this problem, we need to use a polyfill.
Babel Polyfill adds support to the web browsers for features, which are not available. Babel compiles the code from recent ecma version to the one, which we want. It changes the syntax as per the preset, but cannot do anything for the objects or methods used.
At first, Babel is looking for target browsers needed to be polyfilled in a configuration file such as .babelrc, .babelrc.json, package.json, or babel.config.js. So if you support IE11, you have to write it like this: useBuiltIns: usage is an option that allows injection of a polyfill based on the files used in your project.
@babel/preset-env has an option called useBuiltIns. With this option, you can make Babel cherry-pick polyfills for specific browsers: With useBuiltIns: "entry", Babel will replace the import of core-js – the most common polyfill library – with specific polyfills required for browsers you’re targeting.
So far Babel provided three different ways to inject core-js polyfills in the source code: By using @babel/preset-env 's useBuiltIns: "entry" option, it is possible to inject self-installing polyfills for every ECMAScript functionality not natively supported by the target browsers;
core-js is a library that provides a set of polyfill features. Babel uses core-js-compact and maps it to targeted browsers in order to provide the necessary polyfill feature. So when you target IE11, it’ll map IE11 and provide the polyfill code that IE11 doesn’t support.
Services like polyfill.io investigate your User Agent
against a predefined set and based on that provide you with different bundle of polyfills. What you're trying to do is actually way different.
One solution I could thing of is to introduce code splitting into your build (it is on by default in Webpack 4 production build) and create several files in your project, where each would import a different set of polyfills. This will require you to import polyfills manually, but will allow you to have several polyfill chunks, each with a different subset of missing features. After you will have those chunks, you could use some feature detection (probably Modernizr) on the startup of your application and dynamically load only those chunks which are needed by the browser. Keep in mind that this process is rather cumbersome - you will need to take care of including each polyfill manually. Also another disadvantage of it, it will need to make several requests to the server, which will additionally slow down your app start time.
As to other part of your question - webpack/babel will not do the automatic polyfill chunks splitting and runtime feature checking for you, those will need to be handled manually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With