Eslint
Eslint 是国外的前端大牛Nicholas C. Zakas在 2013 年发起的一个开源项目,有一本书被誉为前端界的”圣经”,叫《JavaScript 高级程序设计》(即红宝书),他正是这本书的作者。
Nicholas 当初做这个开源项目,就是为了打造一款插件化的 JavaScript 代码静态检查工具,通过解析代码的 AST 来分析代码格式,检查代码的风格和质量问题。现在,Eslint 已经成为一个非常成功的开源项目了,基本上属于前端项目中 Lint 工具的标配。
ESLint 的使用并不复杂,主要通过配置文件对各种代码格式的规则(rules)进行配置,以指定具体的代码规范。目前开源社区也有一些成熟的规范集可供使用,著名的包括Airbnb JavaScript 代码规范、Standard JavaScript 规范、Google JavaScript 规范等等,你可以在项目中直接使用这些成熟的规范,也可以自己定制一套团队独有的代码规范,这在一些大型团队当中还是很常见的。
安装 & 初始化
pnpm i eslint -D
接着执行 ESLint 的初始化命令,并进行如下的命令行交互:
npx eslint --init
核心配置
1. parser - 解析器
ESLint 底层默认使用 Espree来进行 AST 解析,这个解析器目前已经基于 Acron 来实现,虽然说 Acron 目前能够解析绝大多数的 ECMAScript 规范的语法,但还是不支持 TypeScript ,因此需要引入其他的解析器完成 TS 的解析。
社区提供了@typescript-eslint/parser这个解决方案,专门为了 TypeScript 的解析而诞生,将 TS 代码转换为 Espree 能够识别的格式(即 Estree 格式),然后在 Eslint 下通过Espree进行格式检查, 以此兼容了 TypeScript 语法。
2. parserOptions - 解析器选项
这个配置可以对上述的解析器进行能力定制,默认情况下 ESLint 支持 ES5 语法,你可以配置这个选项,具体内容如下:
- ecmaVersion: 这个配置和
Acron的 ecmaVersion 是兼容的,可以配置ES + 数字(如 ES6)或者ES + 年份(如 ES2015),也可以直接配置为latest,启用最新的 ES 语法。 - sourceType: 默认为
script,如果使用 ES Module 则应设置为module - ecmaFeatures: 为一个对象,表示想使用的额外语言特性,如开启
jsx
3. rules - 具体代码规则
rules 配置即代表在 ESLint 中手动调整哪些代码规则,比如禁止在 if 语句中使用赋值语句这条规则可以像如下的方式配置:
// .eslintrc.js
module.exports = {
// 其它配置省略
rules: {
// key 为规则名,value 配置内容
"no-cond-assign": ["error", "always"]
}
}
在 rules 对象中,key 一般为规则名,value 为具体的配置内容,在上述的例子中我们设置为一个数组,数组第一项为规则的 ID,第二项为规则的配置。
这里重点说一说规则的 ID,它的语法对所有规则都适用,你可以设置以下的值:
off或0: 表示关闭规则。warn或1: 表示开启规则,不过违背规则后只抛出 warning,而不会导致程序退出。error或2: 表示开启规则,不过违背规则后抛出 error,程序会退出。
具体的规则配置可能会不一样,有的是一个字符串,有的可以配置一个对象,你可以参考 ESLint 官方文档。
当然,你也能直接将 rules 对象的 value 配置成 ID,如: "no-cond-assign": "error"。
4. plugins
上面提到过 ESLint 的 parser 基于Acorn实现,不能直接解析 TypeScript,需要我们指定 parser 选项为@typescript-eslint/parser才能兼容 TS 的解析。同理,ESLint 本身也没有内置 TypeScript 的代码规则,这个时候 ESLint 的插件系统就派上用场了。我们需要通过添加 ESLint 插件来增加一些特定的规则,比如添加@typescript-eslint/eslint-plugin 来拓展一些关于 TS 代码的规则,如下代码所示:
// .eslintrc.js
module.exports = {
// 添加 TS 规则,可省略`eslint-plugin`
plugins: ['@typescript-eslint']
}
值得注意的是,添加插件后只是拓展了 ESLint 本身的规则集,但 ESLint 默认并没有开启这些规则的校验!如果要开启或者调整这些规则,你需要在 rules 中进行配置,如:
// .eslintrc.js
module.exports = {
// 开启一些 TS 规则
rules: {
'@typescript-eslint/ban-ts-comment': 'error',
'@typescript-eslint/no-explicit-any': 'warn',
}
}
5. extends - 继承配置
extends 相当于继承另外一份 ESLint 配置,可以配置为一个字符串,也可以配置成一个字符串数组。主要分如下 3 种情况:
- 从 ESLint 本身继承;
- 从类似
eslint-config-xxx的 npm 包继承; - 从 ESLint 插件继承;
- 从配置文件中继承。
// .eslintrc.js
module.exports = {
"extends": [
// 第1种情况
"eslint:recommended",
// or 启用当前安装的 ESLint 中所有的核心规则
"eslint:all",
// 第2种情况,一般配置的时候可以省略 `eslint-config`
"standard"
// 第3种情况,可以省略包名中的 `eslint-plugin`
// 格式一般为: `plugin:${pluginName}/${configName}`
"plugin:react/recommended"
"plugin:@typescript-eslint/recommended",
// 第4种
"./node_modules/coding-standard/eslintDefaults.js",
]
}
有了 extends 的配置,对于之前所说的 ESLint 插件中的繁多配置,我们就不需要手动一一开启了,通过 extends 字段即可自动开启插件中的推荐规则:
extends: ["plugin:@typescript-eslint/recommended"]
更多继承配置项:Configuring ESLint - ESLint中文文档
6. env 和 globals
这两个配置分别表示运行环境和全局变量,在指定的运行环境中会预设一些全局变量,比如:
// .eslint.js
module.export = {
"env": {
"browser": "true",
"node": "true"
}
}
指定上述的 env 配置后便会启用浏览器和 Node.js 环境,这两个环境中的一些全局变量(如 window、global 等)会同时启用。
有些全局变量是业务代码引入的第三方库所声明,这里就需要在globals配置中声明全局变量了。每个全局变量的配置值有 3 种情况:
"writable"或者true,表示变量可重写;"readonly"或者false,表示变量不可重写;"off",表示禁用该全局变量。
那jquery举例,我们可以在配置文件中声明如下:
// .eslintrc.js
module.exports = {
"globals": {
// 不可重写
"$": false,
"jQuery": false
}
}
相信有了上述核心配置部分的讲解,你再回头看看初始化生成的 ESLint 配置文件,你也能很好地理解各个配置项的含义了。
eslint-plugin-vue
是Vue.js 的官方 ESLint 插件。这个插件允许我们使用 ESLint 检查文件的<template>和,以及文件中的 Vue 代码。
Tips:
插件支持Vue.js 3.2的基本语法、
<script setup>CSS变量注入,但尚不支持Vue.js 3.2的实验性特性ref糖。
安装
npm install --save-dev eslint eslint-plugin-vue
# or
yarn add -D eslint eslint-plugin-vue
要求:
- ESLint v6.2.0 及以上版本
- Node.js v14.17.x、v16.x 及更高版本
使用
实例**.eslintrc.js**
module.exports = {
extends: [
'plugin:vue/base',
// Vue3 配置
'plugin:vue/vue3-essential',
'plugin:vue/vue3-strongly-recommended',
'plugin:vue/vue3-recommended',
// Vue2 配置
'plugin:vue/essential',
'plugin:vue/strongly-recommended',
'plugin:vue/recommended',
],
}
查看规则列表以获取此插件提供的extends和 rules
捆绑配置
这个插件提供了一些预定义的配置,可以通过将以下配置添加到extends.
"plugin:vue/base"…启用正确 ESLint 解析的设置和规则。- 使用 Vue.js 3.x 的配置。
"plugin:vue/vue3-essential"…base,加上防止错误或意外行为的规则。"plugin:vue/vue3-strongly-recommended"… 以上,加上可显着提高代码可读性和/或开发体验的规则。"plugin:vue/vue3-recommended"… 以上,加上强制执行主观社区默认设置以确保一致性的规则。
- 使用 Vue.js 2.x 的配置。
"plugin:vue/essential"…base,加上防止错误或意外行为的规则。"plugin:vue/strongly-recommended"… 以上,加上可显着提高代码可读性和/或开发体验的规则。"plugin:vue/recommended"… 以上,加上强制执行主观社区默认设置以确保一致性的规则
从命令行运行 ESLint
如果要eslint从命令行运行,请确保使用选项.vue或 glob 模式包含扩展名,--ext因为.js默认情况下 ESLint 仅针对文件。
举个例子:
eslint --ext .js,.vue src
eslint "src/**/*.{js,vue}"
如果你安装了@vue/cli-plugin-eslint,你应该将lint脚本添加到你的package.json. 这意味着您可以运行yarn lintor npm run lint。
如何使用自定义解析器?
如果你想使用自定义解析器,比如@babel/eslint-parser或@typescript-eslint/parser,你必须使用parserOptions.parseroption 而不是parseroption 。因为这个插件需要vue-eslint-parser来解析.vue文件,所以如果你覆盖这个选项,这个插件就不起作用了parser。
- "parser": "@typescript-eslint/parser",
+ "parser": "vue-eslint-parser",
"parserOptions": {
+ "parser": "@typescript-eslint/parser",
"sourceType": "module"
}
该parserOptions.parser选项还可以指定一个对象来指定多个解析器。有关详细信息,请参阅vue-eslint-parser README 。
解析器选项
如果使用vue-eslint-parser解析器。对于parserOptions,你可以使用vueFeatures选项去配置vue-eslint-parser。
{
"parser": "vue-eslint-parser",
"parserOptions": {
"vueFeatures": {
"filter": true,
"interpolationAsNonHTML": false,
}
}
}
有关详细信息,请参阅parserOptions.vueFeatures文档。vue-eslint-parser
更多阅读:用户指南 | eslint-插件-vue
在 Vite 中接入 ESLint
vite-plugin-eslint可以在开发阶段进行 ESLint 扫描,以命令行的方式展示出代码中的规范问题,并能够直接定位到原文件。
安装:
npm install eslint vite-plugin-eslint --save-dev
# or
yarn add eslint vite-plugin-eslint -D
vite.config.ts 中接入:
// vite.config.ts
import viteEslint from 'vite-plugin-eslint';
// 具体配置
{
plugins: [
// 省略其它插件
viteEslint(),
]
}
Prettier
安装 & 初始化
pnpm i prettier -D
在项目根目录新建.prettierrc.js配置文件
// .prettierrc.js
module.exports = {
printWidth: 80, //一行的字符数,如果超过会进行换行,默认为80
tabWidth: 2, // 一个 tab 代表几个空格数,默认为 2 个
useTabs: false, //是否使用 tab 进行缩进,默认为false,表示用空格进行缩减
singleQuote: true, // 字符串是否使用单引号,默认为 false,使用双引号
semi: true, // 行尾是否使用分号,默认为true
trailingComma: "none", // 是否使用尾逗号
bracketSpacing: true // 对象大括号直接是否有空格,默认为 true,效果:{ a: 1 }
};
结合 Eslint
接下来我们将Prettier集成到现有的ESLint工具中,首先安装两个工具包:
pnpm i eslint-config-prettier eslint-plugin-prettier -D
其中eslint-config-prettier用来覆盖 ESLint 本身的规则配置,避免冲突。而eslint-plugin-prettier则是用于让 Prettier 来接管eslint --fix即修复代码的能力。
extends: [
// 其他配置
// 接入 prettier 的规则
"prettier",
"plugin:prettier/recommended"
],
Stylelint
Stylelint 的强大源于:
- 拥有超过 170 条内置规则 赖检查最新的 CSS 语法和功能
- 支持 插件 以创建你自己的规则
- 自动 修复 大多数代码格式上的问题
- 经过 15000 多次的 充分的单元测试
- 支持扩展或创建 可共享的配置
- 非强制约束(unopinionated),可根据你自己的需求进行自定义
- 像 Prettier 一样可以 美化打印 效果
- 拥有一个 不断增长的社区,并且被 Google、GitHub 和 WordPress 所使用
还可以被扩展为:
- 解析 类似 CSS 的语法,例如 SCSS、Sass、Less 以及 SugarSS
- 能够从 HTML、Markdown 和 CSS-in-JS 对象以及模板文本中提取 内嵌的样式代码
它是如何帮助你的? 它可以帮助你避免错误,例如:
- 无效的东西,比如说畸形的网格区域
- 有问题的有效内容,如重复的选择器
- 未知的东西,例如,拼错的属性名称
不允许的事情,例如:
- 不允许的事情,比如说特定的单位
- 强制执行命名模式,例如,自定义属性的命名模式
- 设置限制,例如,ID选择器的数量
- 指定符号,例如,现代颜色功能的符号
我们建议在使用Stylelint的同时使用Prettier。Linters和pretty printers是互补的工具,它们一起工作,帮助你写出一致且无错误的代码。