前言
熟话说,不以规矩,不能成方圆。良好的代码规范,不管是对于个人还是团队都非常重要。为了提供代码质量
和统一代码规范
,我选择了eslint
和prettier
搭配来使用,并且在最后提交到git仓库时用husky
搭配lint-stage
进行预检查,保证线上仓库的代码符合要求。
eslint和prettier区别
ESLint 主要解决的是代码质量问题,代码质量出问题意味着程序有潜在Bug
。比如:
- 代码质量规则 (code-quality rules)
Prettier 主要解决的是代码风格问题,风格问题充其量也只是看着不爽。比如:
- 代码风格规则 (code-formatting rules)
eslint配置
// 首先安装eslint
npm install eslint -D
// 然后生成.eslintrc.json配置文件
npx eslint init
// 配置适合自己或者整个团队的代码规则
// 配置完成之后
npx eslint [文件路径]
- parser
ESLint的默认解析器和(espree)核心规则只支持最新的最终ECMAScript标准,不支持Babel提供的实验性(如新特性)和non-standard(如流或TypeScript类型)语法,此时这里可以自定义解析器
Babel-ESLint
、@typescript-eslint/parser
。
{
"parser": "@typescript-eslint/parser"
// 先调用typescript模块,生成标准的 TypeScript AST,
// 然后再将它转换成兼容 ESLint的ESTree
// 可参考 https://www.jianshu.com/p/ade75072c70a
// 或者
"parser":"babel-eslint"
// 代码将由Babel的解析器(使用Babel配置文件中指定的配置)解析,
// 并将生成的AST转换为ESLint可以理解的ESTree兼容结构
// 可参考 https://www.5axxw.com/wiki/content/8ygnvk
}
不管是哪个解析器,最终目的都是转化成eslint兼容的ESTree
。
- parserOptions
// 解析器选项
// 指定要支持的 JavaScript 语言版本的选项
// 应该始终设置解析器选项:
// 1. 使用默认解析器的时候,ESLint 需要 parserOptions 配置属性才能使 ESLint 与 ECMAScript 5 中未包含的功能正常配合使用
// 2. 即使使用其他的解析器。解析器会被传入 parserOptions,但是不一定会使用它们来决定功能特性的开关
"parserOptions": {
// ecma版本:支持 ES6 语法,默认支持 ECMAScript 5 语法,可以选值有: 3, 5, 6, 7, 8, 9, 10, 11, 12
// 注意的是不会自动启用支持 ES6 新的全局变量
"ecmaVersion": 6,
// 源码类型:如果你的代码在 ECMAScript 模块中可以设置为 "module",默认为 "script"
// 如果不设置未 "module",那么 export、import 就会报错
"sourceType": "module",
// 以对象的形式指定您要使用哪些附加语言特性
"ecmaFeatures": {
"globalReturn": false, // 允许在 global 作用域使用 return 语句
"impliedStrict": false, // 如果 ecmaVersion 设置为 5 或者更高的时候,在 global 作用域启用严格模式。implied 是隐性的意思
"jsx": false, // 支持 JSX 语法
},
},
- env 设置编码的环境。
// 设置环境
// 设置您的脚本在哪种环境中运行。每个环境都会带来一组特定的预定义全局变量。
// 可以简单理解为批量设置全局变量,这些环境不是互斥的,因此您一次可以定义多个环境。
// 开启全部环境
"env": {
"browser": true, // 浏览器全局变量
"node": true, // Node.js 全局变量和 Node.js 作用域
"commonjs": true, // CommonJS 全局变量和 CommonJS 作用域 (启用此环境用于使用 Browserify/WebPack 的 browser-only 代码)
"es6": true, // 启用除 modules 以外的所有 ECMAScript 6 特性 (这会自动将 `ecmaVersion` 解析器选项设置为 6)
"es2017": true, // 添加所有 ECMAScript 2017 的全局变量并且自动设置 `ecmaVersion` 解析器选项设置为 8
"es2020": true, // 添加所有 ECMAScript 2020 的全局变量并且自动设置 `ecmaVersion` 解析器选项设置为 11
"es2021": true, // 添加所有 ECMAScript 2021 的全局变量并且自动设置 `ecmaVersion` 解析器选项设置为 12
"amd": true, // 根据 amd 规范定义 `require()` 和 `define()` 作为全局变量
}
- globals 设置全局变量。
// 全局变量
// 如果访问未在同一文件中定义的变量,将会出现 no-undef 警告。如果要在文件内部使用全局变量,为了让 ESLint 不会出现警告,需要进行定义。
// readonly-可读不可写 writable-可读可写
"globals": {
"WX": "readonly",
"Wang":"writable"
}
- extends 规则集,批量扩展规则。对于不同项目,如果希望使用相同的 rules,直接复制粘贴显然不是一个好方法,一是 rules 太多,配置文件会显得很乱,二是无法同步更新。
推荐使用的方法是把所需的 rules 抽离成一个 npm 包,需要的时候再通过 extends 引用。而且对于这些抽离出来的包,有着统一的命名规范。
extends 的模块名称以 eslint-config-
开头,例如eslint-config-wang
"extends": [
"eslint-config-wang", // 全称
"wang", // 简写
"eslint:recommended", // eslint官方提供的规则集
"plugin:@typescript-eslint/recommended" // typescirpt规则集
],
// 可以无限扩充,后面的规则会覆盖前面的规则
// 前提是plugin里面已经定义了这些规则,extends的作用是开启plugin定义的规则
// 形如plugin: ,会自动引入plugin,不用在plugin配置项里面再写一遍
- rules 逐条配置规则
rules:{
// 禁用 console
"no-console":0,
// 要求使用 let 或 const 而不是 var
"no-var":0,
// 优先级最高,会覆盖extends的规则,同样也是要先配置plugin,plugin定义的规则才会生效。
}
- plugin
虽然官方提供了很多规则,但是总有覆盖不到的情况。这时候可以使用
plugin
定义自己的规则。与extends
类似的命名规则,把 config 替换成 plugin 即可。例如:eslint-plugin-wang
。 引入plugin
可以理解为引入了额外的rules
,需要在rules
、extends
中定义后才会生效。
plugins: ['wang'],
// 如果在extends引入plugin:wang/recommended,plugin会被自动引入
为了不每次都执行命令来检查代码,简化开发,vscdoe
可安装eslint插件
来自动标记错误,eslint插件
可自动检测.eslintrc.json
,在编码的同时就能发现错误。
prettier配置
// 安装prettier
npm install prettier -D
创建配置文件 .prettierrc.js,下面是配置文件:
module.exports = {
// 最大长度80个字符
printWidth: 80,
// 使用单引号, 默认false(在jsx中配置无效, 默认都是双引号)
singleQuote: false,
// 行末分号, 默认true
semi: true,
// JSX双引号
jsxSingleQuote: false,
// 尽可能使用尾随逗号(包括函数参数),默认none,可选 none|es5|all
// es5 包括es5中的数组、对象
// all 包括函数对象等所有可选
trailingComma: "all",
// 在对象文字中打印括号之间的空格。 默认true
bracketSpacing: true,
// 箭头函数参数括号 默认avoid 可选 avoid| always
// avoid 能省略括号的时候就省略 例如x => x
// always 总是有括号
arrowParens: "avoid",
// 在文件顶部插入一个特殊的 @format 标记,指定文件格式需要被格式化。
insertPragma: false,
// 行尾换行格式
endOfLine: "auto",
// html空格敏感度
htmlWhitespaceSensitivity: "ignore",
// tab缩进大小,默认为2
tabWidth: 2,
// 使用tab缩进还是空格,默认false
useTabs: false,
// vue缩进脚本和样式
vueIndentScriptAndStyle: false,
// > 标签放在最后一行的末尾,而不是单独放在下一行 默认false
jsxBracketSameLine: false,
insertPragma: false,
requirePragma: false,
};
最后执行下面命令来fix
代码风格
npx prettier --write [文件路径]
为了不每次都执行命令来格式化代码,简化开发,vscode
可安装prettier插件
,保存自动根据配置文件来格式化代码,非常方便。
eslint和prettier配置冲突
eslint
和prettier
各自详细的配置这里不多说,社区里面有很多详细的配置。这里主要讲一下eslint
和prettier
搭配使用的注意点。因为eslint
在代码检查的过程中,也会对代码风格进行检查,如果prettier
的配置和eslint
的规则冲突,则会陷入死循环。解决方法如下:
npm install eslint-plugin-prettier -D
然后在.eslintrc.json
文件中配置:
"extends": ["plugin:prettier/recommended"]
即可。具体可看这里
husky
husky
是一个为 git 客户端增加 hook 的工具。在执行git命令之前我们可以自定义某些的操作,比如 pre-commit 钩子就会在你执行 git commit 的触发,我们可以在 pre-commit 中实现一些比如 lint 检查、单元测试、代码美化等操作。
- 首先安装
husky
(我装的是v7+,v7之前的与下面的配置不一样,可以自行百度)
npm install husky -D
- 然后配置运行
npx husky install
命令,执行完命令之后,会出现.husky
的目录,如下图
当执行完上面的步骤之后,在.husky
目录下是没有commit-msg
和pre-commit
两个目录的,我们要手动添加hooks
,添加完成之后,husky
会自动执行我们添加的操作。
// 添加pre-commit勾子
npx husky add .husky/pre-commit "npx lint-staged --allow-empty $1"
// 添加commit-msg勾子
npx husky add .husky/commit-msg "npx commitlint --edit $1"
lint-stage
lint-stage
一个仅仅过滤出 Git 代码暂存区文件(被 git add 的文件)的工具;这个很实用,因为我们如果对整个项目的代码做一个检查,可能耗时很长,如果是老项目,要对之前的代码做一个代码规范检查并修改的话,这可能就麻烦了,可能导致项目改动很大。所以这个 lint-staged,对团队项目和开源项目来说,是一个很好的工具,它是对个人要提交的代码的一个规范和约束。
如果对于husky和lint-stage不清楚的话可以点击后面的两个链接,里面有详细的介绍。
最后送上dogc
仓库地址