preface

After fixing the problem of using ES new API after the project is packaged in the old project using core-js@2. Compare the use scenarios and differences of @babel/preset-env, core-js@3, and @babel/ Runtime, and the following information is summarized. If there is improper content, but also hope not stingy correction, rational communication.

What is the Babel

  • Babel is a JS compiler that allows you to compile JS code written to the latest standards down to a generic version that is compatible with browsers and other environments.
  • Babel works out of the box, but if you enter raw code without doing any configuration, the same raw code will be output. If you want to do some real work, you need to addPlugins. Importing the required plug-ins one by one is too tedious, so the official ones are usually usedPresetsThe default is a collection of plug-ins.
  • Official preset: @babel/preset-env

Plug-ins and default execution order

  • Plug-ins execute first, then presets
  • The plug-in set executes from front to back
  • Default sets are executed from back to front

Babel translates the code and splits it into two parts

  • syntax(syntax) : arrow functions, lets, const, expansion operators, etc
  • api: Promise, includes, map, etc
  • Babel does not convert syntax and API by default, conversion of syntax, but not the API, using @babel/preset-env or babel-Runtime. You need to use the gasket (Polyfill) transformation API, which makes new built-in functions, instance methods, and so on available in lower-release environments.

Two polyfill schemes are officially offered

  • babel-polyfill: will pollute the global suitable for business projects. (Since Babel7.4.0, Babel/Polyfill has been deprecated and core-js is recommended)
  • babel-runtime: Non-polluting global is suitable for use in component or library projects.

Create a catalog of projects to compare several common Polyfill configurations

Create demo folder Go to the SRC folder and create the index.js file mkdir demo && CD $_ && mkdir SRC && CD $_ && touch index.js # with the default configuration to initialize package.json NPM init -y NPM install --save-dev @babel/ core-babel /cliCopy the code

SRC /index.js to compile

1. Do not perform any configuration

After configuring NPM Scripts for package.json, run NPM run build

  "scripts": {
    "build": "babel src --out-dir lib"
  },
Copy the code

NPM version 5.2 and above, you can also run the compile command: NPX Babel SRC –out-dir lib

You’ll notice that the output lib/index.js file is the same as the original code before compilation.

Add files to the root directory:

  • Babel.config. json (Babel configuration file)
  • .browserslistrc (declares a collection of browsers, according to which the collection describes the specific output compatibility code)

Take a look at what happens when you use configuration and browser policies.

2.@babel/preset-env

  • Convert syntax (class, typeof, arrow function), not API (map, includes)
  • Syntax’s conversion policy changes according to browser policy (configured in the.browserslistrc file)
  • Install: NPM i@babel /preset-env -d

Add the following code to the babel.config.json file

{
    "presets": [["@babel/preset-env"]]}Copy the code

Set up browsers compatible with earlier versions

// .browserslistrc
>0.25%
Copy the code

The compiled code looks like thisSet a browser compatible with a later version

//.browserslistrc
Chrome > 75
Copy the code

3.@babel/preset-env + core-js@3

  • Convert syntax and API.
  • Syntax and API conversion policies change depending on browser policy.
  • Polyfill was introduced from core-js@3.
  • Install: NPM I core-js@3 -s
  • The size of the file packaged with Webpack is about 23KB.
{
    "presets": [["@babel/preset-env",
            {
                "corejs": 3."useBuiltIns": "usage"}}]]Copy the code

A brief introduction to the useBuiltIns configuration item: The default value is false. The usage and entry values can be used

  • usage: There is no need to manually import ‘@babel/polyfill’. Polyfill is automatically added on demand based on the new API used by browserList + business code
  • entry: Manually import ‘@babel/polyfill’ to split polyfill into non-browser-supported polyfills according to the browser version in BrowserList. This results in polyfills that are not actually needed being packaged into the output file, resulting in a larger file.
  • false: Polyfill is disabled. If you import ‘@babel/polyfill’, all polyfills will be loaded in regardless of browserList.
  • New versions of Babel will prompt you to introduce core-js or regenerator-Runtime/Runtime directly instead of @babel/polyfill.

Target browser: >0.25%

Target browser: Chrome > 75

4.@babel/preset-env + @babel/runtime-corejs3 + @babel/plugin-transform-runtime

  • API transformations change based on policy.
  • Syntax transformations change according to policy.
  • NPM I @babel/plugin-transform-runtime -d @babel/ runtime-corejs3-s
  • The size of the file packed with Webpack is about 26KB.

@babel/plugin/transform-runtime

  • The plugin – transform – runtime forCompile timeTranslated code, true polyfill in the codeThe runtimeFrom Babel/Runtime, so plugin-transform-Runtime needs to be installed inThe development environment, while Babel/Runtime is installed inThe production environment.

@ Babel/runtime and @ Babel/runtime – corejs3:

  • @ Babel /runtime Helpers, regenerator-runtime You can only handle syntax.
  • Babel /runtime-corejs3 Includes helpers, regenerator-Runtime, and core-js@3. Introduce the core-js@3 processing API.

Select the corresponding package according to corejs’ options:

Babel inserts helpers in front of each code that needs to be converted, which can result in multiple files having duplicate helpers. Helpers: true at @babel/plugin-transform-runtime helpers: true at @babel/plugin-transform-runtime helpers: true

{
    "plugins": [["@babel/plugin-transform-runtime",
            {
                "corejs": 3."helpers": true."regenerator": false
            }
        ]yu
    ],
    "presets": [["@babel/preset-env"]]}Copy the code

Target browser: >0.25%

Target browser: Chrome > 75

5. Use @babel/preset-env + core-js@3 + @babel/ plugin-transform-Runtime + @babel/runtime-corejs3

  • Core-js sets translation API, Runtime sets false does not translate API.
  • Runtime converts syntax, not API, core-js converts API.
  • Runtime extracts helper code to reduce duplicate code, and Core-js is introduced on demand using the latest version.
  • The size of the file packed with Webpack is about 12KB,The smallest.
{
    "plugins": [["@babel/plugin-transform-runtime",
            {
                "corejs": false."helpers": true."regenerator": false}]],"presets": [["@babel/preset-env",
            {
                "corejs": 3."useBuiltIns": "usage"}}]]Copy the code

Target browser: >0.25%

Target browser: Chrome > 75

6. Use @babel/preset-env + core-js@3 + @babel/ plugin-transform-Runtime + @babel/runtime-corejs3, core-js and Runtime to set the translation API

  • The runtime does not translate the syntax and API repeatedly, and the output is the same as configuration 4.
{
    "plugins": [["@babel/plugin-transform-runtime",
            {
                "corejs": 3."helpers": true."regenerator": false}]],"presets": [["@babel/preset-env",
            {
                "corejs": 3."useBuiltIns": "usage"}}]]Copy the code

Conclusion:

  • The smallest compiled volume of code for individual tests is configuration 5: Use core-js useBuiltIns setting to introduce helper code for polyfill with @babel/ plugin-transform-Runtime to extract duplicate code as needed.
  • The official recommended usage is: useBuiltIns polyfill global scope added, @babel/ plugin-transform-Runtime polyfill non-global scope added, using one configuration depending on the usage scenario.