How to clearly price the team's unspoken rules

Reliable front-end teams generally introduce their own code style specifications, but problems in real projects are often not solved by unifying the number of spaces and whether to add semicolons, but there are many invisible pits. Do we have a higher level of control over code quality beyond code style? The ESLint plugin might be able to open up new worlds for you.

In this era of rapid development of front-end, we are actually facing the increasingly severe problem of front-end code corruption. For example, all students who have taken over and maintained front-end projects should have encountered such a scenario:

  • The agreed-upon module path, naming method and other specifications are not followed, and the project development is like a mess.
  • To do the same thing, some places use third-party libraries, some places use internal libraries, and some places rewrite them by themselves.
  • The old grammar and the new grammar coexist. For example, the way to import a library, there are ESM / CommonJS / UMD and so on.
  • ……

According to the broken window theory, if bad phenomena in the environment are allowed to exist, they will induce people to follow suit, or even intensify. However, the phenomenon of entropy increase in the code does not mean that programmers are criminals. In many cases, the above problems actually originate from the implicit unspoken rules in the project that are unfamiliar to newcomers :

  • If a new student doesn't know that we are used to importing lodash/xxxto reduce the package size, he may import lodash in full.
  • If a new student does not know that we have encapsulated a basic library for handling common business requirements such as requests and serialization, he may install a third-party library or even reinvent the wheel.
  • If a new student doesn't know that our business components are agreed to inherit from a common base class, then he may start a new version that is easiest for him to understand.
  • ……

The consistency problem at this level has gone beyond whether to use spaces or tabs, or whether to add semicolons at the end of lines. The existing code style checking tools on the market are "not so wide." Of course, this level of problems can indeed be solved with Code Review, but manual review may not be able to be pushed away in every team that advertises agile and Moving Fast. So, do we have more efficient means to settle these implicit "unspoken rules"? Here we try to give an answer: write your own business lint plugin .

In 2018, ESLint is basically an essential dependency in reliable front-end scaffolding. But in most cases we use an existing code style guide. But ESLint can actually not only be used to detect style issues such as spaces and line breaks. When combined with business development specifications, you will find that it also has great potential. And the process of writing an ESLint plugin from scratch is actually not complicated, let's see how to practice it:

Environment configuration

Like normal front-end projects, ESLint plugins also provide a set of scaffolding out of the box. Just install the global dependencies:

npm install -g yo generator-eslint

We can create our own plugin:

mkdir eslint-plugin-demo
cd eslint-plugin-demo

yo eslint:plugin

? What is your name? ...
? What is the plugin ID? demo
? Type a short description of this plugin: ...
? Does this plugin contain custom ESLint rules? Yes
? Does this plugin contain one or more processors? No

npm install

Initializing a plugin is create-react-appas easy as , right?

Create a rule

Now it's time to create our first Lint rule! As an example, the whitespace-compulsive writer doesn't like to see comments like this in code:

// 获取abc数据2次

The convention of Chinese typesetting on the Web is actually like this:

// 获取 abc 数据 2 次

But not everyone insists on manually inserting spaces in the WeChat chat like the author, and forcibly changing other people's comments in the commit record also feels uncomfortable for others. So how do we upgrade this convention to ESLint's rules? We need to understand a little bit of how ESLint works.

ESLint uses Espree, the JavaScript parser, to parse your project source code. Parser will parse the source code string into an abstract syntax tree (AST). For each node in the tree, ESLint will find whether there is a matching rule, and if it matches, calculate whether the rule is satisfied. And what does an AST look like? For example, a one // hello world- JS code file, the AST format is as follows:

{
  "type": "Program",
  "start": 14,
  "end": 14,
  "body": [],
  "innerComments": [
    {
      "type": "Line",
      "value": " hello world",
      "start": 0,
      "end": 14
      "range": [
        0,
        12
      ]
    }
  ],
  "//": "......"
}

Based on this data structure, if we want to add rules to all variable declaration statements, our plugin rules will look like:

module.exports = function (context) {
  return {
    'VariableDeclaration' (node) {
      // 在这里搞事情
      // ...
    }
  }
}

VariableDeclarationWhere did this come from? This is the time to show your familiarity with ES Spec as a senior front-end! In fact, each statement in JavaScript has a corresponding type defined in the specification, and we can write the rules for checking it according to the type name. If we want to verify the annotation, Commentjust . Isn't it intuitive?

The above method can be understood as a very classic Visitor mode. While it is convenient to write rules declaratively, it also has the problem of complete transparency between adjacent nodes, which is inconvenient for some complex operations. So you can also use some of the more procedural APIs to aid in the writing of rules:

module.exports = {
  create: function (context) {
    const sourceCode = context.getSourceCode()

    return {
      // Program 相当于 AST 根节点
      Program () {
        const comments = sourceCode.getAllComments()
        comments.forEach(node => {
          if (/* 满足校验规则 */) {
            context.report(node, 'Something WRONG!')
          }
        })
      }
    }
  }
}

For our current need to detect whitespace, a ready-made dependency is pangu.js. We can achieve verification by calling pangu's formatting API at the comment above. However, when actually writing your own plug-ins, the specific business rules are often not difficult, but the difficulty actually lies in being familiar with the JS syntax tree structure. The tool astexplorer is especially recommended here , which can intuitively let you understand the AST structure corresponding to the source code and facilitate the writing of verification rules.

At this point, we should have some intuitive understanding of writing rules. Going back to the question posed at the beginning, we can use ESLint to prescribe the right medicine:

  • For a particular module file, we can write ESLint rules that require its variable names to meet special conventions.
  • For the native API encapsulated by the team base library, its appearance is prohibited in the ESLint rules, so as to avoid problems such as re fetch- .
  • For syntax usage that does not conform to best practices, we can warn you in time. For example, when it is found that the require statement _is lodashassigning to or , this will probably lead to a dramatic increase in the size of the package, which can be avoided by writing rules.
  • ……

test drive

We already know how to write flexible validation rules, but most of these codes are not encountered in daily business development. How to ensure that it is reliable? This requires us to introduce a test-driven development model.

In the plugin's package.json, there will be a script like this:

"scripts": {
  "test": "mocha ./tests/**/*.js"
}

As an example, let's add a test case to the /testsdirectory spacing-test.jsand fill it with something like this:

const rule = require('../lib/rules/spacing')
const RuleTester = require('eslint').RuleTester

const ruleTester = new RuleTester()
ruleTester.run('comment', rule, {
  valid: [
    '// 白色相簿 2'
  ],
  invalid: [
    {
      code: '// 白色相簿2',
      errors: [{
        message: 'Something WRONG!',
        type: 'Line'
      }]
    }
  ]
})

This is the fundamental way to drive ESLint plugin development through tests. The code fragments that the rules hope to cover can be provided in the form of test cases, which will greatly facilitate the understanding and maintenance of later generations. After writing the test case, the way to execute the test case is also very simple:

npm test

If all the test cases pass, it means that the plug-in is done! All that's left is to publish it on NPM, and import it in your project according to how the ESLint plugin is configured. In the README generated for you by the first step of scaffolding, this process has been well documented, so I won't go into details here.

Summarize

Many front-end students will read the specification documents of ES Spec in order to delve into the technical depth. But unfortunately, the content at this level is often not very useful for general business development. But after you have the ability to develop (rather than use) ESLint plugins, coupled with your familiarity with JS itself, you will have a new feeling of unlocking the "code to control code" skill: use code to constrain and optimize The code itself, this is the power of Meta Programming.

The annotation plug-in written above has also been released to GitHub , and you are welcome to refer to it or try it out for students with obsessive-compulsive disorder. Finally, I suddenly thought of saying something...

The girl who is willing to add a space for you in WeChat must be true love.

Guess you like

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