Pre-read: The Babel plugin manual

directory

  • Babel is introduced
  • Babel purposes
  • How does Babel escape code?
  • Babel development apis
  • Babel’s built-in features
  • Example of the Babel Plugin

Babel is introduced

Babel’s predecessor was 6to5, which was released in 2014 and featured a transition from ES6 to ES5. He changed his name to Babel.

Babel is the tower of Babel, the tower of Babel in Babylonian civilization when all the people on earth spoke the same language, and when they left the east, they came to the land of Shinar. There, people tried to burn bricks so that they could build a city and a tower that reached into the clouds and spread their fame, so that they would not be scattered all over the world. God came down to earth and saw this city and this tower, and said that people who spoke only one language could do nothing; So God disrupted their language so that they could not understand each other, scattered them all over the world, and the building of the city stopped. The city became known as the city of Babel. — Genesis 1.2

Babel purposes

1. Translate js supported by the target environment, such as ESNext and typescript

High – level language to low – level language is called compilation, high – level language to high – level language is called translation

2. Code conversion

Taro is a grammatical translation using Babel, and there is another example.

3. Code analysis

Module analysis, Tree-shaking, code compression, Linter, etc

How does Babel translate code?

Parse the source string, generate an AST, convert code changes into additions and deleters to the AST, and then print the AST as the object code string.

Babel plugin development API

Babel package

Different apis are used for different stages of Babel translation

1. Parse phase use@babel/parserThe function is to convert source code into AST


require('@babel/parser').parse(source, {

sourceType: 'module'.plugins: ['jsx'.'flow'.'classProperties'.'decorator'.'decorators-legacy']});Copy the code

Plugins: Specify JSX, typescript, flow, and other plugins to parse the corresponding syntax

SourceType: Module, script, and unambiguous values. Module indicates the syntax of ES module to be resolved

The Babel of AST

Babel AST tree view

2. Use in the transform phase@babel/traverseYou can iterate over the AST and call a visitor function to modify the AST. Modifying the AST involves AST judgment, creation, modification, and so on@babel/typesWhen the need to batch create AST can be used@babel/templateTo simplify AST creation logic.


require('@babel/traverse').default

function traverse(ast,vistor) / /vistorIt could be a function it could be an object, but a function isenterNodevistorThe name is the node name and the object isenterandexitThe function called.tipsMultiple nodes can be 'FunctionDeclaration|VariableDeclaration'

Copy the code

require('@babel/traverse').default(ast, {

Program(path,state){}})Copy the code

// path api

{

"parent": {... },"node": {... },"hub": {... },"contexts": []."data": {},

"shouldSkip": false."shouldStop": false."removed": false."state": null."opts": null."skipKeys": null."parentPath": null."context": null."container": null."listKey": null."inList": false."parentKey": null."key": null."scope": null."type": null."typeAnnotation": null,

get(key)

set(key, node)

inList()

getSibling(key)

getNextSibling()

getPrevSibling()

getAllPrevSiblings()

getAllNextSiblings()

isXxx(opts)

assertXxx(opts)

find(callback)

findParent(callback)

insertBefore(nodes)

insertAfter(nodes)

replaceWith(replacement)

replaceWithMultiple(nodes)

replaceWithSourceString(replacement)

remove()

traverse(visitor, state)

skip()

stop()

}

Copy the code

@babel/types is used to create and determine AST nodes and provides apis for XXX, isXxx, assertXxx

@ Babel/template examples

3. Generate prints the AST as an object code string and generates the Sourcemap, as required@babel/generatePackage, used when an error occurs and you want to print the location of the code@babel/code-framepackage


const { code,map } = generator(ast, { sourceMaps: true });

// sourceMaps is available only when sourceMaps is set to true

Copy the code

@ Babel/code – frame example

Babel’s built-in features

1. First, let’s look at what Babel needs to do

Convert from higher version syntax and API to lower version syntax and automatically polyfill the missing API.

Babel conversion

[ES2015]262.ecma-international.org/6.0/), ES201… And so on.

B. proposal

  • Phase 0: Just an idea, possibly implemented with the Babel Plugin

  • Stage 1: Recommendations worth continuing

  • Phase 2: Establish the spec

  • Phase 3: Complete the spec and implement it in the browser

  • Phase 4: Added to next year’s ES20XX spec

R. act, flow, typescript

Because of the syntax to be converted

Babel7’s built-in plug-ins to implement these features are divided into three categories: syntax, Transform, and proposal. Syntax specifies the syntax to be translated, transform converts the AST, and proposal does not include the AST transformation with features of language standards. When there are too many plug-ins a lot of common logic needs to be shared so this part is implemented in the helper.

Babel package

Because Babel has so many plugins that it is difficult to configure, the presets are designed in facade mode to make configuration easy.

Language standards of different versions are supported, such as preset- ES2015 and preset- ES2016. After babel7, preset-env is replaced

No support for standard language features: features for Stage0, StagE1, and Stage2, and a separate proposal plugin was introduced in Babel7

Support for React, JSX, and Flow: Package corresponding plug-ins as preset- React, PRESET – JSX, and PRESET -flow respectively, and use corresponding preset directly

D. Each feature is implemented with a Babel plug-in. When there are more Babel plug-ins, there will naturally be some common logic. How do we share this logic?

Babel designed a mechanism for sharing logic between plug-ins, called helpers.

There are two types of helpers:

  • One is the runtime global functions (such as class) injected into the AST

  • One is the utility functions that operate on the AST, such as the generic logic of variable promotion (such as constant definitions)

The Babel Runtime contains modules that are loaded at runtime and are packaged into the product by the packaging tool. The options are regenerator, Corejs, and Helper.

  • Corejs this is the new API’s polyfill and comes in versions 2 and 3, with 3 implementing instance method polyfill

  • Regenerator is the Runtime library of AyNC implemented by Facebook. Babel uses Regenerator – Runtime to support implementing async await support.

  • Helpers are functions that Babel uses to do syntax transformations, such as _typeof, _extends, and so on

2. The use of Babel


"presets": [["es2015",

{

"modules": false}]."react"."stage-2"

]

//babel6

Copy the code

"presets": [["@babel/preset-env",

{

"targets": "> 0.25%, not dead." "."useBuiltIns": "usage"."corejs": 3}]],"plugins": [[

"@babel/plugin-transform-runtime",

{

"corejs": 3}]]//babel7

Copy the code

Here we find a problem: why is there a target browser for targets? If you don’t have this it’s possible that the language of your target browser already supports it and you increase the Babel and increase the package size

Babel /preset-env causes the helper to be injected into the AST where the new feature is used. The use of @babel/ plugin-transform-Runtime is to bring these out of the module.

The Runtime code for Babel consists of two parts:

Part of this is for Polyfill, namely Corejs and ReGenerator (implementing async await), both of which are third-party implementations that Babel has integrated

The other part is the helper for transforming code, such as code that implements inheritance or implements classes, and is injected into the code by default

If @babel/ plugin-transform-Runtime is used, two changes will be made:

  1. Change the helper part of the code from injection to import from the @babel/ Runtime package

  2. The code in the Polyfill section is no longer a global import, but a module import.

So transform Runtime has two benefits:

  1. Remove the helper code for repeated injection and reduce the product volume

  2. Polyfills do not pollute the overall situation

But there are also corresponding problems

Babel will process the plug-in and preset in the following order:

  1. Use plugin first, then preset

  2. Plugin from front to back, PRESET from back to front

This can cause @babel/plugin-transform-runtime to be executed before the targets is reached. The unwanted Babel package has been added. This babel8 will solve this problem.

Finally, there is a question about the @babel/preset-typescript, TS-loader selection when Wen Tao shared TS last time

Babel is compiled in a single file, and each file is handled the same way. Internally, ts-Loader calls TypeScript’s official compiler, TSC. TSC compilers multiple files together because it parses module syntax, does type derivation, and checks during compilation, which is the biggest difference between the two processes. So TSC inevitably gets stuck with multiple files, whereas Babel has nothing to do with size. Babel does not resolve ts types, so namespace merge and const enum are not supported. Overall, Babel compiles TS code much faster. Babel generated code can also be compiled on demand for targets and introduce polyfills, which TSC does not support. Type check is required to run TSC –noEmit separately.


// tsconfig.json{..."compilerOptions": {"noEmit":true // Do not output files, only type checking}}Copy the code

Babel compiling typescript is a better choice

Example of the Babel Plugin

Let’s look at the demand

!

1. The page preview page of the small program should be written again on the B side

2. UI changes should be made on both sides at the same time.

The C-side code of Taro is applied to the Web side

Use Babel to compile to the B side to solve common code problems, use PostCSS to solve style problems

The first version

No mobx is just a matter of the component passing values twice the distance

Version 2

There are MOBX optimization CSS VH, etc

Learn about the idea of taro transformation

Design of taro component library

Taro’s goal is to implement component libraries that are available to frameworks like React and Vue.

Web Components

Taro cross-end component library design

Refer to the link

  • The Babel plugin

  • Babel plugin manual

  • Taro cross-end component library design

  • Babel compiling typescript is a better choice