@babel/polyfill
As of Babel 7.4.0, this package has been deprecated in favor of directly including core-js/stable (to polyfill ECMAScript features):
If you are compiling generators or async function to ES5, and you are using a version of @babel/core or @babel/plugin-transform-regenerator older than 7.18.0 , you must also load the regenerator runtime package. It is automatically loaded when using @babel/preset-env 's useBuiltIns: "usage" option or @babel/plugin-transform-runtime .
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 ).
This means you can use new built-ins like Promise or WeakMap , static methods like Array.from or Object.assign , instance methods like Array.prototype.includes , and generator functions (provided you use the regenerator plugin). The polyfill adds to the global scope as well as native prototypes like String in order to do this.
Installation
- npm
- Yarn
Because this is a polyfill (which will run before your source code), we need it to be a dependency , not a devDependency
The polyfill is provided as a convenience but you should use it with @babel/preset-env and the useBuiltIns option so that it doesn't include the whole polyfill which isn't always needed. Otherwise, we would recommend you import the individual polyfills manually.
TC39 Proposals
If you need to use a proposal that is not Stage 4, @babel/polyfill will not automatically import those for you. You will have to import those from another polyfill like core-js individually. We may work towards including this as separate files in @babel/polyfill soon.
Usage in Node / Browserify / Webpack
To include the polyfill you need to require it at the top of the entry point to your application.
Make sure it is called before all other code/require statements!
If you are using ES6's import syntax in your application's entry point, you should instead import the polyfill at the top of the entry point to ensure the polyfills are loaded first:
With webpack, there are multiple ways to include the polyfills:
If useBuiltIns: 'usage' is specified in .babelrc then do not include @babel/polyfill in either webpack.config.js entry array nor source. Note, @babel/polyfill still needs to be installed.
If useBuiltIns: 'entry' is specified in .babelrc then include @babel/polyfill at the top of the entry point to your application via require or import as discussed above.
If useBuiltIns key is not specified or it is explicitly set with useBuiltIns: false in your .babelrc, add @babel/polyfill directly to the entry array in your webpack.config.js .
- If @babel/preset-env is not used then add @babel/polyfill to webpack entry array as discussed above. It can still be added at the top of the entry point to application via import or require , but this is not recommended.
We do not recommend that you import the whole polyfill directly: either try the useBuiltIns options or import only the polyfills you need manually (either from this package or somewhere else).
Usage in Browser
Available from the dist/polyfill.js file within a @babel/polyfill npm release. This needs to be included before all your compiled Babel code. You can either prepend it to your compiled code or include it in a <script> before it.
NOTE: Do not require this via browserify etc, use @babel/polyfill .
Introduction to Babel
Babel is a JavaScript compiler. Babel transpiles/converts modern JavaScript ( ECMAScript 2015+ ) code into a backward compatible version of JavaScript in current and older browsers or environments.
Features of Babel
Here are the main things Babel can do for you:
- Transform syntax
- Polyfill features that are missing in your target environment (through @babel/polyfill)
- Source code transformations
Plugins
Babel is a compiler (source code => output code). Like many other compilers it runs in 3 stages: parsing, transforming, and printing.
Now, out of the box, Babel doesn’t do anything. It basically acts like const babel = code => code; by parsing the code and then generating the same code back out again. You will need to add plugins for Babel to do anything.
Babel is built on a plugin system that parses your modern JavaScript into an AST ( Abstract Syntax Tree ) and rewrites it into a version that can be interpreted by the browser.
Babel plugins are small JavaScript programs that instruct Babel on how to carry out transformations to the code.
Since Babel plugins are small, so generally one plugin covers one feature.
Presets
Instead of adding all the plugins we want one by one, we can use a “preset” which is just a pre-determined set of plugins.
Babel’s concept of presets, helps us determine which feature you want to use broadly. So Presets are groups of plugins that babel uses for its transpilation.
Common ones are :
@babel/preset-env
@babel/preset-flow
@babel/preset-react ( for React and it supports JSX Syntax )
@babel/preset-typescript
@babel/preset-env
@babel/preset-env is a smart preset that allows you to use the latest JavaScript without needing to micromanage which syntax transforms (and optionally, browser polyfills) are needed by your target environment(s). This both makes your life easier and JavaScript bundles smaller!
Without any configuration, this preset will include all plugins to support modern JavaScript (ES2015, ES2016, etc.)
Why use @babel/preset-env?
Earlier we used to transpile arrow functions to ES5 using ‘babel-plugin-transform-es2015-arrow-functions’ plugin. The problem is that most of the browsers are getting better day by day, and many of them now support the latest JavaScript features like arrow functions. If they support it then you don’t want to transpile it because if you do then your app gets bigger and slower. So in babel 7 they introduced @babel/preset-env
The most popular preset is @babel/preset-env because it helps us specify what level of compatibility you need for the targets you intend to support and babel will automatically install the appropriate transformation plugin
For example, you can create a .babelrc file in the root of your project. and add support for last 2 versions of the browser.
This will ensure that when the browser is updated it will stop transpiling of the old browser version and will transpile for the new one.
Configuration files:
Presets can take options too. Rather than passing both cli and preset options from the terminal, let’s look at another way of passing options in the configuration files.
There are two types of configuration files . You can use either of those based on your requirement:
1-babel.config.js ( Project-wide configuration: You can use it if you want to programmatically create configuration or if you want to compile node modules )
2-.babelrc ( File-relative configuration: If you have a static configuration that only applies to a single package ) https://babeljs.io/docs/en/config-files#file-relative-configuration
You can often place all of your repo configurations in the root babel.config.js . With "overrides", you can easily specify the configuration that only applies to certain subfolders of your repository, which can often be easier to follow than creating many .babelrc files across the repo.
.babelrc
Its a configuration file for babel. You can specify here:
-Which plugins and presets to be used.
-Which files to ignore
-And different settings for different targets
You can also put these settings in your package.json file but it is done a little less frequently. Many projects include babel with a bundler like webpack as part of their compilation pipeline, but you can still use babel by itself.
Babel loads .babelrc (and .babelrc.js / package.json#babel ) files by searching up the directory structure starting from the "filename" being compiled.
Modules: false means Hey babel don’t do anything with the modules let webpack handle it. Webpack now understands modules natively, it does not have to worry about common js. So babel only includes the code for a function that you are using from the node_modules and not the rest of it. This is called tree shaking or live code inclusion
- Plugins run before Presets.
- Plugin order is first to last.
- Preset ordering is reversed (last to first).
Polyfill
A polyfill is code that implements a feature on web browsers that do not support the feature.
When we use modern features of the language, some engines may fail to support such code. Here Babel comes to the rescue
In order for certain features to work they require certain polyfills. You can satisfy all Babel feature requirements by using @babel/polyfill.
There are two parts in Babel:
a-Transpile the code
b-Polyfill.
The transpiler rewrites the code, so syntax features are covered. But for new functions, we need to write a special script that implements them. JavaScript is a highly dynamic language, scripts may not just add new functions, but also modify built-in ones so that they behave according to the modern standard. There’s a term “polyfill” for scripts that “fill in” the gap and add missing implementations.
@babel/polyfill
Since Babel assumes that your code will run in an ES5 environment it uses ES5 functions. So if you’re using an environment that has limited or no support for ES5 such as lower versions of IE then using @babel/polyfill will add support for these methods. Make sure to add it as a dependency and not dev dependency. If you don’t install and configure @babel/polyfill then babel will not be able to convert the async await functions to a javascript that most browsers can understand and you will get an error.
Полифилы
JavaScript – динамично развивающийся язык программирования. Регулярно появляются предложения о добавлении в JS новых возможностей, они анализируются, и, если предложения одобряются, то описания новых возможностей языка переносятся в черновик https://tc39.github.io/ecma262/, а затем публикуются в спецификации.
Разработчики JavaScript-движков сами решают, какие предложения реализовывать в первую очередь. Они могут заранее добавить в браузеры поддержку функций, которые всё ещё находятся в черновике, и отложить разработку функций, которые уже перенесены в спецификацию, потому что они менее интересны разработчикам или более сложные в реализации.
Таким образом, довольно часто реализуется только часть стандарта.
Можно проверить текущее состояние поддержки различных возможностей JavaScript на странице https://kangax.github.io/compat-table/es6/ (нам ещё предстоит изучить многое из этого списка).
Babel
Когда мы используем современные возможности JavaScript, некоторые движки могут не поддерживать их. Как было сказано выше, не везде реализованы все функции.
И тут приходит на помощь Babel.
Babel – это транспилер. Он переписывает современный JavaScript-код в предыдущий стандарт.
На самом деле, есть две части Babel:
Во-первых, транспилер, который переписывает код. Разработчик запускает Babel на своём компьютере. Он переписывает код в старый стандарт. И после этого код отправляется на сайт. Современные сборщики проектов, такие как webpack или brunch, предоставляют возможность запускать транспилер автоматически после каждого изменения кода, что позволяет экономить время.
Новые возможности языка могут включать встроенные функции и синтаксические конструкции. Транспилер переписывает код, преобразовывая новые синтаксические конструкции в старые. Но что касается новых встроенных функций, нам нужно их как-то реализовать. JavaScript является высокодинамичным языком, скрипты могут добавлять/изменять любые функции, чтобы они вели себя в соответствии с современным стандартом.
Термин «полифил» означает, что скрипт «заполняет» пробелы и добавляет современные функции.
Два интересных хранилища полифилов:
-
поддерживает много функций, можно подключать только нужные. – сервис, который автоматически создаёт скрипт с полифилом в зависимости от необходимых функций и браузера пользователя.
Таким образом, чтобы современные функции поддерживались в старых движках, нам надо установить транспилер и добавить полифил.
Примеры в учебнике
Большинство примеров можно запустить «на месте», как этот:
Примеры, в которых используются современные возможности JS, будут работать, если ваш браузер их поддерживает.
Google Chrome обычно поддерживает современные функции, можно запускать новейшие примеры без каких-либо транспилеров, но и другие современные браузеры тоже хорошо работают.
Name already in use
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
A set of Babel plugins that enable injecting different polyfills with different strategies in your compiled code. Additionally, this repository contains a package that helps with creating providers for other polyfills.
ℹ️ This repository implements what was initially proposed at babel/babel#10008.
If you are looking for some quick setup examples, or just want to see how to migrate your config, please check docs/migration.md .
The main Babel packages only transform JavaScript syntax: you also need to load a polyfill, to make native functions ( Array.prototype.flat ) or built-in objects ( Reflect ) work in older browsers.
The easiest way to do so is to directly load the polyfill using a <script . > tag:
However, this simple approach can potentially include a lot of unnecessary code. The Babel plugins implemented in this repository automatically inject the polyfills in your code, while trying to only load what is really needed. It does this based on your compilation targets and on what you are using in your code.
These plugins (we are calling them «polyfill providers») support different injection methods, to better fit your needs.
For example, if you want to inject imports to es-shims polyfills by adding the missing functions to the global objects, you could configure Babel as such:
If you want to see more configuration examples, you can check the migration docs: docs/migration.md .
If you are interested in reading about all the options supported by these plugins, you can check the usage docs: docs/usage.md .
| Polyfill | Plugin | Methods |
|---|---|---|
| core-js@2 | babel-plugin-polyfill-corejs2 | entry-global , usage-global and usage-pure |
| core-js@3 | babel-plugin-polyfill-corejs3 | entry-global , usage-global and usage-pure |
| es-shims | babel-plugin-polyfill-es-shims | usage-global and usage-pure |
| regenerator-runtime | babel-plugin-polyfill-regenerator | entry-global , usage-global and usage-pure |
We are maintaining support for core-js and es-shims , but we encourage you to implement a provider for your own polyfill, or for your favorite one! One of our goals is to encourage competition between different polyfills, to better balance the different trade offs like spec compliancy and code size.
If you want to implement support for a custom polyfill, you can use @babel/helper-define-polyfill-provider . ( docs/polyfill-provider.md .)
Polyfill plugins can expose three different injection methods: entry-global , usage-global and usage-pure . Note that polyfill plugins don’t automatically add the necessary package(s) to your dependencies, so you must explicitly list them in your package.json .
ℹ️ All the examples assume that you are targeting Chrome 62.
The entry-global method replaces a single simple import to the whole polyfill with imports to the specific features not supported by the target environments. It is most useful when you want to be sure that every unsupported function is available, regardless of what you are using in the code you are compiling with Babel. You might want to use this method if:
- you are not compiling your dependencies, but you want to be sure that they have all the necessary polyfills;
- Babel’s detection logic isn’t smart enough to understand which functions you are using;
- you want to have a single bundled file containing all the polyfills, without needing to regenerate it when your code changes.
The usage-global method injects imports to polyfills attached to the global scope, but only for unsupported features which are used in your code. You might want to use this method if:
- you need to keep your code size as small as possible, and only include what is effectively used;
- your polyfill doesn’t support a single entry point, but each of its features must be loaded separately.
The usage-pure method injects imports to polyfills for unsupported features which are used in your code, without attaching the polyfills to the global scope but importing them as normal functions. You might want to use this method if:
- you are a library author, and don’t want to «pollute» the global scope with the polyfills you are loading.
History and Motivation
In the last three years and a half, @babel/preset-env has shown its full potential in reducing bundle sizes not only by not transpiling supported syntax features, but also by not including unnecessary core-js polyfills.
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;
- By using @babel/preset-env ‘s useBuiltIns: «usage» , Babel will only inject self-installing polyfills for unsupported ECMAScript features but only if they are actually used in the input souce code;
- By using @babel/plugin-transform-runtime , Babel will inject «pure» polyfills (which, unlike self-installing ones, don’t pollute the global scope) for every used ECMAScript feature supported by core-js . This is usually used by library authors.
Our old approach has two main problems:
- It wasn’t possible to use @babel/preset-env ‘s targets option with «pure» polyfills, because @babel/plugin-transform-runtime is a completely separate package.
- We forced our users to use core-js if they wanted a Babel integration. core-js is a good and comprehensive polyfill, but it doesn’t fit the needs of all of our users.
With this new packages we are proposing a solution for both of these problem, while still maintaining full backward compatibility.
Want to contribute?
See our CONTRIBUTING.md to get started with setting up the repo.
About
A set of Babel plugins that enable injecting different polyfills with different strategies in your compiled code.