What’s a Babel?
In the official Babel documentation, this is how Babel is described
Babel is a JavaScript compiler that converts ECMAScript 2015+ code into backward-compatible JavaScript syntax so that it can run in current and older browsers and other environments. In a nutshell,Babel’s job is to:
- The syntax conversion
- JS source conversion
- Add missing features to the target environment by using a Polyfill
Babel fundamentals
The basic principle of Babel is to transform the source code into an abstract syntax tree, then process the abstract syntax tree to generate a new syntax tree, and finally generate new JS code from the new syntax tree. The whole compilation process can be divided into three stages:
Parsing –>transforming –>generating
Note :Babel is only responsible for compiling new syntax introduced under new standards, such as Class,Array Function, and ES Instead of compiling new methods and apis for native objects, such as array.includes,Map,Set, etc., these are solved by ployfill.
Babel basic use
Basic environment to run Babel
1. Babel/cli or Babel/node
npm install i -S @babel/cli
Copy the code
@babel/ CLI is a built-in command-line tool provided by Babel. @babel/cli is installed in a project, while @babel/node is installed globally.
2.@babel/core
npm install i -S @babel/core
Copy the code
If @babel/cli is installed and you execute Babel test.js in the project directory, you will find that @babel/core is not found, because @babel/cli relies on @babel/core to generate AST. Therefore, you need to install @babel/core after installing @babel/ CLI.
Command not found: Not found: Not found: Not found: Not found This is because @babel/cli is installed under the project, not globally. Therefore, you cannot use the Babel command directly. You need to add the following configuration item in the package.json file:
"scripts": {
"babel":"babel"
}
Copy the code
At this point, the code still cannot be encoded because the corresponding plug-in or preset needs to be installed to compile the file.
Configuration file.babelrc
The configuration file for Babel is.babelrc and is stored in the project root directory. The first step in using Babel is to configure this file.
This file is used to set transcoding rules and plug-ins. The basic format is as follows.
{
"presets": [],
"plugins": []
}
Copy the code
The presets field sets transcoding rules. The following rule sets are provided officially and you can install them as needed.
$NPM install --save-dev babel-preset- ES2015 # react presets $NPM install --save-dev babel-preset- preset-react # ES7 transcoding rules for syntax proposals in different stages (there are four stages), Select a $NPM install --save-dev babel-preset-stage-0 $NPM install --save-dev babel-preset-stage-1 $NPM install --save-dev babel-preset-stage-2 $ npm install --save-dev babel-preset-stage-3Copy the code
Then, add these rules to.babelrc.
{
"presets": [
"es2015",
"react",
"stage-2"
],
"plugins": []
}
Copy the code
The plug-in
Plug-ins are used to define how to transform your code. Babel will load the NPM package in node_modules and compile the syntax for the plugin.
.babelrc
{
"plugins": ["transform-decorators-legacy", "transform-class-properties"]
}
Copy the code
Plug-in execution sequence
The plug-in executes before the preset
Plug-ins are executed from left to right. That is, in the example above, Babel calls the transform methods defined in the transform-decorators-Legacy plug-in first, and then the transform-class-Properties methods when it does the AST traversal.
The plug-in and transfer
Parameters are an array of plug-in names and parameter objects.
{
"plugins": [
[
"@babel/plugin-proposal-class-properties",
{ "loose": true }
]
]
}
Copy the code
The preset
A preset is a combination of plugins to achieve a certain translation capability, such as @babel/preset-react used in React, which is a combination of the following plugins.
@babel/plugin-syntax-jsx @babel/plugin-transform-react-jsx @babel/plugin-transform-react-display-name
We can also manually configure a series of plugins in our plugins to do this, like this:
{
"plugins":["@babel/plugin-syntax-jsx","@babel/plugin-transform-react-jsx","@babel/plugin-transform-react-display-name"]
}
Copy the code
But this is not so elegant on the one hand, on the other hand, it increases the user’s difficulty. If you use the preset, it will be much fresher
{
"presets":["@babel/preset-react"]
}
Copy the code
The default order of execution
As mentioned earlier, plug-ins are executed from left to right, and the default execution order is the exact opposite, right to left
As mentioned earlier, plugins are executed from left to right, and the default execution order is the exact opposite, right to left {"presets": ["a", "b", "c"]}Copy the code
It executes in THE order C, B, A, which is a little odd, mostly to ensure backward compatibility, since most users put “ES2015” before “stage-0”.
Polyfill
Polyfill translates to “gasket.” A gasket is a way to smooth out the differences between different browser environments so that everyone is the same.
By default, Babel only converts new JavaScript syntax, not new apis, such as Iterator, Generator, Set, Maps, Proxy, Reflect, Symbol, Promise, and other global objects. And some methods defined on global objects (such as object.assign) are not transcoded.
For example, ES6 adds the array. from method to Array objects. Babel does not transcode this method. If you want this method to work, you must use babel-polyfill to provide a spacer for the current environment.
The installation command is as follows.
$ npm install --save babel-polyfill
Copy the code
Note that @babel/polyfill is not configured in the Babel configuration file, but is introduced in our code.
import '@babel/polyfill'; Const arrFun = ()=>{} const arr = [1,2] console.log(arr.includes(1)) promise.resolve (true)Copy the code
The compiled:
require("@babel/polyfill");
var arrFun = function arrFun() {};
var arr = [1, 2, 3];
console.log(arr.includes(1));
Promise.resolve(true);
Copy the code
This should work well in older browsers.
I don’t know if you’ve seen a problem here, but require(“@babel/polyfill”) loads the entire @babel/polyfill in, but in this case we need to deal with Array. Includes and promises. If this results in a larger packet volume, it is obviously not an optimal solution. If only it could load on demand. Actually, Babel had a plan for us
Load useBuiltIns on demand
Let’s go back to @babel/preset-env, the purpose of his appearance is to realize national unity, even the stage-x is dead, why did he leave out the Polyfill feature? The useBuiltIns parameter is provided in the configuration item of @babel/preset-env. As long as the useBuiltIns parameter is used when @babel/preset-env is used, Babel will automatically Polyfill at compilation time. There is no need to manually introduce @babel/ Polyfill into your code, and it can be loaded on demand
Note that you need to configure the version number of Corejs, and if you don’t configure a compilation alert.
UseBuiltIns mechanism parameters:
False: Polyfill will not be loaded on demand if @babel/ Polyfill is introduced. All code will be imported
Usage: Polyfill is performed based on the browser compatibility configuration and the API you use in your code, enabling on-demand loading
Entry: It will be loaded on demand depending on the browser compatibility configuration and the API you use in your code. However, you need to manually import ‘@babel/ Polyfill’ in the entry file.
Code reuse of helper functions
@babel/ plugin-transform-Runtime allows Babel to reuse helper functions during compilation, thus reducing the size of the package.
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
Copy the code
Configure the Babel:
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3
}
]
],
"plugins": [
"@babel/plugin-transform-runtime"
]
}
Copy the code