前言
团队开发的成员越来越多,项目都是由多个人进行开发和维护,每个人的代码书写习惯和风格又不尽相同,commit 的提交log 也是乱七八糟,为以后的开发和维护增添了很多困难,所以规范和约束在多人协作下,就显得尤为重要。
工具说明
ESLint
-
目的:ESLint 主要用于发现代码中的问题,如潜在的错误、不一致的编码风格、未使用的变量等。
-
可配置性:ESLint 允许自定义规则,使其可以强制实施特定的编码标准和最佳实践。
Prettier
-
目的:Prettier 主要用于自动格式化代码,以保持代码风格的一致性。
-
风格规则:Prettier 有一套默认的风格规则,例如缩进、行宽、引号等,并且这些规则不太可配置。
commitlint
- 目的:检查提交消息是否符合常规提交格式,用于在每次提交时生成符合规范的commit消息。
lint-staged
- 目的:用于在 Git 提交时仅对暂存的文件(即将要提交的文件)运行指定的 linting 或格式化任务。它与
husky
配合使用,可以实现更高效的代码检查和格式化。
husky
-
代码质量检查:在提交代码之前自动运行 lint、测试等,确保代码符合质量标准。
-
格式化代码:可以在提交时自动格式化代码,以保持代码风格一致。
-
自定义检查:允许开发者编写自定义脚本,例如检查提交信息格式,确保遵循约定式提交(Conventional Commits)。
话不多说,直接展开我们的项目规范化构建!
-
初始化eslint
pnpm install eslint -D
npx eslint --init
-
配置eslintrc.config.js
{
settings: {
react: {
version: 'detect',
},
},
},
{ languageOptions: { globals: globals.browser } },
"scripts": {
"lint": "eslint --fix \"./src/**/*.{js,jsx,ts,tsx}\""
}
注意,在vite项目中,它会初始化这个文件,eslint初始化完成后并不会出现 .esintrc 文件,而是在这个文件的languageOptions上新增内容。
OK,到这里,我们可以先来测试一下,写一行未使用的代码,执行 npm run lint格式检查下面代码。
import React from 'react';
const App = () => {const a={};return <div></div>;
};
export default App;
-
设置忽略文件 .eslintignore
dist/*
node_modules/*
*.json
public
-
配置 prettier 格式化,重启vscode
npm install prettier -D
-
在packages.json 中的 script 配置命令
"scripts": {
"format": "prettier --write \"src/**/*.+(js|ts|jsx|tsx)\"",
}
这时,运行 npm run format 会将我们项目中的文件都格式化一遍,后续如果添加其他格式的文件,可在该命令中添加,例如:.less后缀的文件。
代码结果
import React from 'react';
const App = () => {
const a = {};
return <div></div>;
};
export default App;
-
设置 .prettierignore忽略文件
node_modules/**
dist/**
public/**
doc/**
-
解决ESLint和Prettier的冲突
-
冲突通常发生在两个工具对某些代码风格规则有不同的处理方式。例如,ESLint 可能要求使用单引号,而 Prettier 默认使用双引号。
-
当这两个工具同时运行时,它们可能会对代码的同一部分提出不同的修改建议,从而造成冲突。
方法:安装依赖包
npm install eslint-config-prettier eslint-plugin-prettier -D
- eslint-config-prettier 基于 prettier 代码风格的 eslint 规则,即eslint使用pretter规则来格式化代码。
- eslint-plugin-prettier 禁用所有与格式相关的 eslint 规则,解决 prettier 与 eslint 规则冲突,确保将其放在 extends 队列最后,这样它将覆盖其他配置。
-
安装初始化husky
// 初始化husky。
// 1将prepare脚本添加到package
// 2、根目录创建.husky文件夹,包含pre-commit钩子
npm install husky -D
npx husky-init
这时,项目根目录下会出现.husky文件夹。
-
安装并配置lint-staged
npm install lint-staged -D
-
配置package.json命令
// 设置lint-staged;提交时prettier代码格式化,eslint检查修复
{
"lint-staged": {
"*.{js,ts,jsx,tsx}": [
"prettier --write",
"eslint --fix"
],
"*.{js,json,ts,tsx,css,scss,html}": [
"prettier --write"
]
},
}
-
修改.husky/pre-commit文件,使提交时能执行lint-staged钩子
注意!!! ①pre-commit文件必须在.husky下,而不是 _ 中的pre-commit。②npx lint-staged可以是npm run lint-staged,如果过程中出错,建议使用npx lint-staged
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
-
安装commit-msg
npm install @commitlint/config-conventional @commitlint/cli --save-dev
-
根目录新建 commitlint.config.js 配置文件
(这里使用的ES规范导出,但要求使用commonJS规范,也可以将文件命名为.cjs解决)
const Configuration = {
extends: ['@commitlint/config-conventional'],
rules: {
// type 类型定义
'type-enum': [
2,
'always',
[
'feat', // 新功能 feature
'fix', // 修复 bug
'docs', // 文档注释
'style', // 代码格式(不影响代码运行的变动)
'refactor', // 重构(既不增加新功能,也不是修复bug)
'perf', // 性能优化
'test', // 增加测试
'chore', // 构建过程或辅助工具的变动
'revert', // 回退
'build', // 打包
],
],
// subject 大小写不做校验
// 自动部署的BUILD ROBOT的commit信息大写,以作区别
'subject-case': [0],
},
};
export default Configuration;
commit规范参考。例子:git commit -m 'feat: 测试一下'
-
执行以下命令添加commitlint钩子
npx husky add .husky/commit-msg "npm run commitlint"
-
在package.json中配置
"scripts": {
"commitlint": "commitlint --config commitlint.config.js -e -V"
}
按上面步骤修改完,我们在提交代码时候,如果随便写一个提交message将会报错,不允许提交。
代码格式如下
import React from 'react';
const App = () => {const a = {};return <div></div>;
};
export default App;
代码结果
import React from 'react';
const App = () => {
const a = {};
return <div></div>;
};
export default App;
而且,如果我们没有把需要规范的地方解决,即便我们按照正确的提交规范,也不会通过。
自定义代码提交规则
自定义提交规则可以根据团队开发规范来进行额外配置,假设提交规则为:把每个需求的产品文档链接关联到每一个feature,这样后续要是有问题,也方便找到对应的产品文档。
配置如下commitlint.config.js
主要就增加了plugin 和 三个rule 规则
const Configuration = {
extends: ['@commitlint/config-conventional'],
rules: {
// type 类型定义
'type-enum': [
2,
'always',
[
'feat', // 新功能、新特性feature
'fix', // 修复 bug
'docs', // 文档修改
'style', // 代码格式(不影响代码运行的变动)
'refactor', // 代码重构
'perf', // 优化相关,比如提升性能、体验
'test', // 测试用例修改
'chore', // 其他修改, 比如改变构建流程、或者增加依赖库、工具等
'revert', // 回滚上一个版本
'build', // 编译相关的修改,例如发布版本、对项目构建或者依赖的改动
],
],
// subject 大小写不做校验
// 自动部署的BUILD ROBOT的commit信息大写,以作区别
'subject-case': [0],
'must-add-document-url': [2, 'always'], // 加入自定义规则
'body-max-line-length': [2, 'always', 200], // body最大内容行数
'header-max-length': [2, 'always', 200], // header 最大长度
},
plugins: [
{
rules: {
'must-add-document-url': ({ type, body }) => {
const ALIYUN_DOCUMENT_PREFIX = 'https://devops.aliyun.com';
// 排除的类型
const excludeTypes = ['chore', 'refactor', 'style', 'test'];
if (excludeTypes.includes(type)) {
return [true];
}
return [body && body.includes(ALIYUN_DOCUMENT_PREFIX), `提交的内容中必须包含云效相关文档地址`];
},
},
},
],
};
export default Configuration;
测试一下
到这里,我们的规范化已经配置完成了!其中有一些需要注意的点,比如package.json中的脚本:"format": "prettier --write \"src/**/*.+(js|ts|jsx|tsx)\"",当时我配置的时候使用了" ' ' " 双引号套单引号的写法,执行就检测不到!