preface

This article aims to document the Babel learning process, the relationships between Babel packages and their roles. The article is based on Babel 7+

Blog Address of this article

::: tip Article reference

  • Babel
  • Personal understanding of Babel 7 use
  • Babel7 knowledge not to be missed

: : :

What is theBabel

Babel is a tool designed to address the differences between the ES language on various platforms.

Babel is a javascript complier

Babel is a toolchain for converting ECMAScript 2015+ code into a backward-compatible version of JavaScript in current and older browsers or environments. Here are the main things Babel can do for you:

  • Transform syntax
  • Missing Polyfill functionality in target environment (via @babel/ Polyfill)
  • Source code Conversion (Codemods)

Babel concept

summary

concept The library instructions
core @babel/core babel compilerCore compiler for parsing and converting code.
cli @babel/cli Babel built-in command line tools that can be used to compile code using command line tools.
plugins Transform Plugins

@babel/plugin-transform-runtime

@babel/plugin-transform-react-jsx

.
Plug-in for code conversion, internal call@babel/coreThe transformation code, the plug-in is the object of the observed pattern and only performs the transformation on the observed syntax
presets @babel/preset-env

@babel/preset-flow

@babel/preset-react

@babel/preset-typescript

A default is a collection of plugins that can define its own default.
cli @babel/plugin-transform-runtime A plug-in that recycles the @babel/ Runtime helper injected by Babel

@babel/core

@babel/core is a code compiler based on running in Node, whether through @babel/ CLI tools or webpack Babel plug-in translation, internal node calls @babel/core related functions to achieve code translation. Is a development dependency package.

npm install --save-dev @babel/core
Copy the code

@babel/core internally implements transform, tranformFile, and transformFromAst methods. Both implement callback, synchronous, and asynchronous promise invocation interfaces,

  • transform
babel.transform(code: string, options? :Object.callback: Function)
Copy the code
  • transformSync
const{code, map, ast} = babel.transformSync(code: string, options? :Object)
Copy the code
  • transformAsync
babel.transformAsync(code, options).then(result= > {
 const  {code, map, ast} = result
});
Copy the code
  • transformFile
babel.transformFile(filename, options, callback)
Copy the code
  • transformFileSync
const  {code, map, ast} = babel.transformFileSync(filename, options)
Copy the code
  • transformFileAsync
babel.transformFileAsync(filename, options).then(result= > {
 const  {code, map, ast} = result
});
Copy the code
  • transformFromAst
const sourceCode = "if (true) return;";
const parsedAst = babel.parse(sourceCode, { parserOpts: { allowReturnOutsideFunction: true}}); babel.transformFromAst(parsedAst, sourceCode, options,function(err, result) {
  const { code, map, ast } = result;
});

Copy the code
  • transformFromAstSync
const sourceCode = "if (true) return;";
const parsedAst = babel.parse(sourceCode, { parserOpts: { allowReturnOutsideFunction: true}});const { code, map, ast } = babel.transformFromAstSync(parsedAst, sourceCode, options);

Copy the code
  • transformFromAstAsync
const sourceCode = "if (true) return;";
babel.parseAsync(sourceCode, { parserOpts: { allowReturnOutsideFunction: true } })
  .then(parsedAst= > {
    return babel.transformFromAstAsync(parsedAst, sourceCode, options);
  })
  .then(({ code, map, ast }) = > {
    // ...
  });

Copy the code

@babel/cli

@babel/cli is an official CLI scaffolding tool provided by Babel. It is used to execute compiled commands on the command line and output compiled code.

It is not recommended to install @babel/ CLI globally because:

  • The same computer may run different versionsBabelProject, installed in the project can be updated maintenance.
  • In-project installation reduces project dependency on the global environment for better portability support.
npm install --save-dev @babel/core @babel/cli
Copy the code

Create the test file test.js

const aa = () = > { const bb  = [1.2]; console.log(... bb); };const {x, y} = obj;
const [a, b, ...rest] = arr;
Copy the code

Run the command

npx babel test.js
Copy the code

The output

const aa = () => { const bb = [1, 2]; console.log(... bb); }; const { x, y } = obj; const [a, b, ...rest] = arr;Copy the code

You can see that there is no translation.

Since only the scaffolding tools and core package @babel/core were installed, there were no plugins to implement the conversion

Install @babel/plugin-transform-arrow-functions to parse the syntax of arrow functions

npm i -D @babel/plugin-transform-arrow-functions
Install destruct syntax support
npm i -D @babel/plugin-transform-destructuring
Copy the code

After installing the plugin to parse the transformation, we also need to configure the use of the plug-in.

  • For the CLI tool, you can use the command line to specify the use of plugin. You can view the command line help NPX Babel –help

  • Using the local configuration file. Babelrc or. Babelrc. json has a lower priority than the command line configuration

So we can

npx babel test.js --plugins @babel/plugin-transform-arrow-functions,@babel/plugin-transform-destructuring
Copy the code

The output

const aa = function () { const bb = [1, 2]; console.log(... bb); }; const _obj = obj, x = _obj.x, y = _obj.y; const _arr = arr, _arr2 = _toArray(_arr), a = _arr2[0], b = _arr2[1], rest = _arr2.slice(2);Copy the code

Or create a.babelrc file in the root directory

{
  "presets": []."plugins": [
    "@babel/plugin-transform-arrow-functions"."@babel/plugin-transform-destructuring"]}Copy the code

Run the command

npx babel test.js
Copy the code

The output is consistent with the CLI configuration.

@babel/plugin

Plugin usage is detailed in the previous section.

Babel plugins documentation

Plugin is a syntax conversion tool directly acting on the code. It defines the transformation rules of the specified syntax and internally calls the transform method of @babel/core to achieve the syntax conversion. Plugin focuses on the transformation logic, and @babel/core implements the transformation operation relationship.

Based on the Visitor Visitor pattern, plugin isolates the operations of a node in the AST abstract syntax tree resolved by a scoped code block and transforms the code block of interest without changing the AST structure.

The plugin development

Based on the visitor pattern, the plug-in first parses the code block into an AST abstract syntax tree, then traverses the tree nodes to find the node it wants to visit, and then reassembles the AST of this piece of code based on specific rules. Finally, it calls the method of AST generating code, and converts the TRANSFORMED AST into code block again. Thus realize the translation of the code.

Create the Babel plug-in tutorial

  • BabelUsing aESTreeAnd modifiedAST
  • @babel/typesYou can create an AST based on options.@ Babel/types of documents

A simple example of code to achieve the conversion of the arrow function

// The Babel core library is used to implement the core transformation engine
let babel= require('@babel/core');
// Can realize type judgment, generate AST node
let types = require('@babel/types');
let code = `let sum = (a,b)=>a+b`; // let sum = function (a,b){return a+b}
// This visitor can process specific types of nodes
let visitor = {
 ArrowFunctionExpression(path){
   let params = path.node.params;
   let blockStatement = types.blockStatement([
       types.returnStatement(path.node.body)
   ]);
   let func = types.functionExpression(null, params, blockStatement, false.false); path.replaceWith(func); }}let arrayPlugin = {visitor}
// Inside Babel, the code is converted to AST and then iterated,

console.log(code)
let result = babel.transform(code,{
   plugins:[
       arrayPlugin
   ]
})
console.log(result.code);
Copy the code

output

let sum = (a,b)=>a+b
let sum = function (a, b) {
 return a + b;
};
Copy the code

@babel/preset

A set of plug-ins is easy to use by using or creating a Preset.

The official preset

  • @babel/preset-env

    More configuration

    @babel/ PRESET -env is an intelligent preset that allows you to use the latest JavaScript without micromanaging the syntactic conversions (and the optional browser polyfill) required for the target environment. This all makes your life easier and JavaScript packages smaller!

    Note that @babel/preset-env will generate a list of plug-ins to compile based on the target environment you are configuring. For browser-based or Electron projects, the official recommendation is to use the.browserslistrc file to specify the target environment. By default, if you don’t have in Babel configuration files (such as the babelrc) set the targets or ignoreBrowserslistConfig, @ Babel/preset – env will use browserslist configuration source.

    If you do not want to be compatible with all browsers and environments, it is recommended that you specify the target environment so that your compiled code is kept to a minimum.

    For example, only polyfill and transcoding required by users with more than 0.25% of the browser market share is included (ignoring browsers without security updates such as IE10 and BlackBerry) :

    //. Browserslistrc > 0.25% not deadCopy the code

    See more configurations of Browserslist

  • @babel/preset-flow

    More configuration

    This default is recommended if you use Flow, a static type checker for JavaScript code. It contains the following plugins: -@babel /plugin-transform-flow-strip-types

  • @babel/preset-react

    More configuration

  • @babel/preset-typescript

    More configuration

@babel/plugin-transform-runtime

A plug-in that reuses helper code injected by Babel to save code size.

npm install --save-dev @babel/plugin-transform-runtime
The helper is installed as dependencies as needed at runtime
npm install --save @babel/runtime
Copy the code

Configure the reference

// .babelrc
{
 "plugins": [["@babel/plugin-transform-runtime",
     {
       "helpers": true."regenerator": true."useESModules": false,}]]}Copy the code