概述
为了统一代码风格,制定代码规范是必备的手段,但是如何有效的执行规范,如何检测编写代码是否符合规范,如何修复提示不符合规范要求的代码。这就需要一套自动检测与修复工具。结合当前前端生态,我们采用 ESLint + Prettier + Commitlint + Husky 结合的方法,确保本地和仓库代码的规范化。
ESLint
ESLint可帮助你查找和修复 JavaScript 代码中的问题。 无论你是在浏览器中还是在服务器上编写 JavaScript,无论是否使用框架,ESLint 都可以帮助你的代码发挥最大的作用。
-
发现问题
ESLint 静态地分析你的代码以快速发现问题。 ESLint 内置于大多数文本编辑器中,你也可以在持续集成管道中运行 ESLint。
-
自动修复问题
ESLint 发现的许多问题都可以自动修复。 ESLint 修复是语法感知的,因此你不会遇到传统查找和替换算法引入的错误。
-
配置一切
预处理代码,使用自定义解析器,并编写与 ESLint 的内置规则一起工作的你自己的规则。 自定义 ESLint 以完全按照项目所需的方式工作。
安装
项目依赖安装
kotlin
npm init @eslint/config@latest
根据终端提示选择具体的信息,最后生成一个eslint.config.mjs
文件,文件内容大致如下(不同的选择会生成不同的配置信息):
javascript
import globals from 'globals';
import pluginJs from '@eslint/js';
import tseslint from 'typescript-eslint';
import pluginReactConfig from 'eslint-plugin-react/configs/recommended.js';
import { fixupConfigRules } from '@eslint/compat';
export default [
{files: ['**/*.js'], languageOptions: {sourceType: 'commonjs'}},
{languageOptions: { globals: globals.browser }},
pluginJs.configs.recommended,
...tseslint.configs.recommended,
...fixupConfigRules(pluginReactConfig),
// 自定义规则
// {
// rules: {
// quotes: ['error', 'single'],
// }
// }
];
配置
配置规则的严重性有以下三种:
- "off" 或 0 - 关闭规则
- "warn" 或 1 - 打开规则作为警告(不影响退出代码)
- "error" 或 2 - 打开规则作为错误(触发时退出代码为 1)
规则通常设置为 "error",以在持 Sequelize 成测试、预提交检查和拉取请求合并期间强制遵守规则,因为这样做会导致 ESLint 以非零退出代码退出。
以下是一则配置示例:
javascript
{
rules: {
// 使用单引号
quotes: ['error', 'single'],
}
}
附:规则参考
第三方规则集
如官方自动生成的模板中继承的 recommended
,他是官方提供的规则集,我们也可以其他自定义规则集。 如果有部分不想采用以上 recommended
规则,我们只需要在下方 rules 中覆盖即可。如:
javascript
rules: {
'no-extra-semi': ['off'],
}
命令添加
package.json 新增lint命令
json
"scripts": {
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
},
vscode ESLint插件
以上过程将ESLint配置集成到项目中,可使用 eslint 命令对代码进行检测,但是对于我们开发过程中不能及时提示。因此我们需要下载 vscode ESLint 插件,实时提示代码存在的规范问题。
补充
9.0 版本以下,在项目根目录新建 .eslintrc.cjs
文件,并写入以下基础配置:
javascript
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
// 'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: [/*'react-refresh'*/],
rules: {
//'react-refresh/only-export-components': [
// 'warn',
// { allowConstantExport: true },
//]
},
}
v9.x 版本配置文件不兼容低版本 .eslintrc.*
文件
ESLint couldn't find an eslint.config.(js|mjs|cjs) file. From ESLint v9.0.0, the default configuration file is now eslint.config.js.
Prettier
Prettier 是一个代码格式化工具。可支持以下类型文件:
- JavaScript (including experimental features)
- JSX
- Angular
- Vue
- Flow
- TypeScript
- CSS, Less, and SCSS
- HTML
- Ember/Handlebars
- JSON
- GraphQL
- Markdown, including GFM and MDX v1
- YAML
它通过解析代码再根据配置规则,重新生成代码,从而实现代码风格的统一。
安装
shell
npm install --save-dev --save-exact prettier
配置
新建 .prettierrc
文件
javascript
module.exports = {
printWidth: 80,
tabWidth: 2,
useTabs: false,
semi: false,
singleQuote: true,
quoteProps: 'as-needed',
trailingComma: 'all',
bracketSpacing: true,
jsxBracketSameLine: false,
arrowParens: 'always',
rangeStart: 0,
rangeEnd: Infinity,
requirePragma: false,
insertPragma: false,
proseWrap: 'preserve',
htmlWhitespaceSensitivity: 'css',
endOfLine: 'auto',
}
注意: prettier 中semi 规则和eslint中 no-extra-semi 稍微有点区别,prettier 配置 semi: false 和 no-extra-semi: ['error'] 表现如下:
typescript
const a = {}
// prettier.semi: false
if (a) {
;(a as any).toString()
}
// no-extra-semi: ['error']
if (a) {
(a as any).toString()
}
对于语句末尾 ;
问题,配置结果有如下两种:
- 不在语句结尾添加分号
javascript
// .prettierrc
prettier.semi: false
// eslint.config.cjs
no-extra-semi: ['off']
格式化结果如下
typescript
const a = {}
if (a) {
;(a as unknown as string).toString()
}
- 在语句结尾添加分号
javascript
// .prettierrc
prettier.semi: true
// eslint.config.cjs
格式化结果如下:
typescript
const a = {};
if (a) {
(a as unknown as string).toString();
}
忽略文件配置: 选择是否新建 .prettierignore
文件,如果不创建则使用 .gitignore
规则。
注:vscode可查看当前实际生效配置,在终端 > 输出 > prettier
vscode Prettier插件
安装Prettier作为文件格式化工具,建议设置文件保存自动格式化 "editor.formatOnSave": true,
,可保证git
提交代码已格式化,。 为了统一配置,需要将以上设置配置到当前工作区,并将 .vscode
忽略信息从 .gitignore
文件中移除。
ESLint 和 prettier 的区别
ESLint和Prettier是两个不同的工具,它们各自有不同的侧重点和功能。包括以下区别:
- ESLint:主要是一个代码质量检查工具,用于检测JavaScript代码中的错误和潜在问题,例如未使用的变量、未定义的引用、不必要的括号等。它还可以检测代码风格问题,但主要集中在语法和逻辑错误上。ESLint具有高度的可配置性,允许用户根据项目需求定义自己的规则。
- Prettier:主要是一个代码格式化工具,用于统一代码风格,确保代码的可读性和一致性。它专注于格式化,如代码缩进、单引号与双引号的使用等。Prettier支持多种语言,包括JavaScript等,并且可以与其他工具集成,以在代码提交前自动格式化代码。
在实际开发中,通常将ESLint和Prettier一起使用,以实现代码质量和风格的双重检查。为了防止两者之间的冲突,可能需要调整它们的配置,确保它们在代码格式和规则上保持一致。
如上所述,ESLint 和 Prettier 侧重点不一样,结合使用可实现功能互补。
commitlint
Commitlint 是一个用于规范化提交信息的工具,它可以帮助团队保持一致的提交信息风格,从而提高代码可读性和维护性。通过 commitlint,可以定义一些规则来检查提交信息是否符合指定的格式和风格要求。
安装依赖
shell
npm install --save-dev @commitlint/config-conventional @commitlint/cli
配置
在项目根目录创建配置文件,@commitlint/cli
会从以下文件中读取配置:
- .commitlintrc
- .commitlintrc.json
- .commitlintrc.yaml
- .commitlintrc.yml
- .commitlintrc.js
- .commitlintrc.cjs
- .commitlintrc.mjs
- .commitlintrc.ts
- .commitlintrc.cts
- commitlint.config.js
- commitlint.config.cjs
- commitlint.config.mjs
- commitlint.config.ts
- commitlint.config.cts 我们选择创建
.commitlintrc.cjs
,写入配置
javascript
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'build', // 编译相关修改(新版本发布)
'feat', // 新功能
'fix', // 修复bug
'update', // 更新某功能
'refactor', // 重构
'docs', // 文档
'chore', // 增加依赖或库
'style', // 格式(不影响代码变动)
'revert', // 撤销commit 回滚上一版本
'perf', // 性能优化
'test', // 单测
'ci', // cicd
],
],
'scope-case': [
2,
'always',
[
'lower-case', // default
// 'upper-case', // UPPERCASE
// 'camel-case', // camelCase
// 'kebab-case', // kebab-case
// 'pascal-case', // PascalCase
// 'sentence-case', // Sentence case
// 'snake-case', // snake_case
// 'start-case', // Start Case
],
],
},
plugins: [
{
rules: {
'commit-rule': ({ raw }) => {
return [
/^\[(build|feat|fix|update|refactor|docs|chore|style|revert|perf|test|ci)].+/g.test(raw),
`commit备注信息格式错误,格式为 <[type] 修改内容>,type支持${types.join(',')}`,
]
},
},
},
],
}
以上配置完成后,一般结合 git-hooks
一起使用,具体步骤见 [commitlint hooks](#commitlint hooks "#commitlint-hook")
husky
Husky 是一个用于在 Git hooks 中运行脚本的工具,它可以帮助开发者在提交代码之前执行一些自定义的代码检查或测试来确保代码的质量。
安装
css
npm install --save-dev husky
初始化husky
csharp
npx husky init
lint hooks
安装依赖
css
npm install --save-dev lint-staged
package.json 配置新增
json
"lint-staged": {
"*.{vue,js,ts,tsx,jsx}": [
"eslint --fix",
"prettier --write --ignore-unknown"
]
}
在 .husky/
目录下新建 pre-commit
文件,写入以下内容
shell
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged --no-stash
commitlint hooks
在 .husky/
目录下新建 commit-msg
文件,写入以下内容
shell
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no -- commitlint --edit $1
注:不建议使用官方文档的 echo 命令,出入内容windows和linux系统不一致。
验证
- 验证
eslint
异常,编写以下代码
javascript
const unusedVar = ''
提交,输出以下异常
log
✖ eslint --fix:
D:\workplace\xxx\test.tsx
1:7 error 'unusedVar' is assigned a value but never used @typescript-eslint/no-unused-vars
✖ 1 problem (1 error, 0 warnings)
husky - pre-commit script failed (code 1)
- 验证
git msg
异常 修改仓库代码,提交faet: git test
log
⧗ input: faet: git test
✖ type must be one of [build, feat, fix, update, refactor, docs, chore, style, revert, perf, test, ci] [type-enum]
✖ found 1 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
husky - commit-msg script failed (code 1)
将 commit 信息修改为 feat: git test
,提交成功。
总结
保证代码格式的统一是多人开发必备的工作。代码风格的统一有助于其他成员的快速接入,eslint的规则校验可减少代码潜在的问题,git信息的规范可大概了解本次提交内容。