This paper introduces the practical application of code standardization in our team from the aspects of code specification, code inspection, code formatting, and editor automation.

Outline the preview

The content of this article includes the following aspects:

  • Understanding code specifications
  • Develop and unify specifications
  • ESLint
  • Prettier Prettier
  • VSCode
  • Appendix: Naming and project structure specifications

Understanding code specifications

Let’s start with two questions:

  1. What is a code specification?
  2. Why do you need a code specification?

If you’re a seasoned front-end developer, you’ve probably worked on old projects where variable names are arbitrary like ABC and FDS, or numeric names like name1 and name2, which are uncommented so you don’t know what they do.

This type of code is a classic example of noncanonical code. Aside from making us developers cranky, the most important problem with such code is that it greatly reduces the efficiency of teamwork and the quality of programs.

In teamwork, when other people in the group need to use or review your code, they will spend a lot of time understanding what you have written, in addition to criticizing you. At the same time, it is very easy to cause variable conflicts, unknown hidden dangers, debugging difficulties and other problems, and even can see a programmer’s coding attitude and professional degree.

Of course, there are many aspects to the code specification, and the variable naming specification is only the most basic specification. The more irregularities there are, the lower the quality of the application, and the less effective the team collaboration will be.

With this knowledge of non-standard code and the problems it causes, we, as front-end architects, need to ask three questions:

  1. How do you make norms?
  2. How to unify the team’s specifications?
  3. How are specifications tested?

Develop and unify specifications

Arbitrary naming of variables like the one above was common in early front-end projects.

Because of the scale of the early project and the limited size of the team, there is no awareness of naming norms, so it seems that there is no big problem with naming arbitrarily, as long as there is no repetition. However, with the increasing scale and complexity of front-end projects, there are more and more problems caused by irregularities, and the awareness of standardization is gradually taken seriously.

Through the development of the community, it has been agreed that naming includes the following specifications:

  • Underline naming:user_name
  • Underlined name:user-name
  • Small hump naming:userName
  • Big hump naming:UserName

With these specifications in place, developers have a name in mind. These specifications are now accepted by most developers, and if you don’t follow them, you’re at risk of being teased by your colleagues.

As specifications become common, people use different specifications to their own preferences, gradually forming their own coding habits. On a team, developers often have their own coding habits.

However, this becomes a problem again. Another variable example: some people on a team used to name variables with underscores, such as user_name. Some people use hump to name variables, such as userName. Both naming methods are correct and conform to the specification, but can lead to confusion and inconsistency in the team’s code style.

So why unification?

The benefits of unification are many. For example, we have a uniform rule: name variables with underscores, naming methods with small humps. So when you’re working with a team, you know it’s a variable when you see the underline, you know it’s a method when you see the little hump. Ten people’s code is written out of one person’s style, do not need to understand other coding styles, to achieve barrier-free collaboration.

Ten people’s code to write one person’s style is ideal, but it is almost impossible to achieve by supervision and self-awareness.

What to do? Here are the highlights of this article: Three magic tricks for implementing code specifications.

ESLint

As mentioned above, team development projects will produce a variety of code due to the different coding habits of each person. Such code is messy and difficult to maintain.

So what we wanted was a tool that would create a fairly comprehensive set of specifications, that would warn or even report errors if people didn’t conform to the specifications, and that would force team members to follow the same code style.

There is a tool, we’ve all heard of it, known as ESLint

ESLint has two capabilities:

  • Check for code quality, such as defined but unused variables.
  • Check code style, line breaks, quotes, indentation, etc.

These capabilities cover almost all code specifications, and specifications are configurable so that teams can customize their preferred code style.

After you customize the specification, ESLint will automatically check if the code conforms to the specification when the project is running or hot updated.

Q: What’s the difference between ESLint checking and TypeScript checking?

TypeScript only checks for type errors, while ESLint checks for style errors.

Try ESLint

First install under the project:

$ npm install eslint --save-dev
Copy the code

Then run the command eslint –init to initialize the configuration

Eslint is an interactive command that toggles up and down to select options appropriate to the project; The.eslintrc.json file is generated when completed.

The basic configuration

The basic configuration of.eslintrc.json is as follows:

{
  "env": {
    "browser": true."es2021": true,},"extends": [
    "eslint:recommended"]."parserOptions": {
    "ecmaVersion": 12."sourceType": "module",},"rules": {}};Copy the code

This base configuration contains a set of default recommended configurations, defined in the extension ESLint :recommended.

The React configuration

If your front-end framework is React and you want to define the ESLint specification, then add the following configuration marked with a + sign to the base configuration:

{
  "env": {
    "browser": true."es2021": true
  },
  "extends": [
    "eslint:recommended",
+   "plugin:react/recommended"]."parserOptions": {+"ecmaFeatures": {+"jsx": true+},"ecmaVersion": 12."sourceType": "module"
  },
+ "plugins": [+"react"+],"rules": {}};Copy the code

Configure React + TS

To support TS with React, you need to add some additional configuration:

{
  "env": {
    "browser": true."es2021": true
  },
  "extends": [
    "eslint:recommended"."plugin:react/recommended"
+   "plugin:@typescript-eslint/recommended"
  ],
+ "parser": "@typescript-eslint/parser"."parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 12."sourceType": "module"
  },
  "plugins": [
    "react",
+   "@typescript-eslint"]."rules": {}};Copy the code

Code review

With the specification defined above, let’s now write a piece of code and perform the specification check.

Create a new index.js file and write:

const a = '13'
function add() {
  return '1'
}
Copy the code

From a JS perspective, these two lines of code are fine. Then we run the check command:

$ npx eslint index.js
Copy the code

You will see an error on the console:

2:7   error  'a' is assigned a value but never used  no-unused-vars
4:10  error  'add' is defined but never used         no-unused-vars

2 problems (2 errors, 0 warnings)
Copy the code

The error means that the variable A and function add are declared but not used, indicating that the code does not conform to the conventions. This exception is also common and is executed when NPM run dev and NPM start are used in scaffold-built projects.

ESLint specification

As mentioned above, ESLint can custom check specifications defined under the rules object in the.eslintrc.json configuration file.

For example, to define the specification, strings must use double quotes:

{
  "rules": {
    "quotes": ["error"."double"]}}Copy the code

Once defined, ESLint will report an error if your code uses single quotes on strings.

Quotes stands for quote specifications, one of many, and its value is an array.

The first entry of the array is the error level, which is one of three values:

  • "off" or 0– Off specification
  • "warn" or 1– Warning level specification
  • "error" or 2– Error level specification

The second entry in the array is the actual specification. See here for the full specification

Open the page above, the green check indicates that it is configured. If you need to customize it, just write it in rules.

Prettier Prettier

In the previous step we used ESLint to implement specification writing and checking. When a developer finishes saving a piece of code, the project automatically executes an ESLint check command to check the code, check for exceptions, and output the console until the developer fixes the exception before continuing development.

If you have a complex and strict coding specification, for example, strings must be single quotes, code must end with a semicolon, and newlines must be two tabs and no Spaces. With a specification as small as this, you’re going to have a lot of inconsistencies in your development process, and you’re going to have a lot of errors in the console, and you’re going to have to fix a space or a punctuation mark, and it’s going to get annoying over time.

Because of this, ESLint is turned on by default in scaffold-generated projects, but many people find it annoying and inefficient after using it, so they turn it off manually.

So, is there a more efficient way for people to write fully compliant code very quickly?

Prettier yes, Prettier is the second trick

Prettier is the most popular code formatting tool for formatting code.

What is formatting? Above we used ESLint to customize the coding specification so that when we detect nonconforming code, an exception will be raised and we developers will need to manually fix the nonconforming code as prompted.

And the power of formatting, is not standard code, according to the specification of one button automatic repair.

That sounds exciting. Let’s give it a try.

First install under the project:

$ npm install prettier --save-dev
Copy the code

Then create a.prettierrc.json file:

{
  "singleQuote": true."semi": true
}
Copy the code

This configuration file works the same way as the rules configuration under ESLint, where code specifications are defined — yes, Prettier also supports defining specifications and then formatting code according to the specifications.

Listing the common conventions for Prettier:

{
  "singleQuote": true.// Whether to use single quotation marks
  "semi": false.// Declaration ends with a semicolon (default true)
  "printWidth": 100.// The number of characters in a line, more than will be wrapped (default 80)
  "tabWidth": 2.// How many Spaces per TAB (default: 2)
  "useTabs": true.// Whether to indent with TAB (default false)
  "trailingComma": "all".// Use trailing commas for multiple lines (default none)
  "bracketSpacing": true.// Use Spaces between braces for object literals (default true)
  "jsxBracketSameLine": false.// In multi-line JSX, the > is placed at the end of the last line instead of starting on another line (default false)
  "arrowParens": "avoid" // Avoid parentheses for arrow functions with only one argument (default: avoid)
}
Copy the code

After defining the configuration, we write something to the index.js file:

const a = "13"
function add() {
  return "1"
}
Copy the code

Then run the formatting command on the terminal:

$ npx prettier --write index.js
Copy the code

After formatting, the index.js file looks like this:

const a = '13';
function add() {
  return '1';
}
Copy the code

As you can see, double quotes are automatically changed to single quotes, and semicolons are added to the end of lines, just as defined in the configuration file.

Xi Big pu Ben! Finally, no more manual fixing of non-standard code, just a command!

Above is to format a file, of course, also support batch format files. Batch formatting uses fuzzy matching to search for files. It is commonly used. You are advised to define it in the script script as follows:

// package.json
"scripts": {
  "format": "prettier --write \"src/**/*.js\" \"src/**/*.ts\"",}Copy the code

Prettier also supports different code specifications for files with different suffixes, as follows:

{
  "semi": false."overrides": [{"files": "*.test.js"."options": {
        "semi": true}}, {"files": ["*.json"]."options": {
        "parser": "json-stringify"}}}]Copy the code

Q: How is ESLint different from Prettier?

Similarities: Both can define a code specification.

Differences: ESLint will check for non-standard code with errors; Prettier formats code directly according to the specification.

So ESLint and Prettier have the same specifications, not conflicting ones.

VSCode

ESLint and Prettier make it easy to standardize code, inspect code, and format code according to a single command while ESLint and Prettier make it easy to unify team code styles.

However, the challenge of breaking through efficiency knows no limits. It’s easy, but it’s not elegant to check your code and format your code depending on the check command.

Okay, not elegant, but is there an elegant solution?

The answer is yes. This is our third magic trick, VSCode

Powerful plug-ins

VSCode is no stranger to our front-end, a development weapon we use every day. Currently VSCode almost unified front-end circle editor, powerful, highly praised.

Since it can be so widely recognized, it must have its advantages. In addition to its light weight and fast startup speed, VSCode is most powerful is its rich variety of plug-ins to meet the various needs of users.

Of all the plug-ins, ESLint is one of the most powerful. Yes, ESLint is a plugin with the same name that VSCode supports. Screenshot below:

After installing this plugin, exceptions that previously required running the esLint command on the terminal to check for are now marked directly in your code!

Even if you make a typo, the plugin will track your mistake in real time and give you a sign and an exception. This is a huge improvement in development efficiency, no more having to run commands to check the code and see who says it’s not elegant.

Where does the ESLint plugin exist, where does the Prettier plugin also exist? Prettier-code Formatter prettier-code Formatter prettier-code Formatter prettier-code Formatter prettier-code Formatter prettier-code Formatter prettier-code Formatter

The Prettier plug-in is installed as a formatter for the editor. Right-click formatting in the code and select Prettier to format the current code.

If Prettier is to be automated, it needs to be configured in an editor.

Editor configuration

VSCode has a user setting.json file that holds the user’s custom configuration of the editor.

This configuration is very rich, see the website. Prettier is the default formatter in this configuration:

{
  "editor.defaultFormatter": "esbenp.prettier-vscode"."[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"}}Copy the code

With this step in place, here’s the thing! Let’s configure automatic formatting of save files:

{
  "editor.formatOnSave": true
}
Copy the code

Once it’s done, something magical happens: when you finish writing the code and save it, the file you’re editing is instantly formatted. That is, whether your code is written according to the specification or not, it will automatically format it for you when you save it.

In this step, the formatting command is automatically executed when the file is saved. Because Prettier was the default formatter, we joined formatting while saving to the Prettier command.

At this point, with the help of the three magic techniques, we have implemented automatic checking and automatic formatting of the code. Now you do not need to worry about formatting when coding, as long as the normal save, the editor will automatically do these things for you.

Share editor configuration

Above we go through a configuration in the editor, and finally achieve automatic formatting. Now we need to synchronize these Settings to the rest of the team. What do we do?

Don’t panic. Don’t go to so much trouble. VSCode’s Settings fall into two categories:

  • User Settings: Applies to the entire editor
  • Workspace Settings: Applies to the current directory/workspace

The two types of configuration are exactly the same; the difference is just a matter of priority. If the project directory you open contains workspace Settings, the workspace Settings will override the current user Settings.

So to synchronize the Settings to the rest of the team, we don’t need to change the user Settings, just create a workspace setting in the project directory.

How to add workspace Settings: Create a.vscode/setting.json file in the root directory of the project, and write the unified editor configuration here. So let’s put the Prettier configuration here and share it.

Appendix: Naming and project structure specifications

With the introduction of code specification, code inspection, and code formatting, the uniform code style is pretty comprehensive.

During the team development process, we also accumulated some specifications that were not written in the configuration file, which were also very important within a team. This part can be regarded as our team specification sharing.

There are two parts: naming specification and project structure specification.

Naming conventions

Naming conventions, as mentioned at the beginning of this article, there are four naming conventions for variables. But we also have agreements on which specifications to use where.

  • Variable name: underscoreuser_id
  • Css-class name: hyphenuser-id
  • Method function name: small humpuserId
  • Js-class naming: big humpUserId
  • Folder name: underlineuser-id
  • Names of components in the folder are underlineduser-id
  • Component export name: Big humpUserId

Project structure specification

The project structure specification mainly refers to the structure organization under the SRC folder.

|-- src
    |-- index.tsx # import file
    |-- assets Static resource directory
    |-- components Public component directory
    |   |-- header
    |   |   |-- index.tsx
    |   |   |-- index.less
    |-- stores State management directory, corresponding to the Pages structure
    |   |-- admins
    |   |   |-- index.tsx # status file
    |   |   |-- types.ts  Define the state type
    |   |-- index.tsx
    |-- pages # page directory, corresponding to stores structure
    |   |-- admins
    |   |   |-- index.tsx
    |   |   |-- index.less
    |-- request
    |   |-- index.ts # axios instance, global request processing
    |-- router
    |   |-- home.tsx
    |   |-- index.tsx
    |   |-- root.tsx
    |-- styles # global style
    |   |-- common.less
    |   |-- index.less
    |-- utils # Tools directory
        |-- index.ts
Copy the code

Past wonderful

This column is a long-term output of front-end engineering and architecture articles, which have been published as follows:

  • How good are you at git as a front-end architect?
  • Pure Git implements front-end CI/CD

If you like my post, please give me a thumbs up! Please follow my column and thank you 🙏🙏