babel plugin development

In development, babel needs to be used to convert js features that are not currently supported by browsers into versions that browsers can run.

However, there are some business features that babel cannot do for us. We need to develop babel plug-ins and apply them to our projects.

 

For example, there are two classes

class A {
    doSomething() {
        console.log('Something was done in A');
    }
}

class B extends A {
    doSomething() {
        console.log('Something was done in B');
    }
}

 

Class B writes its own methods in its own class, but if our project requires our subclass of A to implement its own doSomething, it must first execute A's doSomething. Because A may have done some common things, it is not necessary for each subclass to implement it again. If the method of the parent class A is not called, it may cause some unknown errors or other problems. It is obviously time-consuming, labor-intensive and difficult to ensure quality by manually reviewing the code for such a requirement. It is more reliable to leave it to the program.

 

Write the plugin file myplugin.js

module.exports = function(babel) {
  const t = babel.types;

  return {
    visitor: {
      ClassMethod (path) {    
        if (path.node.key.name == 'doSomething' && path.parentPath.parent.superClass && path.parentPath.parent.superClass.name === 'A') {
          var hasCallSuper = false;
          path.traverse({
            CallExpression(path){
              if (t.isMemberExpression(path.node.callee) && t.isSuper(path.node.callee.object) && 'doSomething' === path.node.callee.property.name) {
                hasCallSuper = true;
                path.stop();
              }
            }
          });
          if (!hasCallSuper) {
            throw path.buildCodeFrameError('If a subclass of A implements doSomething, it needs to implement A's doSomething. Please add \nsuper.doSomething();\n')
          }
        }
      }
    }
  };
};

 

Roughly speaking about the implementation of the plugin:

The main thing is to define various types of detection methods in the visitor. Here ClassMethod is used to detect class methods

First determine whether the method name is doSomething and there is a parent class, and the parent class name is A

Then traverse the doSomething method through the path.traverse method. The parameter of the traverse method is actually a visitor.

This is the CallExpression is the method call.

If it is a member function, and the caller is the super method name is doSomething, the mark has been called super.doSomething

 

Finally if not called. Just prompted the user by throwing path.buildCodeFrameError('error message')

 

The operation effect is as follows:


  

An error message is given and the code location is suggested.

 

 

The above is just a simple application scenario. According to different business scenarios, more complex plug-ins need to be written.

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326174869&siteId=291194637