Eslint
eslint规约 Eslint 代码规范整合记录
前景准备
咨询了阿里那边的人员,得知他们的一套规范目前是开发对外的,虽然在阿里云的代码扫描的文档里面只写了 Eslint默认规则集。所以我们拿到了https://github.com/alibaba/f2e-spec 这个链接。
文档写的很清晰明了,可以自行查阅。阿里甚至还封装了 F2ELint 这个 npm 包,它收敛屏蔽了这些依赖和配置细节,提供简单的 CLI 和 Node.js API,让项目能够一键接入、一键扫描、一键修复、一键升级,并为项目配置 git commit 卡口,降低项目接入规约的成本。
实际操作
安装
在终端执行:
npm install f2elint -g
安装完成后,可执行 f2elint -h 以验证安装成功。(npm可能需要高版本)
使用
f2elint init:一键接入
在项目根目录执行 f2elint init,即可一键接入规约,为项目安装规约 Lint 所需的依赖和配置。
f2elint init
具体会做以下事情:
安装各种依赖:包括 Linter 依赖,如 ESLint、stylelint、commitlint、markdownlint 等;配置依赖,如 eslint-config-ali、stylelint-config-ali、commitlint-config-ali、markdownlint-config-ali 等写入各种配置文件,包括:
- .eslintrc.js、.eslintignore:ESLint 配置(继承 eslint-config-ali)及黑名单文件
- .stylelintrc.js、.stylelintignore:stylelint 配置(继承 stylelint-config-ali)及黑名单文件
- commitlint.config.js:commitlint 配置(继承 commitlint-config-ali)
- .markdownlint.json、.markdownlintignore:markdownlint 配置及黑名单文件
- .prettierrc.js:符合规约的 Prettier 配置
- .editorconfig:符合规约的 editorconfig
- .vscode/extensions.json:写入规约相关的 VSCode 插件推荐,包括 ESLint、stylelint、markdownlint、prettier 等
- .vscode/settings.json:写入规约相关的 VSCode 设置,设置 ESLint 和 stylelint 插件的 validate 及保存时自动运行 fix,如果选择使用 Prettier,会同时将 prettier-vscode 插件设置为各前端语言的 defaultFormatter,并配置保存时自动格式化
- f2elint.config.js:f2elint 包的一些配置,如启用的功能等 配置 git commit 卡口:使用 husky 设置代码提交卡口,在 git commit 时会运行 f2elint commit-file-scan 和 f2elint commit-msg-scan 分别对提交文件和提交信息进行规约检查。f2elint commit-file-scan 默认仅对 error 问题卡口,如果你想对 warn 问题也卡口,可以增加 --strict 参数以开启严格模式
注 1:如果项目已经配置过 ESLint、stylelint 等 Linter,执行 f2elint init 将会提示存在冲突的依赖和配置,并在得到确认后进行覆盖。
注 2:如果项目的 .vscode/ 目录被 .gitignore 忽略,可以在拉取项目后单独执行 f2elint init --vscode 命令写入 .vscode/extensions.json 和 .vscode/settings.json 配置文件
f2elint scan:一键扫描
在项目的根目录执行命令,即可扫描项目的规约问题:
支持下列参数:
-q --quiet 仅报告 error 级别的问题 -o--output-report 输出扫描出的规约问题日志 -i--include 指定要进行规约扫描的目录 --no-ignore 忽略 eslint 的 ignore 配置文件和 ignore 规则
注 1:事实上,你可以在任意目录执行 f2elint scan,F2ELint 会根据文件类型、JSON 等特征嗅探项目类型。但我们还是推荐在执行过 f2elint init 的项目根目录执行 f2elint scan,以得到最准确的扫描结果。
注 2:F2ELint 会根据项目内有无 eslint 和 stylelint 配置文件判断使用项目的配置文件还是 F2ELint 默认配置进行扫描。若使用项目的,在未安装依赖时会帮其安装(执行 npm i)。若使用项目配置扫描失败,则使用默认配置扫描
f2elint fix:一键修复
在项目的根目录执行命令,即可修复部分规约问题.
f2elint fix
支持下列参数: -i --include 指定要进行修复扫描的目录 --no-ignore 忽略 eslint 的 ignore 配置文件和 ignore 规则 注意请 review 下修复前后的代码,以免工具误修的情况。
f2elint commit-file-scan 提交文件扫描
在 git commit 时对提交文件进行规约问题扫描,需配合 git 的 pre-commit 钩子使用。
支持下列参数: -s --strict 严格模式,对 warn 和 error 问题都卡口,默认仅对 error 问题卡口
f2elint commit-msg-scan 提交信息扫描
git commit 时对 commit message 的格式进行扫描(使用 commitlint),需配合 husky 的 commit-msg 钩子使用。
结果
一顿操作过后我们基本上算是已经修复了80%的问题了,但是剩下的20%因为需要人工干涉取舍才能完成修复。
-
Expected '===' and instead saw '=='. eslint(eqeqeq)
项目中最多的warning,目的是为了类型安全。虽然只是警告,修复起来也不算困难,但是项目中实在是太多太多太多了。。。
-
Assignment to property of function parameter 'xxxx' eslint(no-param-reassign)
顾名思义就是不能给函数参数赋值类型。
这个问题在项目中也很常见,其次也不是很好修复。
规则的错误代码示例:
/*eslint no-param-reassign: "error"*/ function foo(bar) { bar = 13; } function foo(bar) { bar++; }
规则的正确代码示例:
/*eslint no-param-reassign: "error"*/ function foo(bar) { var baz = bar; }
-
no-nested-ternary 不允许有三元表达式,目的好像是嵌套三元表达式会使代码更难理解。
-
eval can be harmful.eslint(no-eval)
JavaScript的eval()功能是潜在的危险,经常被滥用。eval()在不受信任的代码上使用可以打开一个程序,最多可以进行多种不同的注入攻击 eval()在大多数情况下的使用可以取代对问题更好的替代方法。
-
indent 首行缩进
-
Unexpected var, use let or const instead.eslint(no-var)
除了非 ES6环境外,如果开始将 ES6引入其代码库的现有 JavaScript 项目可能不希望应用此规则,如果从var迁移到let的代价过高。
-
Missing radix parameter.eslint(radix)
第二个参数必填。如果您不想强制执基数值的存在或省略,则可以关闭此规则。
-
Unexpected string concatenation. eslint(prefer-template)
在 ES2015(ES6)中,我们可以使用模板文字而不是字符串连接。
-
Expected 1 empty line after import statement not followed by another import import/newline-after-import
import语句后的空行后面没有另一个import。(导入/导入后换行)
-
The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.eslint(guard-for-in)
循环遍历对象for in将包含通过原型链继承的属性。此行为可能会导致 for 循环中出现意外的项目。
正确示例:
/*eslint guard-for-in: "error"*/ for (key in foo) { if (Object.prototype.hasOwnProperty.call(foo, key)) { doSomething(key); } if ({}.hasOwnProperty.call(foo, key)) { doSomething(key); } }
-
no-lonely-if 如果一个if陈述是该else块中唯一的陈述,那么使用一个else if表格通常会更清晰。
if (foo) { // ... } else { if (bar) { // ... } }
应改写为:
if (foo) { // ... } else if (bar) { // ... }
-
xxxx is better written in dot notation.eslintdot-notation eslint(dot-notation)
在 JavaScript 中,可以使用点符号(foo.bar)或方括号表示法(foo["bar"])来访问属性。但是,点符号通常是首选,因为它更易于阅读,不会太冗长,而且在**性 JavaScript 最小化器中效果更好。
-
Expected longform method syntax for string literal keys.eslint(object-shorthand)
ECMAScript 6为定义对象字面值方法和属性提供了一个简明的形式。这种语法可以使定义复杂的对象文字更清晰。
var foo = { w: function() {}, x: function *() {}, [y]: function() {}, z: z };
应改写为:
var foo = { w() {}, *x() {}, [y]() {}, z };