Introduction to the

Babel is the next generation compiler for JavaScript syntax, based on Node.js and a must for modern front-end development.

role

Developers can use the latest and most cool new javascript features (ES6+) to write front-end code, but also compatible with lower versions of browsers (mainly IE), in a word, the ES6+ (including ES2015, ES2016… ESXXXX, etc.) to ES5

Implementation process

As you can see, the core of Babel is parse, Transform, and Generator

The parser compiler

@babel/ Parser, used to convert source code into an AST tree

You don’t need to install it separately, because @babel/core is already included, or you can install it yourself unless you want to

npm i @babel/parser -D
Copy the code

Transform process

By default, Babel does not have plug-ins. If Babel does not have plug-ins, it simply generates the AST source code and then uses generators to generate code that is identical to the original source code.

Where the Babel plug-in comes into play is basically in the TranFrom phase, as long as the Babel transform plug-in is installed to convert the desired code

Ps: Babel is divided into transformation plug-ins, which need to be installed manually, and utility plug-ins, which are built in when the @babel/core core is installed, and provide the ability to manipulate ast nodes

The generator generator

@babel/generator for generating code from the transformed AST tree

You don’t need to install it separately, because @babel/core is already included, or you can install it yourself unless you want to

npm i @babel/generator -D
Copy the code

The installation

When the project uses ES6+ features and is compatible with older browsers, you need to use Babel for code conversion. You need to install Babel first (core package + command package) :

@babel/core
@babel/cli
Copy the code

@babel/core

We often refer to the @babel/core package

introduce

It integrates dozens of basic packages, such as @babel/ Parser compiler, @babel/ Generator, etc. It also includes some utility class plug-ins, such as @babel/types, @babel/traverse, etc., to provide the function of manipulating AST nodes.

Why the @babel/core package? The main reason is for ease of use, because Babel is made up of three parts and relies on a lot of third-party packages. If we had installed Babel one by one, there would have been some version incompatibility issues and it would probably have gone crazy

role

Used for parsing, code generation, and missing conversions by default because conversions dependbabelA plugin

The installation

// Must rely on NPM i@babel/core-d as developmentCopy the code

@babel/cli

Babel is similar to WebPack in that the CLI command line tools are split out for easy maintenance and import on demand. The WebPack command line toolkit is WebPack-CLI

introduce

Babel is a CLI command line tool that provides the Babel command

role

Babel (webPack-CLI) provides a way to use Babel by command, which is also provided by many tools, such as Webpack-CLI

Note: Although this command mode is provided to use Babel, it is not suitable for development and production because of the numerous options and inconvenient to write. It is generally used for learning purposes. Development and production are generally used in integrated mode, which will be explained later

The installation

NPM i@babel /cli -d is required as a development dependencyCopy the code

configuration

Why configure it? A metaphor, run the command = = = send you to Beijing on business (mission), the configuration is like details of the mission, tell you should be to go by plane, or bus, or take the high-speed rail, is to go in the morning or evening, go is a group or a person, if there is no configuration, is equivalent to using the default configuration (rules), Therefore, there are many configuration items attached to common commands

While it is possible to run Babel for transcoding with commands, if you want to configure something like this, it is extremely disgusting and easy to write wrong (especially if there are too many configurations).

npx babel src -d lib --plugins=@babel/plugin-transform-arrow-functions --presets=@babel/preset-env
Copy the code

Therefore, it is not recommended to configure on the command (not not recommended command, you should distinguish well).

[Recommendation] The command can be used, but the configuration needs to be removed to an independent file for unified management, and this file name is the most confusing place for beginners

File name classification

According to the file name classification, there are two categories:

Json babel.config.js babel.config. CJS babel.config. MJS // use ESM modularized writing method // The second babelrc // yes Json alias.babelrc.json.babelrc.js.babelrc.cjs.babelrc.mjsCopy the code

You can configure it directly in the Babel field of package.json, but it is not recommended

According to the scope of action, there are two categories:

Json babel.config.js babel.config. CJS babel.config. MJS // use ESM modularized writing method // Second kind: For the file.babelrc // is alias.babelrc.json.babelrc.js.babelrc.cjs.babelrc.mjs package.json in the Babel optionCopy the code

According to the functional classification, there are two major categories:

// The first type: Babelrc.js.babelrc.cjs.babelrc.mjs // Static configuration. Babelrc // is an alias of.babelrc.jsonCopy the code

The programmable class configuration file can call any of Node’s apis, so it is more flexible and powerful

The most common configuration files are babel.config.js, babel.config.json,.babelrc, and.babelrc.js

Babel. Config. Js and. Babelrc. Js

The code for both profiles is the same, using the CommonJS module specification

module.exports = function (api) { api.cache(true); const presets = [ ... ] ; const plugins = [ ... ] ; return { presets, plugins }; } or const presets = [...] ; const plugins = [ ... ] ; module.exports = { presets, plugins };Copy the code

Babel. Config. Json and babelrc

The code for the two configuration files is the same and is a JSON object directly

{ "presets": [...] , "plugins": [...] }Copy the code

Babel.config. js is different from.babelrc

Babel.config.js (json/ CJS/MJS) was introduced by Babel7 to solve some problems with babel6

Babel.config. js (json/ CJS/MJS) as global configuration (project root),.babelrc (.json/js/ CJS/MJS) as local configuration (local priority is greater than global). Now the retrieval behavior stops at the package.json level.

Please have a look at

Look at 2

Plugins

By default, Babel does not have code conversion built into it. Code conversion is all done by Babel plug-ins (transform classes), so plug-ins are very important to Babel. We don’t usually develop our own Babel transformation plug-ins, and in real projects we tend to use off-the-shelf plug-ins (official or third party). From the list of plugins on the official website, we find that plugins are very rich

PS: All the plug-ins mentioned below refer to conversion plug-ins

Installation and use

The installation is simple, just go to the official plug-in list and use the following command

NPM I @babel/plugin-transform-arrow-functions --save-dev/NPM I @babel/plugin-transform-arrow-functions --save-dev / NPM i@babel/plugin-transform-parameters-d is requiredCopy the code

After installation, use it immediately. Use it in 2 minutes

2. Configuration mode (recommended)

NPX Babel SRC -d lib --plugins=@babel/plugin-transform-arrow-functions NPX Babel SRC -d lib --plugins=@babel/plugin-transform-arrow-functions, @babel/plugin-transform-parameters /* config mode */ // In the root directory of the project, create a babel.config.json config file {"plugins": [ "@babel/plugin-transform-arrow-functions", "@babel/plugin-transform-parameters" ] }Copy the code

Omit the prefix notation

Each plug-in is prefixed with plugin-, and it is cumbersome to write it repeatedly every time you use a plug-in, so Babel provides an easy way to omit the plugin- prefix

The above two clock modes are omitted as follows:

NPX Babel SRC -d lib --plugins=@babel/transform-arrow-functions NPX Babel SRC -d lib --plugins=@babel/transform-arrow-functions,@babel/transform-parameters /* configure mode */ / Json configuration file {"plugins": ["@babel/transform-arrow-functions", "@babel/transform-parameters"]}Copy the code

Execution order

When configuring multiple plug-ins (the commands are the same), execute them from front to back, for example:

{"plugins": ["@babel/transform-arrow-functions", "@babel/transform-parameters"]}Copy the code

Run @babel/transform-arrow-functions and @babel/transform-parameters

Configuration options

In the Babel configuration file, in addition to declaring the Babel plug-in used, you can also configure the Babel plug-in used (provided that the plug-in provides configurable items). , written as follows:

// in babel.config.json {"plugins": [["transform-async-to-module-method", {"module": "bluebird", "method": "coroutine" } ] ] }Copy the code

The problem

We have learned to install and use plugins, and Babel converts ES6+ syntax by using plugins. Look at the list of plug-ins, ~ ~ suddenly meng forced, so many plug-ins do I need to install a use?

73. Of course not, no one will use Babel for code-switching if installed one by one, and Babel has an official solution — preset, which will be explained later

Matters needing attention

Transformation plug-ins are classified by function into three categories:

1. ES6+ syntax conversion plug-in

This plugin is most commonly used to convert the latest ES6+ syntax sugar, not the new ES6+ API and global objects. For example, let/const can be converted. New apis such as includes/ object. assign cannot be converted. @ Babel/plugin – transform – arrow – functions provides, @ Babel/plugin – transform – parameters, etc

2. Add conversion plug-ins

A supplement to the above ES6+ syntax conversion plug-in, to solve the problem it can not solve mainly on ES6+ new API and global object conversion for example: Babel-plugin-transform-runtime converts object. assign and also introduces @babel/polyfill to ensure browser compatibility with new apis such as includes.

General projects use the @babel/ Polyfill supplement, while tools/libraries use the babel-plugin-transform-Runtime plug-in

3. Other conversion plug-ins

TS, Flow, React(JSX) converts JSX syntax and TS syntax to remove type declarations

Preset (Preset)

The Babel plug-in can be broken down to as small a granularity as possible and can be introduced as needed. For example, for ES6 to ES5 functions, Babel has officially split into 20+ plug-ins. But in real development, plug-in by plug-in introduction is not only inefficient, but also prone to error. For this reason, Babel officially offers a set of Babel plugins — Preset, which is used to install and import a Preset

Installation and use

Installation is very simple, find the required presets in the official, use the following command to install

// Install NPM i@babel /preset-env -d to turn ES6+ syntax into ES5Copy the code

Syntax that has been incorporated into the specification (ES2015, ES2016,…. , ES2021, Modules) are included in @babel/preset-env

After installation, use it immediately. Use it in 2 minutes

2. Configuration mode (recommended)

// NPX Babel SRC -d lib --presets=@babel/preset-env NPX Babel SRC -d lib --presets=@babel/preset-env, @babel/preset-typescript // / In the project root directory, New babel.config.json configuration file {"presets": [["@babel/preset-env", {targets: {edge: "17", Chrome: "64", Firefox: "60", Safari: "11.1", IE: "10"}}]]}Copy the code

Omit the prefix notation

Every preset is prefixed with preset-, which can be troublesome to write repeatedly every time a preset is used, so Babel officially provides an easy way to omit preset-

The above two clock modes are omitted as follows:

NPX Babel SRC -d lib --presets=@babel/env Json configuration file {"presets": [["@babel/env", {targets: {edge: "Chrome: 17", "64", firefox: "60", safari: "11.1", ie, "10"}}}]]Copy the code

Configuration options

In the Babel configuration file, in addition to declaring the used Babel presets, you can also configure the used Babel presets. , written as the plugin configuration options!

Execution order

In contrast to the plugin execution order, several Preset versions run in reverse order of declaration.

For example, you need to convert JSX in React to JS and js to ES5, so you need to put the React plugin behind and let it execute first.

// configure {presets: ["@babel/env", "@babel/react"]}Copy the code

If you have both Babel plug-ins and Babel presets, what is the order of execution?

Answer: Plug-ins take precedence over presets, executing plug-ins first (in the order of declared plug-ins) and then presets (in reverse order of declared presets)

Load plug-ins on demand

@babel/preset-env includes ES2015, ES2016, and……. Some of the new ES6+ features are now supported by many of the latest browsers. If your code only needs to run on these advanced (new) browsers, the new ES6+ features do not need the corresponding Babel plug-in conversion, greatly improving the code translation performance

@babel/preset-env supports on-demand loading, and as soon as the target browser and its version are specified, @babel/ Preset -env will load the corresponding Babel plug-in for code-conversion according to the target browser’s features (ES6+ is not supported)

There are two ways to specify the target browser: 1. Specify it using the targets attribute in the Babel configuration file. 2.

PS: Specifies the target browser, besides being used for @babel/preset-env to load the corresponding conversion plug-in on demand, it is also used for AUTOPrefixer to add CSS browser prefixes based on the target browser (CSS3 compatible processing).

See more configurations of Browserslist

Browserslistrc Configuration case Ie >= 8 Firefox >= 3.5 Chrome >= 35 Opera >= 11.5Copy the code

Matters needing attention

1, @ Babel/preset env entirely replace the Babel – preset – es2015 / es2016 es2017 /… (formerly used ES6 + transformation plug-in), namely the Babel – preset – es2015 / es2016 es2017 /… Scrap. Also @babel/preset-env does not support stage-x presets by default

2, Stag-x has been officially scrapped since Babel7, preset-stage-0/1/2/3/4

3. Presets are just a collection of plug-ins, and the default @babel/preset-env will only be used to transform ES6+ new syntax, that is, arrow functions we see, const/let, etc. If you further need to transform built-in objects, instance methods (apis), you will need to supplement them with polyfill, as described next.

PS: Why does it start with the word “default”? Because polyfill is associated with @babel/preset-env, just configure useBuiltIns in @babel/preset-env to enable polyfill, which is disabled by default, more about preset below

Polyfill

The official ‘polypill’ is @babel/polyfill. Since Babel 7.4.0, @babel/polyfill has been deprecated

As mentioned above, the new built-in objects like Promise, Generator, Symbol, and array includes() API are not translated by Babel because the Babel plugin only translates ES6+ syntax by default. This is where the @babel/ Polyfill supplement comes in to simulate the ES6+ environment:

Installation and use

The installation command is as follows:

NPM I@babel /polyfill -s // To produce installation -sCopy the code

Why install with -s instead of -d? Take a look at the code transformed using Polyfill and you can see why

Var hasTwo = [1, 2, 3]. Includes (2); / / the code after the require (" core - js/modules/es7. Array. Includes "); require("core-js/modules/es6.string.includes"); var hasTwo = [1, 2, 3].includes(2);Copy the code

UseBuiltIns is easy to use, just configure @babel/preset-env with useBuiltIns. UseBuiltIns has three optional values: “Usage”, “entry”, and false. The default is false

Normally we set useBuiltIns to “usage”, so when Babel transforms the code, it imports and supplements on demand based on the following two criteria

  1. Target browser
  2. Code (new APIS with ES6+, new built-in objects, etc.)
// babel.config.json configuration {"presets": [["@babel/env", {targets: {edge: "17", Chrome: "64", Firefox: "60", Safari: "11.1", ie: "10"}, useBuiltIns: "usage"}]]}Copy the code

Have been abandoned

The @babel/polyfill package has been deprecated since Babel 7.4.0. The content described above is only suitable for versions prior to Babel 7.4.0, but it is recommended that you do not use @babel/polyfill even before Babel 7.4.0. Because @babel/polyfill has not been updated for a year, but new ES6+ syntax is added every year, in other words, the latest JS syntax @babel/polyfill is not supported this year

Front knowledge

@babel/polyfill is an integrated package consisting of core-js2 and regenerator-Runtime (i.e. @babel/polyfill = core-js@2 + regenerator-Runtime).

Regenerator-runtime: supplement generator and async features (es6 async keyword implementation) Core-js: Supplement GENERATOR and ASYNc features (es6 + features for example: Includes (), array.from, etc.) provides supplements (es6 object and method implementations)

The solution

The official recommendation is to use it alonecore-jsandregenerator-runtimePackage, and then set@babel/preset-envthecorejsOptions for3

If you have installed the @babel/polyfill package, you can uninstall it first: NPM uninstall @babel/polyfill

Install the core-js supplement, which is currently 3.17.3

NPM I core-js --save // Remember to use --save installCopy the code

The regenerator-Runtime supplement doesn’t need to be installed because @babel/ PRESET -env is already built in and everything is ready except for configuration

// babel.config.json configuration {"presets": [["@babel/env", {targets: {edge: "17", Chrome: "64", Firefox: "60", Safari: "11.1", ie, "10"}, useBuiltIns: "usage", 3}}]] corejs:Copy the code

At this point, the @babel/ Polyfill waste problem is perfectly solved

Why core-js@3 instead of core-js@2?

@babel/ Polyfill built-in Core-JS package version 2 by default

The reason for using core-js@3 is that new features are no longer added to the core-js@2 branch; they are added to core-js@3. For example, if you’re using array.prototype.flat (), if you’re using core-js@2, it doesn’t include this new feature. In order to use more of the new features, we recommend that you use core-js@3.

Why not recommend @babel/ Polyfill?

1. @babel/ Polyfill has not been updated for over a year, while core-js@3 is constantly updated, and core-js@3 has replaced @babel/ Polyfill

2. Because @babel/ Polyfill does not support smooth transitions from core-js@2 to core-js@3. So the core-JS official now recommends that we introduce core-js and Regenerator-Runtime/Runtime directly when using polyfill instead of @babel/ Polyfil to prevent major changes

Matters needing attention

For libraries/tools, if you don’t need instance methods like array.prototype.includes, you can use the Transform Runtime plugin instead of using globally polluting @babel/polyfill

For applications, we recommend installing @babel/ Polyfill (Babel 7.4.0+ and later)

Reference and thanks

The original intention of writing this article is from my poor memory (old), often learned knowledge, as time goes by, always forget, so I decided to write down what I learned, when forgotten later can come to a memory.

Before writing, I collected information on the Internet and read a lot of blog articles written by big wigs. I also found a lot of very good articles. Thank you very much

I used up only a few of their thinking ability, according to my understanding of the way to comb again, and then recorded, intermittently write for 3 days, finally do well, I hope to help you a little, like you can point a like oh!!