8
头图

Today is the 90th day of having a crush on her, but I will soon fall in love

Because of organizational changes, I have to move to a place far away from her

In the 90 days of crushing her, I have been in 997

I kill 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 hostess of the annual meeting

The goddess whom thousands of men have a crush on, and I'm just an overtime dog

She is surrounded by flowers and applause

I'm surrounded by big guys and LSPs

She wears nice clothes and designer bags every day

And I only have a yellow blouse and a big black bag for a computer

I am not good enough for her, but I am deeply attracted by her

After 7 years of marriage, I go home every day after get off work

No smoking, no drinking, no sex with women

Tencent's first male ethics

Now I actually feel affection for her

I thought I was very dedicated, but I didn’t understand until I met her

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

Before leaving, I don’t know if I want to confess to her

If she confessed, she would definitely say that I am a good person

If you look better, don’t you need to be inferior

It's a pity that there is no if, I am a perfect rubbish

In this way, I was upset and launched a version of the code, and the configuration file was modified incorrectly.

Directly crash out the big online bug

404 not found on all pages

1000 alarm emails bombed indiscriminately

The boss tactfully sent a hint of 1 star performance

Almost crying

It’s too easy to be affected by emotions to correct things like configuration files manually.

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

Babel modify the js configuration file implementation principle

Complete code reference: github .

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

For example, if we want to insert a page in the front-end project, we need to modify the configuration files such as router and menus, and manually copy the page template, etc.

These highly repetitive mechanized operations are very error-prone for manual modification

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

First, let’s understand what AST is

AST, Abstract Syntax Tree (Abstract Syntax Tree) It is an abstract representation of the source code syntax structure. It expresses the grammatical structure of a programming language in a tree-like form.

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

Three stages of operating AST

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

Parser

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

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

Then generate the AST abstract syntax tree from the configuration file code

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

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

configJsTree is our AST

sourceType: "module" is added to allow babel to support the analysis of export and import

Conversion (traverse)

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

code show as below:

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

traverse(configJsTree, {
    ObjectProperty(path) {
      // 插入配置文件代码
    },
  });

We use @babel/traverse to traverse the entire AST

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

Then we began to insert the configuration code, and the code

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

Insert the following position

We need to traverse the position and insert the code ObjectProperty

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

code show as below:

traverse(configJsTree, {
    ObjectProperty(path) {
      if ( path.node.key.name === "key" && path.node.value.value === "home" ) {
        // 这就是 key: 'home'的位置
      }
    },
  });

Find the Object object path.node.value.value key and the object value is home through path.node.key.name and 061b00aac2bb3e

After finding the location, start inserting the code

traverse(configJsTree, {
    ObjectProperty(path) {
      // 搜索并识别出配置文件里key: "home" 这个object对象位置
      if ( path.node.key.name === "key" && path.node.value.value === "home" ) {
        path.parent.properties.forEach(e=>{
          if ( e.key.name === "children" ) {
           // 找到children属性
          }
        })
      }
    },
  });

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

Next we have to construct the data to be inserted

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

The code to construct the 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 dentifier used to identify the attributes of an object, stringLiteral identify string data, and booleanLiteral identify boolean values. These types can all be queried @babel/types

The last step is to insert the constructed data:

e.value.elements.push(newObj)

Finished~!

The code of all traverse phases is summarized as follows:

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

traverse(configJsTree, {
    ObjectProperty(path) {
      // 搜索并识别出配置文件里key: "home" 这个object对象位置
      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 the AST abstract syntax tree to generate our regular code

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

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

fs.writeFileSync(resultPath, result);

@babel/generator the AST abstract code syntax tree back to the original code through jsescOption: { minimal: true } configuration is to solve the problem of Unicode garbled in Chinese.

So far we have finished inserting code into the js configuration file, and the final result is as follows:

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

end

After everything is stable online

Looking back at the goddess

She is looking in the mirror and putting on lipstick

I just sit quietly, I like it so much.

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

Every day in her life is a song

And I can only type code, work overtime until my leg cramps

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

And I'm old and ugly, not only poor but also bald

I heard that she is still very young, and I am 32

I will be 35 in less than 3 years, my time is running out

How can I 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

Do not disturb is the most advanced confession of diaosi

It's just a pity

From beginning to end, I don’t know what her name is

We never said a word

It's all my one-man show

Lu Xun once said: "I know you are not my flower, but I am honored to be able to pass through your blooming."

。。。。。。

The headquarters building with no one in the night sky

Just sitting beside each other in silence

Just assume that we have been together before

This parting may never be seen again

I don't know if you will think of me

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

But thank you anyway

Amazing every night I work overtime

goodbye my lover

————— yours small tadpole

Author: first place tadpole , public account: first place tadpole

第一名的小蝌蚪
2.5k 声望1.3k 粉丝

腾讯前端切图犬