Babel polyfill is dead. Long live core-js!
January 08, 2020I encountered problems in some projects with core-js versions. After resolving them, I want to share to you my findings
@babel/polyfill is deprecated
@babel/polyfill has been deprecated since babel version of 7.4.0.
@babel/polyfill is combination
of core-js and regenerator-runtime but it tingly coupled to core-js@2 and cannot provide smooth migration to core-js@3
Official @babel/polyfill documentation
Long live core-js
What is core-js? core-js github link
- It is a polyfill of the JavaScript standard library, which supports:
- The latest ECMAScript standard.
- ECMAScript standard library proposals.
- Some WHATWG / W3C standards (cross-platform or closely related ECMAScript).
- It is maximally modular: you can easily choose to load only the features you will be using.
- It can be used without polluting the global namespace.
- It is tightly integrated with
babel: this allows many optimizations ofcore-jsimport.
Long story short - core-js is modularized set of polyfills with can be used independently or with babel
Simplest migration for manual import from @babel/polyfill to core-js is change
import "@babel/polyfill";
to
import "core-js/stable";
import "regenerator-runtime/runtime";
@babel/preset-env with core-js
@babel/preset-env has 2 different modes, which can be enabled with the useBuiltIns option: entry and usage, which optimize imports of core-js in different ways.
Babel 7.4.0 introduces both changes commons to the two modes and specific to each mode.
Since @babel/preset-env now supports core-js@2 and core-js@3, useBuiltIns requires setting a new option, corejs, which specifies the used version (corejs: 2 or corejs: 3). If it isn't directly set, corejs: 2 will be used by default and it will show a warning.
To make it possible for Babel to support new core-js features introduced in future minor versions, you also can specify the minor core-js version used in your project. For example, if you want to use core-js@3.1 and take advantage of new features added in that version, you can set the corejs option to 3.1: corejs: '3.1' or corejs: { version: '3.1' }.
One of the most important parts of @babel/preset-env was the source providing data about the features supported by different target engines, to understand whether something needs to be polyfilled by core-js or not.
Should I use core-js@2 or core-js@3?
Short answer - you should use version 3. Why? Coz it maintainable.
Force core-js@3 by adding concrete dependably
npm i --save-dev core-js@3 @babel/runtime-corejs3
Configure @babel/preset-env in .babelrc to use core-js version 3
presets: [
["@babel/preset-env", {
useBuiltIns: "usage", // or "entry"
corejs: 3,
}]
]
In case you are using @babel/transform-runtime
plugins: [
["@babel/transform-runtime", {
corejs: 3,
}]
]
otherwise, your project will end up unbuildable
Customized preset-env also support core-js
NuxtJS
@nuxt/babel-preset-app also support core-js configuration by extending nuxt.config.js build section:
{
/*
** Build configuration
*/
build: {
babel: {
presets({ isServer }) {
return [
[
'@nuxt/babel-preset-app',
{
buildTarget: isServer ? 'server' : 'client',
corejs: { version: 3 } // or version: 2
}
]
]
}
},
extend(config, ctx) {}
}
}
Also insure to install correct dependency:
npm i --save-dev core-js@2 @babel/runtime-corejs2
Core js build errors
Errors like
Module not found: Error: Can't resolve 'core-js/modules
Indicate what you encounter problem with invalid core-js version. You should force concrete version on your project to eliminate headache. Use -
npm i --save-dev core-js@3 @babel/runtime-corejs3
or
npm i --save-dev core-js@2 @babel/runtime-corejs2