preface

As a front-end developer, if you haven’t used Babel yet, you’re a bit behind The Times

When it comes to Babel, a series of nouns come up, like:

  • babel-cli
  • babel-core
  • babel-runtime
  • babel-node
  • babel-polyfill
  • .

What do they do? What’s the difference? With these questions, this article will take you from 0 to 1 to understand and get a better understanding of Babel. This article is mainly the basic part, and there will be an in-depth principle part later. The purpose of this article is to review and sort out Babel and have a deeper understanding of Babel

What is the Babel

The official definition of

Babel is a JavaScript compiler

Babel is a toolchain for converting code written in ECMAScript 2015+ syntax into backwardly compatible JavaScript syntax so it can run in current and older versions of browsers or other environments.

Personal understanding

The simple solution is to convert the new syntax of es2015+ in JavaScript to ES5, which can be understood and executed by low-end runtime environments such as browsers and Nodes. For example, if you use the arrow function of ES6 in your code, it will cause errors in Internet Explorer. In order for your code to run in Internet Explorer, you need to compile your code to the way that Internet Explorer supports it.

const fn = arg => { console.log(arg); }; // Babel "use strict"; var fn = function fn(arg) { console.log(arg); };Copy the code

The working principle of

Babel’s main workflow is divided into three stages: Parse, Transform, and generate.

As shown below:

parsing

The source code string is converted into an abstract syntax tree (AST) by @babel/ Parser. There are two main stages in the parsing process: lexical analysis and syntax analysis

Lexical analysis:

In the lexical analysis stage, strings of code are parsed into data consisting of meaningful syntactical units. These data are called token flows.

What is a grammar unit?

For example, ‘The 2008 Olympic Games will be held in Beijing’. This sentence will be divided into two parts: 2018, Olympic Games, in, Beijing, held, this is participle, break the whole sentence into the smallest meaningful particles, these smallest particles can not continue to be divided, otherwise they will lose the meaning of expression.

Common syntax units in JavaScript are as follows:

  • Whitespace: Consecutive whitespace, line feeds, indentation, etc. in JS have no real logical meaning if they are not in the string, so consecutive whitespace is directly grouped together as a syntax unit.
  • Comment: a line comment or block comment, although meaningful to humans, but for computers to know that this is a “comment”, does not care about the content, so directly as a non-detachable syntax unit
  • String: To the machine, the contents of the string will only participate in the calculation or display, and there is no need to analyze the content of the subdivision
  • Number: JS language has 16, 10, 8 base and scientific expression of number expression grammar, number is also a minimum unit with meaning
  • Identifier: Consecutive characters that are not enclosed by quotation marks and can contain letters, underscores, $, and digits (digits cannot start with digits). Identifiers may represent a variable, built-in constants such as true or false, or keywords such as if, return, or function
  • Operators: +, -, *, /, >, <, etc
  • Parentheses: (…). The word segmentation stage does not care about which semantics, but treats “(” or”) “as a basic syntactic unit
  • There are others: brackets, braces, semicolons, colons, dots, and so on are no longer listed

Syntax analysis:

The syntax parser converts Tokens into an abstract syntax tree AST

What is AST (Abstract Syntax Tree)?

Abstract syntax tree, which is an abstract representation of the syntax structure of source code. It represents the syntactic structure of a programming language as a tree, with each node in the tree representing a structure in the source code.

For example:

Console. log(‘ Hello Babel ‘) parses into AST in json format as follows (conversion can be done at astexplorer.net/#/KJ8AjD6ma… :

Similar to the

{
    "type": "Program",
    "start": 0,
    "end": 23,
    "body": [...]
}
Copy the code

Such structures are called nodes, and an AST is made up of one or more such nodes, with child nodes inside, forming a syntax tree. For details, see: juejin.cn/post/684490…

conversion

Traverse the AST with @babel/traverse and call the plugin in the Babel configuration file to add, delete, or change the AST

generate

Generate object code from the transformed Abstract grammar (AST) via @babel/ Generator

Babel plug-in

Babel does not have the conversion function itself, but rather breaks it up into plug-ins. If no plug-ins are configured, the code that passes through Babel and the input are the same.

Add-ons for Babel:

Syntax plugin:

The syntax plug-in only allows Babel to parse the syntax and does no conversion. When syntax plug-ins are added, Babel can parse more syntax

For example, when we define or call a method, we are not allowed to add a comma after the last argument, such as func(param1, param2,) is illegal. If the source code is written this way, it passes through Babel with a syntax error.

But recent JS proposals have allowed this new approach (to make the code diff clearer). To avoid Babel errors, add the syntax plug-in babel-plugin-syntax-trailing-function-commas

Translation plug-in:

When a translation plug-in is added, the source code is translated for output.

For example, the arrow function (a) => a is converted to function (a) {return a}. The plug-in that does this is called babel-plugin-transform-es2015-arrow-Functions.

What is a preset?

Presets can be encapsulated into presets to simplify the use of presets. Presets are simply a set of presets. For example, @babel/ preset-React contains the following presets:

  • @babel/plugin-syntax-jsx
  • @babel/plugin-transform-react-jsx
  • @babel/plugin-transform-react-display-name

Es2015, for example, is a set of specifications that includes many translation plug-ins. Not only does NPM install take a long time if the configuration file is added and installed one at a time, but Babel also provides a collection of plug-ins to solve this problem. Because it is commonly used, you do not have to repeat the definition & installation.

Common preset types are as follows

See the website often recommended: babel.docschina.org/docs/en/bab…

@babel/ Preset -env can automatically convert ES2015+ code to ES5 based on the target browser or runtime environment configured.

@babel/preset- React Required by the React framework

@babel/preset-flow Is required by flow. Flow is a static type checking tool that performs type checking, similar to TS

@babel/preset-typescript What typescript requires

Execution order

The principles are as follows:

  • Plugin will run ahead of Preset.
  • Plugins are executed from front to back.
  • Preset is Preset from back to front.

The reverse order of preset is mainly to ensure backward compatibility, as most users write in the order [‘ ES2015 ‘, ‘stage-0’]. Stage-0 must be executed to ensure that Babel does not report errors. Because the lower stage contains all the content of the higher stage

Configuration items for plug-ins and Preset

Simple case: Plug-ins and preset only need to list string format names

Add arguments: you need to turn yourself into an array. The first element is still a string, representing its name; The second element is an object, the configuration object.

For example:

{"module": false}]; // If {"stage-2" : {"stage-2" : {"stage-2" : {"stage-2" : {"stage-2" : {"stage-2" : {"stage-2" : {"stage-2" : {Copy the code

Key Configuration Items

We’ve already seen the basics of Babel, but we haven’t covered Babel -* yet

The core

@babel/core

Babel is the core of Babel. Its main function is to convert code according to our configuration files, which are usually. Babelrc (static file) or babel.config.js(programmable).

  • Load and process configuration (Config)
  • Load the plug-in
  • callParserTo parse the syntax and generateAST
  • callTraverserWalk through the AST and useVisitor patternApply the ‘plug-in’ to transform the AST
  • Generate code, including SourceMap transformation and source code generation

Surrounding the core

Parser(@babel/ Parser) : Parses source code to AST.

Traverser (@ Babel/traverse by) : to traverse the AST transformation plug-in will pass it to get interested in AST node, the node to continue operating

Generator(@babel/ Generator) : Convert the AST to source code

integration

babel-cli

The CLI is a command line tool. Babel installed – CLI is able to compile files using Babel on the command line.

The following patterns are often used when developing NPM packages:

  • Install babel-cli as devDependencies
  • Add scripts to package.json and compile the file using the Babel command
  • npm publish

This allows you to write source code using the JS syntax of the newer specification while supporting older environments. If your project is not too big to use a build tool, use Babel-CLI before publishing

babel-node

Babel-node is part of the babel-CLI and does not require a separate installation. It runs es2015 code directly in the Node environment without additional code conversions

babel-register

The babel-register module overwrites the require command by adding a hook to it. Thereafter, whenever files with the js JSX es ES6 suffix are loaded using require, Babel will be used for transcoding.

To use babel-register, require (‘babel-register’) must be loaded first. Note that babel-register only transcodes the files loaded by the require command, not the current file, and is only suitable for use in development environments because of real-time transcoding

babel-polyfill

The Babel default converts JS syntax instead of new apis. Global objects such as Generator, Maps, and methods defined on global objects (object.assign) are not transcoded.

For example, es5 adds a new array. from method on Array objects, which Babel does not transcode. To run with this method, you must use babel-polyfill

When used, add require(‘babel-polyfill’) before all code runs. Or, more generally, babel-polyfill as the first entry in webpack.config.js. Therefore, you must refer to babel-polyfill as dependencies instead of devDependencies

Main disadvantages:

  1. Using babel-Polufill results in a larger package because babel-Polyfill is a whole and adds all methods to the prototype chain. For example, array. from is used, but Object. DefineProperty is also added, which is wasteful. You can solve this problem by using a separate library of Core-js, which is separate
  2. Babel-polyfill contaminates global variables and makes changes to many prototype chains, so it is preferable to use babel-plugin-transform-Runtime

Note: If you use a higher version of the JS instance method in your code, such as [1,2,3].includes(1), you still need to use polyfill

Babel – the runtime and Babel – plugin – transform – runtime

Sometimes syntax conversions are complicated, and sometimes helper functions are needed, such as converting es6 classes

/* test.js */ const Test {} /* test-compiled.js */ function _classCallCheck(instance, Constructor) { if (! (instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Test = function Test() { _classCallCheck(this, Test); };Copy the code

As shown in the figure, the es6 class requires a _classCallCheck helper function. If multiple files use the ES6 class, they need to be defined in each file, which is a waste of time. If you separate the helper functions into one package, all the files used can be referenced to reduce the amount of code. Babel /runtime, which provides various helper functions; So again, how do we know which helper functions to introduce? So the @babel/ plugin-transform-Runtime plugin helps us automatically introduce helpers

Summary:

Babel/Runtime: provides various helper functions

@babel/plugin-transform-runtime: automatically introduces helper functions

The preset

@babel/preset-env

ES5+ code can be automatically converted to ES5 based on the configured target browser or runtime environment

babel-loader

The main function of loader in babel-loader is to use Babel to convert ES6 code into ES5 version when WebPack is packaged

conclusion

The name of the role
targets Describe the environment supported by the project, the target environment
babel-core Convert the code according to the configuration file
babel-cli Allows the command line to translate files using the Babel command
babel-node Allows the command line to directly translate and execute node files using babel-node
babel-register Rewrite the require command to transcode the file it loads, not the current file
babel-polyfill Add compatibility methods for all apis
babel-preset-env ES5+ code can be automatically converted to ES5 based on the configured target browser or runtime environment
babel-plugin-transform-runtime & babel-runtime Provide helper functions & automatically introduce helper functions
babel-loader Babel was used to convert ES6 code to ES5 when WebPack was packaged

Personal practice

Above, we have introduced the basic concepts and related working principles of Babel. Theory is not as good as practice, so let’s start a small project to practice it, and it will be more impressive

Before we begin, a brief description of common usage:

  1. The command line (cli)
  2. Build tool plug-ins (babel-loader for Webpack, rollup-plugin-babel for rollup)

The second is found in a command in the scripts paragraph of package.json. The third is directly integrated into the build tool.

@babel/core

Main functions:

Mainly responsible for code parsing, translation, generation

The demo validation:

Desired result: The arrow function is expected to be converted to es5

After the execution:

Result: The arrow function has not changed after conversion, which meets the expectation, because it is stated in the official website that @babel/core is the core, but the specific version of JS translation needs to be defined by users themselves, and parameter processing needs to be added in options

@babel/preset-env

Main functions:

ES5+ code can be automatically converted to ES5 based on the configured target browser or runtime environment

The demo validation:

After the execution:

The results met expectations and the ES6 conversion was successful

When doing this step, I am a little curious, since it is said that it is determined according to the configuration of the target browser or running environment, then the above configuration does not set the target browser, how to determine? Is there a default configuration? What is the default configuration?

Specify the environment

How Does it work babeljs. IO /docs/en/bab… Babel set the default environment version via browserslist, where browserList ‘Queries’ indicates the method to obtain the environment version.

If the above methods did not produce a valid result Browserslist will use defaults: > 0.5%, last 2 versions, Firefox ESR, not dead The latest two releases have seen a market share of more than 0.5% and have had official mission support and updates within 24 months)

@babel-cli

Main functions:

As mentioned above, @babel/cli allows you to compile files quickly and easily using the command line

The demo validation:

Create the testBabelCli file

After the execution:

npx babel testBabelCli.js –out-file ./src/testBabelCli-compiled.js –presets=@babel/preset-env

Suggestion: For demo, the above is translated by adding parameters to the command, but this will be troublesome. During project development, we can configure the babel.config.js configuration file, and the configuration of the file can be read automatically during execution

Run the following command

npx babel testBabelCli.js --out-file ./src/testBabelCli-compiled.js
Copy the code

Execution Result:

@babel/polyfill

Main functions:

For relatively new JS built-in functions, translation can be done

Demo validation (not using @babel/polyfill) :

After performing

The above code contains const keywords and includes array methods. These are new syntax and APIS in ES6. IE8 does not support these methods, so after the above compilation, only const keywords are converted

Demo validation (using @babel/polyfill)

After performing

Introduced the global core – js/modules/es7. Array. Includes. Js is the introduction of a global, directly on the object constructor or adding methods on the prototype, there will be pollution global variables, Hence the @babel/ plugin-transform-Runtime plugin to solve this problem

@babel/plugin-transform-runtime

The demo validation:

After the execution:

Personal summary

Babel is a js compiler. Babel is a js compiler. Babel is a js compiler. Babel does not convert itself, but is converted by finer grained plug-ins, with the ultimate goal of making code work across browsers. In the follow-up, I will study and summarize the compilation principle of Babel in depth. The above is only the summary and practice in the process of learning and summarizing. Welcome to point out any shortcomings

Refer to the link

www.babeljs.cn/docs/

Juejin. Cn/post / 705155…

Github.com/browserslis…

Juejin. Cn/post / 684490…

Author: Yu Danqiu