25
头图

foreword

An old project of the company did not do the verification before code submission. After I got it, I didn’t have time to help it because of the old project. Anyway, I just changed a little bit; try to follow its code style and write it. Just submit;

Until one day, another person joined in. Good guy, just did something wrong.
Many files were submitted together, and then the commit-msg was not standardized, the code indentation was not standardized, the line breaks were inconsistent, there were still a lot of useless code, and the readability was extremely poor;

When you fetch the code one day, you find that many files are like this 👆 Are you very crashed?
But the problem has to be solved in the end; the best way to treat sewage is to start remediation from the place where sewage can be generated. Let me add it to it. 🥰

Next, I will take you all to complete the simplest code specification verification through husky + eslint , then gradually optimize it, and finally achieve a strong limit through husky + eslint + lint-stage + commitlint + prettier . Finally, cooperate with commitizen and implement custom submission templates and restriction rules through commitlint-config-cz + cz-customizable to achieve the team's final project submission restriction protocol.

eslint+prettier

Here I have adapted a set of eslit rules for this project, and the code submitted according to this set of rules will not conflict.
Everyone should have used eslint and prettier in their usual projects, and they should be familiar with them, so I won't take up space here. (If you want to see it, you can privately chat with me, and I can make a separate article on the theme of eslint and prettier)

🦄 In this article, I mainly explain how to verify, repair, and limit irregular submissions before git commits code changes when the team works together.

husky

The first thing I want to introduce is husky . We will definitely need husky for engineering. It can easily help us stop the attacks of the cuties. No, it is to add git hooks to our project.

specific method

First we install husky into the development dependencies

npm i husky -D
# or
yarn add husky -D

Notice

At present, the version I installed is husky@7.0.4 . Since husky@6.0.0 was made after breaking change , the method of setting hooks before the 6.0.0 version is no longer applicable. Here we only introduce the latest method .

After installation, we need to create a .husky directory in the current project and specify the directory as the directory where git hooks is located.

Use the following command to quickly create 👇

#--no-install 参数表示强制npx使用项目中node_modules目录下的husky依赖包
npx --no-install husky install

In order to allow others to automatically create the .husky directory after installing dependencies in this project and specify the directory as the directory where git hooks is located, we need to add a script package.json "prepare": "husky install"

Use the following command to quickly add 👇

npm set-script prepare "husky install"
prepare script will be automatically executed after npm i or other yarn or yarn add . That is to say, when we install the dependencies, the husky install command will be automatically executed, thereby automatically creating the .husky directory and specifying the directory as the directory where git hooks is located.

Use the following command to quickly create 👇

npx --no-instal husky add .husky/pre-commit "npm run [你要执行的命令]"

After completion, you can see that a pre-commit file has been added to the .husky directory, the content of which is 👇

Here I use npm run lint , so that we can cooperate with Eslint's code verification to limit the submission of irregular code


It can be seen that the code that does not meet the Eslint verification rules cannot be submitted;

Of course, the error reporting problem here is only caused by non-standard indentation. Similar problems include quotation marks, semicolons at the end of sentences, newlines, etc... All can be automatically repaired through the parameter eslint of --fix , so that you can Before submitting, commit the simple code style issues that can be automatically fixed. Complicated situations still have to be handled manually.

Speaking of newlines, here is what we need to understand: On Windows the default is Carriage Return Line Feed (CRLF), however, on Linux/MacOS it is Line Feed (LF).

We can try to execute lf after formatting the file with the newline character crlf as the newline character git add . .

You can see that the final LF line break is still converted by CRLF;

If you don't collaborate across platforms (both on Mac/Linux, or both on Windows), just pass git config core.autocrlf false in your current project to stop this from happening.

To be on the safe side, you need to create a new .gitattributes file (mainly used to define the attributes of each file, so that git can help us manage it uniformly.), set eol (end of line) to the specified newline (lf/crlf), here I set the newline character of all files *.* to LF, and marked some non-text files (excluding them), you can also set the corresponding properties for each file type => *.js eol=lf , *.ts eol=lf ...

*.* eol=lf
*.jpg -text
*.png -text
  ...
# 或者👇

*.js eol=lf
*.ts eol=lf
*.json eol=lf
  ...

The content of the file is as follows👇

image.png
In this way, no matter what platform we develop on, the file newlines are unified as LF.

You can see that after using the .gitattributes configuration file and executing git add , all files that do not specify a newline character will be automatically replaced with the newline character you specified. For example, if I specify lf here, then after git add . , files that are not newline with lf will be converted to lf , and output warning: CRLF will be replaced by LF in xxxx/filename in the terminal, as shown in the figure👇

.gitattributes has many uses, you can check 👉 gitattributes for details.

🥰 At this point, one of the simplest code style restrictions has been implemented.

Since it is done, it must be a complete set, and it is easy to use. Let's continue to improve other functions~


lint-staged

What is lint-staged ? As the name suggests, this tool is only used to check the git staging area file, which is a tool to run lint in the staging area file after your git add file1,2,3... .

It is unnecessary to lint all the files every time you submit one or two files. We only lint the code that needs to be submitted, which can reduce a lot of unnecessary time overhead. (If you have to go to all files of lint every time you modify a file, this tool is meaningless to you, husky is enough 🤐)

Instructions

We changed the code written before in .husky/pre-commit to👇

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
- npm run lint
+ npx --no-install lint-staged

Then add the following code to package.json, the lint-staged object is configured in the form of key-value pairs, the key name is the single file or a file type you want to process, and multiple types can be written in {} , separated by commas; The value is an array of commands to execute when lint is in the array.

{
  "lint-staged": {
    "*.{ts,js,vue}": ["eslint", "echo '没问题!'"]
  }
}

After adding and playing the above code, we passed the test and changed the indentation of the two files to those that do not conform to the specification, and then temporarily stored one of the files. After running git commit , we found that only one file's lint error was reported in the terminal's error report. message, the error of the other file did not appear.

When all the code in the staging area conforms to the specification👇, the submission will be executed through verification.

✔ Preparing lint-staged...
✔ Hiding unstaged changes to partially staged files...
✔ Running tasks for staged files...
✔ Restoring unstaged changes to partially staged files...
✔ Cleaning up temporary files...

commitizen

Commitizen is a tool for writing Commit Message standards above. It can realize the Commit Message of interactive writing specification.

If only used in this warehouse👇

npm install commitizen -D

If you want to use commitizen globally to help you commit

npm install commitizen -g

After the installation is complete, we generally use the submission specification that conforms to Angular's Commit message format (of course, it can also be customized, which will be discussed later), and run the following command to generate a Commit message that conforms to the Angular submission specification format.

If your project is using npm 👇

# 如果你项目用的是npm
npx --no-install commitizen init cz-conventional-changelog --save-dev --save-exact

If your project is using yarn 👇

# 如果你项目用的是yarn
npx --no-install commitizen init cz-conventional-changelog --save-dev --save-exact

After running the above command, it will install the cz-conventional-changelog adapter module for your project, add the key of config.commitizen to the root of the file and add it to package.json

It can be seen in package.json , the following content is automatically added👇

{
  ...
  "config": {
    "commitizen": {
      "path": "./node_modules/cz-conventional-changelog"
    }
  }
  ...
}

After completion, pass the command yarn cz , if you installed commitizen , then you can directly git cz , you can write the commit message interactively through the following and submit

limit commitlint

Since commitizen is not mandatory, it can still be submitted through git commit , so we must check the commit messag once before submitting through cz or git commit . Commit is not allowed if it does not meet the specification.

First we need to install commitlint , commitlint/config-conventional

yarn add @commitlint/cli @commitlint/config-conventional -D

Use the following command to quickly create a commit-msg hook for git hooks👇
In this way, the commit message will be checked by commitlint every time a commit is made.

npx --no-instal husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

Then we create a commitlint configuration file to the project root directory👇

echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js

The above will generate commitlint.config.js in the project directory, the code is as follows, it will inherit the Commit message specification in @commitlint/config-conventional . ("feat", "fix", "perf", "refactor"...)

module.exports = {
  extends: ["@commitlint/config-conventional"],
};

Then we test in the terminal

echo 'feat: bar' | npx --no-install commitlint

If the above error occurs after you execute the above line command.

It can be solved by changing the format of the file to ask UTF-8; this problem has been in 👉 Issues , and many people have encountered it (me too 😂).
The easiest way is to open the file with Notepad, select Save As, and then change the character encoding to UTF-8 in the lower right corner of the pop-up window (when Windows users run echo "xxx" > xx.js , the file encoding may be UTF-16 LE), change it well After that, just replace the original commitlint.config.js file.

After solving the above problems, let's test it again. We can see that the commit-msg that does not conform to the specification will cause an error to be reported, and the commit will not be able to be committed, indicating that our commitlint has taken effect~ 👏👏👏

At this point, the verification of commit-msg has also been completed✔

If you want to customize the interactive text of commitlint (no feat, fix..., many people like to add an emoji in front of the commit message), of course you can.

We need to install cz-customizable to implement custom commit message rules, and install the corresponding commitlint-config-cz to support verification (read rules directly from custom files)

Run the following command👇

yarn add commitlint-config-cz  cz-customizable -D

In the project root directory, create a .cz-config.js file and copy the contents of cz-config-EXAMPLE.js into it. Then change it to whatever rules you want.

Of course, you can also use what I wrote:

module.exports = {
  types: [
    { value: "feat", name: "feat: 一个新的特性" },
    { value: "fix", name: "fix: 修复一个Bug" },
    { value: "docs", name: "docs: 变更的只有文档" },
    { value: "style", name: "style: 代码风格,格式修复" },
    { value: "refactor", name: "refactor: 代码重构,注意和feat、fix区分开" },
    { value: "perf", name: "perf: 码优化,改善性能" },
    { value: "test", name: "test: 测试" },
    { alue: "chore", name: "chore: 变更构建流程或辅助工具" },
    { value: "revert", name: "revert: 代码回退" },
    { value: "init", name: "init: 项目初始化" },
    { value: "build", name: "build: 变更项目构建或外部依赖" },
    { value: "WIP", name: "WIP: 进行中的工作" },
  ],
  scopes: [],
  allowTicketNumber: false,
  isTicketNumberRequired: false,
  ticketNumberPrefix: "TICKET-",
  ticketNumberRegExp: "\\d{1,5}",
  // it needs to match the value for field type. Eg.: 'fix'
  /*
  scopeOverrides: {
    fix: [
      {name: 'merge'},
      {name: 'style'},
      {name: 'e2eTest'},
      {name: 'unitTest'}
    ]
  },
  */
  // override the messages, defaults are as follows
  messages: {
    type: "选择一种你的提交类型:",
    scope: "选择一个scope (可选):",
    // used if allowCustomScopes is true
    customScope: "Denote the SCOPE of this change:",
    subject: "简短说明(最多40个字):",
    body: '长说明,使用"|"换行(可选):\n',
    breaking: "非兼容性说明 (可选):\n",
    footer: "关联关闭的issue,例如:#12, #34(可选):\n",
    confirmCommit: "确定提交?",
  },
  allowCustomScopes: true,
  allowBreakingChanges: ["feat", "fix"],
  // skip any questions you want
  skipQuestions: ["scope", "body", "breaking"],
  // limit subject length
  subjectLimit: 100,
  // breaklineChar: '|', // It is supported for fields body and footer.
  // footerPrefix : 'ISSUES CLOSED:'
  // askForBreakingChangeFirst : true, // default is false
};

After creating the .cz-config.js file, we need to go back to the package.json file and change the config.commitizen.path to "node_modules/cz-customizable" . If your .cz-config.js file is in the project root directory, then you can not configure the following, commitlint-config-cz It will automatically look in the project root directory: .cz-config.js or .config/cz-config.js

...
{
  "config": {
    "commitizen": {
      "path": "node_modules/cz-customizable"
    },
    // 如果你的.cz-config.js文件在项目根目录下,那么可以不配置下面这条,commitlint-config-cz会自动在项目根目录下寻找: .cz-config.js 或 .config/cz-config.js
    "cz-customizable": {
      "config": "你的文件路径/xxxconfig.js"
    }
  }
}
...

For more advanced usage of commitlint-config-cz , see 👉 commitlint-config-cz

Finally, we will change the code in 0620e427fc988b created commitlint.config.js

module.exports = {
- extends: ["@commitlint/config-conventional"],
+ extends: ["cz"],
};

Or you can manually add custom rules in commitlint.config.js , it will override the rules in extends

module.exports = {
  extends: ["@commitlint/config-conventional","cz"],
  rules: {
    "type-enum": [
      2,
      "always",
      [
        "init",
        "build",
        "ci",
        "chore",
        "docs",
        "feat",
        "fix",
        "perf",
        "refactor",
        "revert",
        "style",
        "test",
      ],
    ],
  },
};

At this point, the verification of the custom commit message is also ok ✅

At last

Reminder: The code style and rules of the project should be formulated with the team~

So far, in the collaborative project of the team, the submissions that do not conform to the specification are strangled in the cradle. It is best for all of us to standardize whether we are writing code or submitting code~ While not causing trouble for ourselves, it will not cause trouble to others or the company. This is the whole content of this article~ If it is helpful to you, remember to like and encourage~

I am Rongding, a front-end developer for happy programming 🥰
If you also love front-end related technologies! scan the QR code~ to join the front-end superman technical exchange group🦄

Reply [add group] , will pull you into the learning exchange group, and make progress together with other front-end enthusiasts!
Reply [books] to get a lot of front-end pdf books.
The circle of friends holds book giving activities from time to time. Come on, let's go!


荣顶
570 声望2.5k 粉丝

​公​众​号​​‎​‎‌‎‌‎‌‎​: 前端超人