(1) What is? babel?
babel It's a js tool kit , For backward compatibility , Often used in new versions , That is, the new version can still use the old version code .
babel Main role of :1. Source code conversion .2. Conversion syntax For example, transcoding ( Downward compatibility is achieved by compiling the new version of code into the old version ):
// Babel Input :ES2015 Arrow function
[1, 2, 3].map(n => n + 1);
// Babel Output :ES5 Equivalent grammar
[1, 2, 3].map(function(n) { return n + 1; });
Copy code
We use @babel/cli Run from terminal Babel,@babel/polyfill be used for polyfill All new JavaScript function ,env preset Transformation rules that contain only the functions we use ,polyfills Used to populate missing features in the target browser .
(2)babel/core and @babel/cli
@babel/core We see in many places , It is Babel The core dependency package for transcoding , That we use a lot babel-cli and babel-node All depend on it
var babelCore = require("@babel/core");
var sourceCode = `let fn = (num) => num + 2`;
var options = {
// Whether to generate parsed code
code: true,
// Whether to generate abstract syntax tree
ast: true,
// Whether to generate sourceMap
sourceMaps: true,
plugins: [],
presets: [],
};
babelCore.transform(sourceCode, options, function (err, result) {
console.log(sourceCode);
console.log(result.code);
console.log(result.map);
console.log(result.ast);
});
Copy code
You can find the original es6 The arrow function returns almost intact in the result ;Babel The operation mode of can be divided into three stages : analysis (parsing)、 transformation (transforming) And generation (generating); The plug-in responsible for the parsing phase is @babel/parser
, Its function is to parse the source code into AST; The plug-in responsible for the generation phase is @babel/generator
, Its function is to turn it into a good AST Regenerate code .
and @babel/core It does not have the function of conversion processing , It splits the conversion function into plug-ins (plugins) in ; So when we don't add any plug-ins , The input and output codes are the same .
stay @babel/core There are several by-products of conversion :code、ast and map
@babel/cli
yes Babel Comes with a built-in CLI Command line tools , We can compile the file from the command line ; There are two ways to call it , It can be called through global installation or local installation , Just choose one , It is recommended to install... Locally .
Although we can configure various plug-ins on the command line (plugins) Or preset (presets, That is, a set of plug-ins ), However, this is not conducive to later viewing or maintenance , And most of the time babel It's all a combination webpack perhaps gulp And other packaging tool development , Not directly through the command line ; therefore Babel It is recommended to manage through configuration files .
Babel The main configuration files are .babelrc
、.babelrc.js
、babel.config.js
and package.json
, Their configuration options are the same , The effect is the same , The main difference lies in the difference of format Syntax , Therefore, we only need to select one of them in the project .
about .babelrc
, Its configuration is mainly JSON Format , like this :
{
"presets": [...],
"plugins": [...]
}
Copy code
But sometimes we need to set parameters for plug-ins and presets , You can't directly use the form of string ; Instead, wrap another layer of array , The first item in the array is the name , The second item is the set parameter object :
//.babelrc
{
"plugins": [
[
"@babel/plugin-transform-arrow-functions",
{ "spec": true }
]
]
}
Copy code
(3)babel The difference between presets and plug-ins :
Babel The official website provides nearly 100 plug-ins , However, if we configure plug-ins one by one in our code, we need to understand each plug-in , This is bound to cost a lot of time and energy ; So ,Babel Provides a preset (presets) The concept of , It means a series of pre-set plug-in packages ; This is equivalent to the set meal in KFC , Mix and match many products , Suitable for the needs of different people ; There is always a package for us .
Babel Official preset, What we may actually use is 4 individual :
- @babel/preset-env
- @babel/preset-flow
- @babel/preset-react
- @babel/preset-typescript
@babel/preset-env Is a smart preset , Allows you to use the latest JavaScript, Without the syntax transformation required to micromanage the target environment ( And an optional browser polyfill). This makes your life easier ,JavaScript The bag is smaller !
@babel/preset-env Pay more attention to adaptive browsers , If you specify to adapt to the latest chrome browser , Just modify the configuration to
{
"presets": [
[
"@babel/env",
{
"targets": "last 2 Chrome versions"
}
]
]
}
Copy code
The converted code will only fit chrome The latest two versions , That is not right class, Arrow function, etc .
(4) Execution order :
Both plug-ins and presets are configured in the configuration file in the form of arrays , If both the plug-in and the preset have to deal with the same code fragment , Then it will be determined according to the following execution rules :
- The plug-in executes before the default
- The plug-in execution order is that the plug-in array is executed from front to back
- The default execution order is that the default array is executed from back to front
(5) @babel/polyfill
although @babel/preset-env You can convert most higher versions of JS grammar , But some ES6 Functions on the prototype chain ( For example, on an array instance filter、fill、find Such as function ) And new built-in objects ( such as Promise、Proxy Objects such as ), The lower version of the browser itself does not support , therefore @babel/preset-env There's nothing I can do with them .
For example, we often use filter function , stay IE There will be compatibility problems on the browser , So we passed polyfill( shim ) To solve the problem .polyfill Can be used at the entry file import It can also be introduced in webpack Configuration in file . But this package download rarely references , Because it will load all the functions , It will cause global pollution .
So from Babel7.4 Start @babel/polyfill It's not recommended , But directly introduce core-js And regenerator-runtime Two bags ; and @babel/polyfill It is also a collection of these two packages ; on top webpack Packed dist We can also see the file , These two packages are also referenced . that core-js What is it ?
It is JavaScript Standard library polyfill It is as modular as possible , Let you choose the functions you need It and babel Highly integrated , It can be done to core-js The introduction of is optimized to the greatest extent At present, the default we use is [email protected], But it has blocked the branch , After that, the features will only be added to [email protected], Therefore, it is also recommended to use the latest [email protected]
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3
}
]
]
}
Copy code
At this point, he will introduce .