Detailed explanation of steps to convert babel to es6

php中世界最好的语言
Release: 2018-04-20 11:23:12
Original
1511 people have browsed it

This time I will bring you a detailed step-by-step guide to converting babel to es6. What are theprecautions for converting babel to es6? The following is a practical case, let’s take a look.

Babel is a transcoder, which is currently used when developing react and vue projects. It can convert es6 syntax to es5, as well as JSX and other syntax.

In our projects, we all convert specific codes, such as env, stage-0, etc., by configuring plug-ins and presets (a collection of multiple plug-ins).

In fact, Babel can convert any code through custom plug-ins. Next, let’s learn about Babel through an example of “converting es6’s

classto es5”.

The content is as follows:

webpack environment configuration

Everyone should have configured the babel-core loader and its role It provides the core API of Babel. In fact, our code conversion is implemented through plug-ins.

Next, we will implement an es6 class conversion plug-in ourselves without using third-party plug-ins. First perform the following steps to initialize a project:

  1. npm install webpack webpack-cli babel-core -D

  2. Create a new webpack.config.js

  3. Configure webpack.config.js

If our plug-in name wants to be called transform-class, we need to make the following configuration in the webpack configuration:

Next we create a new folder of babel-plugin-transform-class in node_modules to write the logic of the plug-in (if it is a real project, you need to write this plug-in and Publish to npm warehouse), as shown below:

The red area is my newly created folder, and above it is a standard plug-in project structure. For convenience, I just write The core index.js file.

How to write a babel plug-in

The babel plug-in is actually implemented through AST (Abstract Syntax Tree).

babel helps us convert js code into AST, then allows us to modify it, and finally convert it into js code.

So there are two questions involved: What is the mapping relationship between js code and AST? How to replace or

addAST?

Okay, let’s first introduce a tool: astexplorer.net:

This tool can convert a piece of code into AST:

As shown in the figure , we wrote an es6 class, and then the right side of the webpage generated an AST for us, which actually turned each line of code into an

object, so that we implemented a mapping.

Introducing another document: babel-types:

This is the API document for creating AST nodes.

For example, if we want to create a class, we first convert it in astexplorer.net and find that the AST type corresponding to the class is

ClassDeclaration. Okay, let’s search in the documentation and find that just calling the following api is enough:

The same goes for creating other statements. With the above two things, we can No conversions were made.

Now we start to actually write a plug-in, which is divided into the following steps:

  1. Export a function in index.js

  2. The function returns an object, the object has a visitor parameter (must be called visitor)

  3. Query through astexplorer.net

    Outputclasscorresponding The AST node isClassDeclaration

  4. Set a capture function

    ClassDeclarationin the vistor, which means I want to capture allin the js code ClassDeclarationNode

  5. Write logic code and complete the conversion

module.exports = function ({ types: t }) { return { visitor: { ClassDeclaration(path) { //在这里完成转换 } } }; }
Copy after login

There are two parameters in the code. The first{types:t}thing is to deconstruct thevariablet from the parameters, which is actually t in the babel-types document (red box in the picture below), which is used to create nodes:

The second parameterpath, it It is the information corresponding to the captured node. We can obtain the AST of this node throughpath.node, and modify it on this basis to achieve our goal.

How to convert es6 class to es5 class

The above are all preliminary work, the real logic starts from now, let’s first Consider two questions:

We need to do the following conversion. First, convert es6 classes into es5 class writing (that is, ordinary functions). We have observed that many codes can be reused, including functions. Names, code blocks inside functions, etc.

If theconstructormethod in class is not defined, theJavaScriptengine will automatically add an emptyconstructor for it ()method, which requires us to do compatibility processing.

Next we start writing code, the idea is:

  1. Get the old AST node

  2. Create an array with To hold the new AST node (although the original class is only one node, it will be replaced by several function nodes after replacement) Initialize the defaultconstructornode (mentioned above, the class may not be defined constructor)

  3. Loop the AST object of the old node (several function nodes will be looped out)

  4. Judge whether the type of the function isconstructor, if so, create a normal function node by getting the data, and update the defaultconstructornode

  5. to process the rest that are notconstructornode, create a function of typeprototypethrough data, and place it ines5Fns

  6. End of the loop, putconstructorThe node is also placed ines5Fns

  7. Determine whether the length of es5Fns is greater than 1. If it is greater than 1, usereplaceWithMultipleThis API updates the AST

module.exports = function ({ types: t }) { return { visitor: { ClassDeclaration(path) { //拿到老的AST节点 let node = path.node let className = node.id.name let classInner = node.body.body //创建一个数组用来成盛放新生成AST let es5Fns = [] //初始化默认的constructor节点 let newConstructorId = t.identifier(className) let constructorFn = t.functionDeclaration(newConstructorId, [t.identifier('')], t.blockStatement([]), false, false) //循环老节点的AST对象 for (let i = 0; i < classInner.length; i++) { let item = classInner[i] //判断函数的类型是不是constructor if (item.kind == 'constructor') { let constructorParams = item.params.length ? item.params[0].name : [] let newConstructorParams = t.identifier(constructorParams) let constructorBody = classInner[i].body constructorFn = t.functionDeclaration(newConstructorId, [newConstructorParams], constructorBody, false, false) } //处理其余不是constructor的节点 else { let protoTypeObj = t.memberExpression(t.identifier(className), t.identifier('prototype'), false) let left = t.memberExpression(protoTypeObj, t.identifier(item.key.name), false) //定义等号右边 let prototypeParams = classInner[i].params.length ? classInner[i].params[i].name : [] let newPrototypeParams = t.identifier(prototypeParams) let prototypeBody = classInner[i].body let right = t.functionExpression(null, [newPrototypeParams], prototypeBody, false, false) let protoTypeExpression = t.assignmentExpression("=", left, right) es5Fns.push(protoTypeExpression) } } //循环结束,把constructor节点也放到es5Fns中 es5Fns.push(constructorFn) //判断es5Fns的长度是否大于1 if (es5Fns.length > 1) { path.replaceWithMultiple(es5Fns) } else { path.replaceWith(constructorFn) } } } }; }
Copy after login

Optimizing inheritance

In fact, classes also involve inheritance, and the idea is not complicated. It just determines whether there is any in the ASTsuperClassattribute, if any, we need to add one more line of codeBird.prototype = Object.create(Parent), of course don’t forget to handle thesuperkey Character.

Packaged code

Runnpm startAfter packaging, we see the packaged fileclass

The syntax has been successfully converted into es5 functions one by one.

I believe you have mastered the method after reading the case in this article. For more exciting information, please pay attention to other related articles on the php Chinese website!

Recommended reading:

How to upgrade vue cli to webapck4

Detailed steps for AngularJS application modularization

vue-cli 3.0 What beginners need to know

The above is the detailed content of Detailed explanation of steps to convert babel to es6. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!