Biography of little tadpole: front-end practical skills, accurate operation of js files through babel

Posted by Reaper0167 on Wed, 08 Dec 2021 06:02:15 +0100

Today is the 90th day of secretly falling in love with her, but I will be lovelorn soon

Because of the change of organizational structure, I want to change to a place far away from her

I've been in 997 for 90 days

Killing each other with the same kind every day

I'm tired of working overtime with a group of old men

She is the only light in this dark time

She was the chairwoman of the annual meeting

Thousands of men secretly love the goddess, and I'm just an overtime dog

She was surrounded by flowers and applause

I'm surrounded by stingy guys and LSP s

She wears beautiful clothes and famous brand bags every day

And I only have a yellow coat and a big black bag with a computer

I don't deserve her, but I'm deeply attracted to her

After seven years of marriage, I go home every day after work

Don't smoke, don't drink, don't be close to women

The first man of Tencent

Now I have feelings for her

I thought I was single-minded. I didn't understand until I met her

It turns out that men can really fall in love with several women at the same time

Before leaving, I don't know whether to confess to her or not

If I confess, she will say I am a good man

If you look better, don't you have to feel inferior

Unfortunately, without if, I am a perfect garbage

In this way, a version of the code was launched distractedly, and the configuration file was also modified incorrectly

Direct online big bug

All pages 404 not found

1000 alarm emails were bombed indiscriminately

boss tactfully sent a hint of one star performance

I'm going to cry

Configuration files, which are manually modified, are too easily affected by emotions to correct mistakes

These repetitive and error prone operations should be solved by engineering and automatic means

Implementation principle of babel modifying js configuration file

Full code reference: github.

Like those js configuration files, there may be a lot of non configuration code, and several files may be modified at a time

For example, in our front-end project, to insert a page, we need to modify the router, menu and other configuration files, and manually copy the page template

These highly repetitive mechanized operations and manual modification are very error prone

We can directly use babel to operate the AST abstract syntax tree and modify it accurately through engineering. Let babel help us find the specified location and insert the configuration code correctly. When we do engineering development, we often use babel to operate AST.

First, let's understand what AST is

AST, Abstract Syntax Tree, is an abstract representation of the syntax structure of source code. It represents the syntax structure of programming language in the form of tree.

We use babel to transform and operate AST, which is mainly divided into three steps: parser, traverse and generator

Three stages of AST operation

As shown in the following figure, if we want to insert a piece of configuration code into the configuration file through babel, how should we implement it

Parse

Step 1: read the configuration file code and generate the AST abstract syntax tree

let configJsData = fs.readFileSync(configJsPath, "utf8");

Then the configuration file code is generated into an AST abstract syntax tree

const parser = require("@babel/parser");

let configJsTree = parser.parse(`${configJsData}`,{
    sourceType: "module",
    plugins: [
      "jsx",
      "flow",
    ],
  });

configJsTree is our AST

The configuration attribute sourceType: "module" is added to enable babel to support the resolution of export and import

Transform (traverse)

The traverse phase is to traverse the entire AST abstract syntax tree, find the specified location, and then insert the corresponding configuration code.

The code is as follows:

const traverse = require("@babel/traverse").default;

traverse(configJsTree, {
    ObjectProperty(path) {
      // Insert profile code
    },
  });

We use the traverse method of @ babel/traverse to traverse the entire AST

ObjectProperty is used to identify all Object objects in the process of traversing AST. Because we want to insert the configuration code into an Object object Object, we use ObjectProperty. If you want to insert a configuration into an array, use ArrayExpression.

Then we start to insert the configuration code

{
  key: "testPath",
  icon: HomeOutlined,
  exact: true,
}

Insert the following position

We need to find the location and insert code in the ObjectProperty of traverse

First, we need to find the location of key: 'home'

The code is as follows:

traverse(configJsTree, {
    ObjectProperty(path) {
      if ( path.node.key.name === "key" && path.node.value.value === "home" ) {
        // This is the location of key: 'home'
      }
    },
  });

Find the Object object with the Object attribute of key and the Object value of home through path.node.key.name and path.node.value.value

Start inserting code when the location is found

traverse(configJsTree, {
    ObjectProperty(path) {
      // Search and identify the location of the object key: "home" in the configuration file
      if ( path.node.key.name === "key" && path.node.value.value === "home" ) {
        path.parent.properties.forEach(e=>{
          if ( e.key.name === "children" ) {
           // Find the children property
          }
        })
      }
    },
  });

Find the parent of the object through path.parent.properties, and then traverse all the properties under the parent to find the property children. This is where we want to insert.

Next, we will construct the data to be inserted

{
   key: "testPath",
   icon: HomeOutlined,
   exact: true,
}

The code for constructing data is as follows:

const t = require("@babel/types");

const newObj = t.objectExpression([
    t.objectProperty(
      t.identifier("key"),
      t.stringLiteral("testPath")
    ),
    t.objectProperty(
      t.identifier("icon"),
      t.identifier("HomeOutlined")
    ),
    t.objectProperty(
      t.identifier("exact"),
      t.booleanLiteral(true)
    ),
  ]);

You can see that the attribute of the object is identified by i dentifier, the string data is identified by stringLiteral, and the boolean value is identified by boolean literal. These types can be queried in @ babel/types.

Finally, insert the constructed data into:

e.value.elements.push(newObj)

Done ~!

Summarize all traverse phase codes as follows:

const traverse = require("@babel/traverse").default;
const t = require("@babel/types");

traverse(configJsTree, {
    ObjectProperty(path) {
      // Search and identify the location of the object key: "home" in the configuration file
      if ( path.node.key.name === "key" && path.node.value.value === "home" ) {
        path.parent.properties.forEach(e=>{
          if ( e.key.name === "children" ) {
            const newObj = t.objectExpression([
              t.objectProperty(
                t.identifier("key"),
                t.stringLiteral("testPath")
              ),
              t.objectProperty(
                t.identifier("icon"),
                t.identifier("HomeOutlined")
              ),
              t.objectProperty(
                t.identifier("exact"),
                t.booleanLiteral(true)
              ),
            ]);
            e.value.elements.push(newObj)
          }
        })
      }
    },
  });

generator

This stage is to reverse solve the AST abstract syntax tree and generate our regular code

const generate = require("@babel/generator").default;

const result = generate(configJsTree, { jsescOption: { minimal: true } }, "").code;

fs.writeFileSync(resultPath, result);

Reverse the AST abstract code syntax tree to the original code through @ babel/generator. Jsescoption: {minimal: true} is configured to solve the problem that Chinese is unicode garbled.

So far, we have finished inserting code into the js configuration file. The final results are as follows:

The above is the whole process of operating AST through babel and then accurately inserting the configuration code. For the complete code, refer to: github.

ending

After everything on the line is stable

I looked back at the goddess

She is looking in the mirror and applying lipstick

Just sit quietly. I like it very much

She loves to laugh and plays basketball every Wednesday. She arrives at the company on time at 10:30 in the morning and likes coffee and milk tea

Her life is a song every day

And I just knock the code and work overtime to add leg cramps

According to the informant, she already has a boyfriend, tall, handsome and rich

And I'm old and ugly, poor and bald

I hear she's still young, and I'm 32

I'll be 35 in less than three years. I don't have much time

How can you miss the fireworks in the world

Women only affect the speed at which I type code

Hey... Damn it

I'd better protect her, support her and appreciate her silently

Not interrupting is loser's highest confession

It's just a pity

From beginning to end, I didn't know her name

We never said a word

It's all my own monologue

Lu Xun said, "I know you are not my flower, but it's my great honor to pass through your bloom."

. . . . . .

The empty headquarters building at night

Just sit beside each other silently

Just think we were together

This parting may never be seen again

I wonder if you will think of me

I don't know if I will fall in love with other girls

But thank you

Amazing every night I work overtime

goodbye my lover

--— yours small tadpole

Author: The first little tadpole The official account: the tadpole of the first place.

Topics: Javascript node.js Front-end html5 css