This is the sixth day of my participation in Gwen Challenge

Write this up front: This is a bullshit usage. In the face of unreasonable requirements, it is recommended to communicate with the rule-maker to find out what they really want.

So the story begins.


Some time ago, a member of a tech group mentioned:

The corporate specification group promotes code specifications that require code to be commented at 1/3 of the line of code. Now for an auto-comment solution, let’s get this thing over with.

When it comes to commenting code, mature ides or code editors have plug-ins or code templates that do the same.

In vscode’s case, plug-ins can use koroFileHeader or Document This. Koro can even add character paintings

But if you’re adding comments to existing code, one solution you can think of is a refactoring tool.

Refactoring tools enable developers to refactor large code bases in a short period of time. In some cases, developers may use the IDE to perform refactoring of class or variable names, but it is usually limited to one file at a time. The refactoring tool allows global search and replace.

Some of the best known JS refactoring tools are Facebook’s Codemod and Jscodeshift. Both are based on Esprima.

Both vue and React have their own refactoring tools, react-codemod and VUe-codemod, both of which are supported by Jscodeshift.

To accelerate JavaScript development and refactoring, see the Jscodeshift tutorial, jscodeshift, and Using refactoring (Codemod)

How does jscodeshift play a refactoring role?

Jscodeshift parses JS into an AST syntax tree, and then provides a convenient interface to make changes to each node, such as changing all attribute names.

Take the official code as an example:

const j = require('jscodeshift');

j(jsContent)
    .find(j.Identifier)
    .replaceWith(
      p= > j.identifier(p.node.name.split(' ').reverse().join(' ')));Copy the code

Execute this code to convert console.log(‘123’) to elosnoc.gol(‘123’).

Try to solve the problem

You can also use jscodeshift to resolve your problems.

The solution can be divided into three steps:

Graph TD code analysis --> Write transformation code --> Perform transformation

The code analysis

You first need to transform your code into an AST tree. Once you have an AST tree, you can use the Jscodeshift selector to perform a lookup operation on your PATH.

There is an AST online profiling tool that converts code to an AST.

For example, in the figure below, function is resolved to FunctionDeclaration, foo is resolved to id, and x and y are resolved to params.

Write conversion code

According to the AST tree, we can find the location of the annotation, and add the prewritten annotation template in the corresponding location.

Find where to add comments

For the list of code on the left, we expect to add the necessary comments above the variable A and above the function. By looking at the AST tree on the right, we can first locate VariableDeclaration and functional Declaration. The positioning method is as follows:

export default function transformer(file, api) {
  const j = api.jscodeshift;
  const source = j(file.source)

  source.find(j.VariableDeclaration) / / variable
  source.find(j.FunctionDeclaration) / / function

  / /... Other code
}
Copy the code

Writing comment information

To look standard, we write comments in JSDoc format.

The following is a sample jSdoc comment:

In that case, let’s copy one in this fashion. The corresponding real name in the code in ${.*} format

/** The good ${varName}. */
export var lastColor = null;

/**
 * A good function.
 * @param {string} ${param1} - The good param, in suitable format.
 * @param {string} ${param2} - The good param, in suitable format.
 * @return {string} i don't know.
 */
export function blend(color1, color2) {}
Copy the code

Then we build the annotations. Block comments are constructed using the commentBlock method.

Finally, write a transformation function to put the above annotation method in place. The complete code listing is as follows:

export default function transformer(file, api) {
  const j = api.jscodeshift;
  const source = j(file.source)

  / / variable
  source.find(j.VariableDeclaration).forEach(p= > {
    const comments = p.node.comments = p.node.comments || [];

    p.node.declarations.forEach(d= > {
      const comment = j.commentBlock(`The good ${d.id.name}. `.true.false); // Generate line commentscomments.push(comment); })});/ / function
  source.find(j.FunctionDeclaration).forEach(p= > {
    const comments = p.node.comments = p.node.comments || [];

    let commentArr = []
    commentArr.push(`A good function named ${p.node.id.name}. `)
    p.node.params.forEach(d= > {
      commentArr.push(`@param {string} ${d.name} - The first param, in suitable format.`)
    })
    commentArr.push(`@return {string} i don't know.\n `)

    const comment = j.commentBlock(commentArr.map(c= > `\n * ${c}`).join(' '), true.false); // Generate block comments
    comments.push(comment);
  });

  return source.toSource();
}
Copy the code

See here for the results

Perform the conversion

The conversion code is written and the local runtime environment is installed before execution

npm install -g jscodeshift
Copy the code

Then we execute the conversion code directly on the console:

jscodeshift -t ./transformer.js ./test.js
Copy the code

The console outputs the conversion results.

Depending on the results of the transformation, you can adjust the transformation code to achieve the purpose of the entire transformation.

Language support

Js file natural support, TS file official also provides to open the configuration of a dedicated parser. React JSX and TSX files are also available.

As for the VUE template, I haven’t tested it, but the vUE official also provides conversion tools, I guess it is also possible.