1 overview

Babel itself is a compiler, but the focus of this article is on the subtitle of the website, how to use Babel to help you use the latest version of JS when the current runtime (such as the browser) does not implement the relevant specifications (including ES262 and Web Standard). It is suggested that the two articles be read together.

To do this, Babel needs to do two things

  1. The syntax of the new JS is implemented with the old syntax, so that it can be run at the corresponding runtime, such as the arrow function
  2. Patches (also known as polyfills) in older runtimes to use functionality defined in new versions of JS but provided in older runtimes fall into three categories
    1. Newly defined built-in objects, such asPromise
    2. Static methods added to existing built-in objects, such asArray.from
    3. New instance methods added to existing built-in objects, such asArray.prototype.includes

For the first feature, Babel can convert various new grammars with plug-ins. How to develop plug-ins and how to convert them can also be found in the article above.

For the second function, Babel relies on core-JS, developed by someone who has been looking for a job for years.

The completion of the above two functions will be introduced in detail below. In the first part, the main content of Babel will be discussed. In the second part, core-JS and its combination with Babel will be introduced.

Babel and syntax conversion

The following steps are required to convert the syntax using Babel

  1. Install various packages first
  • Babel core package @babel/core
  • Install @babel/ CLI for command line calls
  • Install plug-ins needed for syntax transformation
  1. Specify plug-ins and other options to use during the transformation, using the configuration

After completing the above steps, run cli commands or related scripts to convert Babel.

2.1 Packages Involved

2.1.1 @ Babel/core

Babel itself, which returns nothing without a plug-in, or else operates on the source code according to the relevant plug-in.

2.1.2 @ Babel/cli

Provides a way to execute Babel from the command line. See the API here

2.1.3 Related plug-ins

Plug-ins are used to guide related syntax parsing and AST processing. The former are called Syntax Plugins and the latter Transform Plugins

Syntax Plugins are generally not operated directly and are automatically enabled when the corresponding Transform Plugins are used

Transform Plugins contain the following categories

  • All versions of ES
  • Modules
  • Experimental grammar
  • To achieve compression
  • react
  • Others, such as typescript and runtime, are covered later

In order to make it easier to use various plug-ins, Babel combines various plug-ins. These combinations are called Presets, and they share the same configuration

  • @babel/preset-env contains all new syntax plug-ins needed for the target environment and is the most commonly used preset, the configuration of which is described in the next chapter in conjunction with Core-JS
  • @ Babel/preset – flow to flow
  • @ Babel/preset – react to react
  • @ Babel/preset – typescript for ts

You can also customize presets

2.2 configuration

2.2.1 Classification of configuration files

Babel accepts a variety of configuration files, including

  • babel.config.json
  • .babelrc.json
  • package.json

Alternatively, it can be specified when the CLI or API is used. Plugin and Preset are mainly specified. For details, see here

2.2.2 Specifying a path

The following forms can be used when a plugin or preset is specified

  • If the plugin is downloaded by NPM, you can pass the plugin name directly, and Babel will go to node_modulesbabel-plugin-Part (Use preset omitted isbabel-preset-), such as
{"plugins": [" myplugins ", "babel-plugin-myplugins" // equivalent]} // or {"plugins": [" myplugins ", "babel-plugin-myplugins" // equivalent]} // or {"plugins": [ "@org/babel-plugin-name", "@org/name" // equivalent ] }Copy the code
  • You can also specify a relative/absolute path for the plug-in
{
  "plugins": ["./node_modules/asdf/plugin"]
}
Copy the code

2.2.3 order

The sequence of plugin or preset affects the execution order of the plug-in visitor, which follows the following rule

  • Plugin takes precedence over preset
  • Plugin from front to back
  • Preset is from back to front

3 polyfill and core – js

Refer to the core-JS official for this section

3.1 polyfill

When it comes to polyfill, a lot of people think of @babel/polyfill, but it’s out of date. It was abandoned for two reasons, according to the archaeological data in the previous link

  • This package simply introduces stable core-js and regenerator-Runtime /runtime, the latter of which can be replaced by the @babel/plugin-transform-regenerator
  • This package does not smoothly transition from core-js@2 to core-js@3

So let’s look at core-JS in detail

3.2 the core – js

3.2.1 What is Core-JS

Core-js can be understood in four ways

  • Polyfill is a JS standard library supported by Polyfill
    • The latest ES standard
    • Es standard proposal
    • web standard
  • Maximum modularity, you can only introduce what you need
  • Can be used without polluting the full name namespace
  • Integrated with Babel, made a lot of optimizations

The most recent and recommended version of Core-JS is core-js@3, which is divided into three packages

  • Core-js defines a global polyfill
  • Core-js-pure does not pollute versions of global variables; instance methods are mainly implemented only in version 3
  • Core-js-bundle core-js is a separate file, which we will not consider in this article because we usually deal with it in a modular way. See the difference between core-js and core-js

3.2.2 How to use Core-js alone: CommonJS API

Core-js can be used either alone or in combination with Babel. Here’s how to use it alone, and see the next chapter for how to use it with Babel.

The usage in this case is to use import directly to introduce the relevant module as needed before any other code within the module

  1. modules path

The node_modules folder is divided into subdirectories that can be imported

  • Es contains features of Stable ECMAScript Features
  • Features includes all core-js Features is a recommendation introduced on demand
  • The proposals contain the proposal features
  • Stable includes all Stable core-JS features and is an on-demand recommendation
  • The stage contains features of ECMAScript proposals
  • The Web contains WHATWG/W3C features

You can also directly import concrete subfiles such as concrete objects or methods

import 'core-js/features/array/from'; // <- at the top of your entry point import 'core-js/features/array/flat'; // <- at the top of your entry point import 'core-js/features/set'; // <- at the top of your entry point import 'core-js/features/promise'; // <- at the top of your entry point Array.from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3] [1, [2, 3], [4, [5]]].flat(2); // => [1, 2, 3, 4, 5] Promise.resolve(32).then(x => console.log(x)); / / = > 32Copy the code

If the directories are not included, they include the features of es, Proposals, and Web subdirectories, for example

import 'core-js'; // <- at the top of your entry point Array.from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3] [1, [2, 3], [4, [5]]].flat(2); // => [1, 2, 3, 4, 5] Promise.resolve(32).then(x => console.log(x)); / / = > 32Copy the code
  1. Do not pollute global variables

As mentioned above, core-js-pure is the version that does not pollute global variables. Static methods and static methods can be used directly. If the current environment contains this feature, such as Set, it will be overwritten by introduced modules, you can consider using an alias.

import from from 'core-js-pure/features/array/from'; import flat from 'core-js-pure/features/array/flat'; import Set from 'core-js-pure/features/set'; import Promise from 'core-js-pure/features/promise'; from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3] flat([1, [2, 3], [4, [5]]], 2); // => [1, 2, 3, 4, 5] Promise.resolve(32).then(x => console.log(x)); / / = > 32Copy the code

When working with instance methods, prototype methods cannot be directly converted to static methods as in other scenarios, which are implemented in core-js@3 using the binding operator (that is ::) plus further compilation. Methods in the /virtual/ directory should be introduced

import fill from 'core-js-pure/features/array/virtual/fill'; import findIndex from 'core-js-pure/features/array/virtual/find-index'; Array(10)::fill(0).map((a, b) => b * b)::findIndex(it => it && ! (it % 8)); // => 4 // or import { fill, findIndex } from 'core-js-pure/features/array/virtual'; Array(10)::fill(0).map((a, b) => b * b)::findIndex(it => it && ! (it % 8)); / / = > 4Copy the code

4 use Babel in combination with core-js

Core-js can be simplified using plug-ins in Babel. Note do not configure core-js at the same time. Otherwise, conflicts may occur.

4.1 @ Babel/preset – env

The useBuiltIns option indicates the use of the global version of Core-JS, which is represented by the corejs parameter, and can add proposals: True to implement the features in the proposal

Corejs: {version: '3.8', proposals: true}Copy the code

Also don’t forget to install the core-JS package for the global version

npm install core-js@3 --save

Copy the code

Refer to the official documentation for more usage of preset-env

4.2 @ Babel/runtime and @ Babel/plugin – transform – runtime

Can be used with the Pure version of core-js to simplify usage of core-js-pure by directly using instance methods and so on without contaminating global variables. The configuration is the same as that in PRESET -env, runtime should be downloaded according to corejs configuration (for example, corejs3 corresponds to @babel/ Runtime-corejs3). Note that only version 3 provides instance methods.

@ Babel/plugin – transform – runtime will

var sym = Symbol(); var promise = Promise.resolve(); var check = arr.includes("yeah!" ); console.log(arr[Symbol.iterator]());Copy the code

into

import _getIterator from "@babel/runtime-corejs3/core-js/get-iterator"; import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes"; import _Promise from "@babel/runtime-corejs3/core-js-stable/promise"; import _Symbol from "@babel/runtime-corejs3/core-js-stable/symbol"; var sym = _Symbol(); var promise = _Promise.resolve(); var check = _includesInstanceProperty(arr).call(arr, "yeah!" ); console.log(_getIterator(arr));Copy the code

Refer to official documentation for more features and technical details

5 Core-JS does not include polyfill

  • The polyfill associated with String#normalize is large, use a separate package unorm if necessary, as well as ecma-402 Intl
  • Proxy cannot polyfill, proxy-Polyfill provides some functionality
  • Window. fetch is not implemented because it is not a cross-platform feature.

End and spend