• babel only does syntax conversion for JS syntax, but not for new JS APIs, such as Map, Set, Promise and other global objects.

  • babel cannot convert methods on global objects, such as the new ES6 Array.find method

1. targets

  • The configuration parameter targets indicates which platforms and which versions we want to support

  • You can also configure the version number of the browser

    • The lower the browser version number, the more polyfill will be introduced

    • The highe r the version number, the less polyfill will be introduced

{
    test: /.js$/,
    use: {
        loader: "babel-loader",
        options: {
            targets: {
            "browsers": ["last 2 versions"] // ["IE 6", "chrome 90"]
          }
        }
    }
}

2. babel-polyfill

babel-polyfill is implemented by adding methods to prototyoe on global objects or built-in objects, with the disadvantage of causing global space pollution

3. useBuiltIns

@babel/preset-env is a plugin preset for converting syntax. By default, it only converts syntax, not API.

useBuiltIns has three options

  • false: the default is false, which means no polyfill processing and full polyfill introduction; if @bebel/polyfill is introduced, all polyfill is introduced regardless of the configured browser compatibility

  • "entry": the entry file introduces @bebel/polyfill

  • "useage": automatically determine what API is used in the code to load on demand

3.1 useBuiltIns: false

{
  test: /.js$/,
  use: {
    loader: "babel-loader",
    options: {
      presets: [
        ["@babel/preset-env", {
            useBuiltIns: false
        }]
      ]
    }
  }
}

3.2 useBuiltIns: "entry"
  • Introduce once in the project entry file (multiple times will report an error)

  • Need to introduce import "@babel/polyfill" in the project entry file

  • will introduce a polyfill that is not compatible with the browser according to the configured browser compatibility

  • Need to specify the version of core-js, default is 2, need to be configured in the entry file import "@babel/polyfill

  • If the version specified for core-js is 3, you need to change import "@babel/polyfill" to import "core-js/stable"; import "regenerator-runtime/runtime" in the entry file

  • core-js is the implementation of the polyfill method

  • The disadvantage is that it will only be introduced according to the browser version, if the code does not use the new API will also introduce the current browser incompatible polyfill
npm install --save core-js@2 npm install --save core-js@3

/src/index.js

// core-js: 2
import "@babel/polyfill";

// core-js: 3
import 'core-js/stable';
import 'regenerator-runtime/runtime';

let sum = (a, b) => a + b;
let promise = Promise.resolve();
console.log([123].find(item => item === 2));

{
  test: /.js$/,
  use: {
    loader: "babel-loader",
    options: {
      presets: [
        ["@babel/preset-env", {
          useBuiltIns: "entry",
          corejs: 3 // corejs: { version: 3 } 
        }]
      ]
    }
  }
}

3.3 useBuiltIns: "usage"

  • If configured as usage, usage will load on demand based on the browser-compatible configuration and the API used in your code

  • When set to usage, there is no need to introduce @babel/polyfill

{
  test: /.js$/,
  use: {
   loader: "babel-loader",
   options: {
      presets: [
        ["@babel/preset-env", {
          useBuiltIns: "usage",
          corejs: 3 // corejs: { version: 3 } 
        }]
      ]
    }
  }
}

4. babel-runtime

  • babel-runtime is a separate package for solving the global space pollution problem with tool functions for compiling modules

  • It is more like an on-demand loading, where you introduce whatever modules you need to use

  • The disadvantage is that you need to introduce everything manually, which is very troublesome and tedious

npm i babel-runtime --save-dev

import Promise from '@babel-runtime/core-js/promise';

let promise = Promise.resolve();

5. babel-plugin-transform-runtime

  • is to solve the problem that multiple files refer to the same helper (helper function) extracted to the runtime

  • The new API global method becomes a local reference and generates multiple method files for exporting

npm i @babel/plugin-transform-runtime @babel/runtime-corejs3 --save-dev

{
  test: /.js$/,
  use: {
    loader: "babel-loader",
    options: {
      presets: [
        ["@babel/preset-env", {
          useBuiltIns: "usage",
          corejs: 3 // corejs: { version: 3 } 
        }]
      ]
    },
    plugins: [
      ["@babel/plugin-transform-runtime", {
        corejs: 3,
        helpers: true
      }]
    ]
  }
}

5.1 corejs: 3

  • When we use ES6 static events or built-in object methods, we automatically refer to babel-runtime/core-js

5.2 helpers: true

  • Remove inline babel helpers and replace them with babel-runtime/helpers

  • Avoid duplicating inline helpers in multiple files

6. Summary

Usual project development

  • For usual project development, @babel/preset-env is used to handle compatibility issues, with the disadvantage of polluting the global variable

  • useBuiltIns: "usage" to determine the browser version and automatically introduce it on demand

  • Reduce repetitive generation of public files by configuring @babel-plugin-transform-runtime with helpers: true to extract into public files

For package and library development

  • Minimize global space pollution

  • You can use @babel-plugin-transform-runtime's corejs:3 to do polyfill compatibility