早在 1978 年,Stephen C. Johnson 在 Debug 自己的 C 语言项目时,突然想到为什么不做一个工具来提示自己写的代码哪里有问题呢?
这个工具也被称为 Linter。Linter 本意指的是衣服上多出来的小球、绒毛和纤维等。
Linter 想要提示错误,首先就得阅读代码,这也是为什么 Linter 也被称为静态代码分析的工具。阅读完之后,再加上人为自定义的一些规则,那么 Linter 就拥有了提示错误的能力。
JavaScript Linter 发展史
JSLint
在 2002 年,Douglas Crockford 就为 JavaScript 写了第一个 Linter 工具:JSLint。
JSLint 的优点就是开箱即用,不需要配置太多的东西,相当于拎包入住。但优点也是缺点,就是规则太严格,完全不可扩展和自定义配置,连配置文件都没有。
JSHint
2010 年 Anton Kovalyov 和其他人,在 JSLint 的基础上 fork 了一份,改造成了 JSHint。
这个工具与 JSLint 的思路正好相反,它的默认规则非常松散,自由度非常高。但是也同样带来了问题:需要非常了解这些规则才能配出一个好用的规则表。因为规则太不严格,过于自由,所以单纯靠默认的规则跟没有配置 Linter 一样。
JSCS
前面的 JSLint 和 JSHint 主要功能都是检查代码质量问题,JSCS(JavaScript Coding Style)则是一个代码风格检查器。
它有超过 90 条规则,也能自己创建规则,不过这些规则主要是和代码风格、代码格式化有关,它不会报任何和 JS 代码质量相关的错误。
尽管 JSCS 在其活跃时期非常受欢迎,但它已于 2016 年被宣布停止维护,并建议用户迁移到 ESLint。ESLint 是一个更强大、更灵活的工具,它不仅可以检查代码风格,还可以发现潜在的错误和代码质量问题。另一个流行的代码格式化工具是 Prettier,它专注于自动格式化代码,而不提供任何代码质量检查。
虽然 JSCS 不再被维护,但它的一些功能和理念已经被 ESLint 和 Prettier 等现代工具所采纳。如果你正在寻找一个代码风格检查器和格式化器,建议使用 ESLint 和 Prettier 来替代 JSCS。这两个工具可以很好地协同工作,ESLint 负责检查代码质量,而 Prettier 负责格式化。
ESLint
2013 年,一个叫 JSChecker 的小项目被改名成我们如今非常熟悉的 ESLint。
ES6 上线之后,JSHint 就受不了直接投降了,因为它不支持这些 ES6 新语法。而 ESLint 正好异军突起,马上用 Esprima (一个高性能的 ECMAScript parser)支持所有 ES6 新语法,并对新语法做好了校验。
除了基础的 ES6 代码质量校验,ESLint 还支持代码风格的规则。开发者不仅可以自定义项目要用哪些规则,也能直接使用社区上制定的规则(比如 eslint-config-airbnb
)。
这一波操作也让 ESLint 成为现在 JavaScript 首选的 Linter 了。然而,关于 Linter 的故事还没结束。
2012 年微软公布了第一版的 TypeScript,随之而来的还有一个叫 TSLint 的 Linter。
在那段时间里,TSLint 是 TypeScript 的标准 Linter 工具,ESLint 则是 JavaScript 标准 Linter。它们各有自身特色:ESLint 有 TSLint 所没有的一些语法特性支持,而 TSLint 可以对代码进行静态分析和类型检查。
可是,一份代码还要两个 Linter 并行检查属实有点让人不爽。TSLint 也经常和 ESLint 的人探讨应该用哪个作为主力 Linter。TS 的社区也有很多声音希望优先满足 JSer 的需求,毕竟 TS 是 JS 的超集,还是以 ESLint 为主。
最终,在 2019 年 TSLint 宣告不再维护,ESLint 支持 TypeScript。
ESLint 核心概念
ESLint 的核心概念包括以下几点:
- 规则(Rules):规则是 ESLint 的核心,它们是独立的脚本,用于检查代码中的特定问题。ESLint 有许多内置规则,这些规则可以覆盖各种编码风格和潜在错误。规则是可配置的,每个规则可以被启用或禁用,并可以设置为警告或错误级别。
- 配置(Configuration):ESLint 允许通过配置文件自定义规则的启用和设置。配置文件可以是
.eslintrc.*
格式的文件或package.json
文件里的eslintConfig
字段。配置可以继承其他配置,这使得可以轻松地共享和组合规则集。共享配置通常是一个 npm 包,可以被多个项目使用。 - 插件(Plugins):插件是可扩展 ESLint 功能的方式,它们包含一组自定义规则和/或处理器。这使得 ESLint 可以适应不同的编码风格和技术栈。插件可以通过 npm 安装并在配置文件中引用。
- 处理器(Processors):处理器是一个可选的插件特性,它可以对非 JavaScript 文件进行预处理,以便 ESLint 可以检查这些文件中嵌入的 JavaScript 代码。例如,HTML 文件中的
<script>
标签或 Markdown 文件中的代码块。 - 命令行接口(CLI):ESLint 提供了一个命令行接口,用于在终端中执行 linting 操作。CLI 允许用户指定一个或多个文件、目录或 glob 模式 以进行检查。CLI 还支持许多选项,这些选项可以覆盖配置文件中的设置,如禁用特定规则、规定输出格式等。
ESLint 快速上手
首先创建一个 eslint-demo
的项目,使用 pnpm init
进行初始化,安装 ESLint:
pnpm add eslint -D
然后在项目根目录下面创建一个 ESLint 的配置文件 .eslintrc
,里面会书写一些配置信息:
{
"env": {
"browser": true,
"es2021": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
"indent": ["error", 2],
"quotes": ["error", "single"],
"semi": ["error", "never"]
}
}
env
:主要是定义预设的全局变量browser
:这份配置适用于浏览器环境,预定义了诸如window
、document
之类的浏览器全局变量es2021
: 表示使用的是 ES2021 标准,会预定义一些新版本的全局变量,如Promise
、Symbol
extends
:ESLint 配置继承,eslint:recommended
是 ESLint 团队推荐的一组核心规则parserOptions
:和解析器相关的配置ecmaVersion
:使用的 ECMAScript 的版本,12 就是 2021sourceType
:模块类型,这里设置为module
,表示使用的 ESM 模块规则,支持import
和export
语法
rules
:定义代码风格,功能类似于 Prettierindent
:缩进,这里设置的是两个空格,如果不符合要求,会报error
类型的错误quotes
:引号的设置,这里设置的是单引号,如果不符合要求,会报error
类型的错误semi
:在没有 ASI 风险情况下,不需要插入分号,如果不符合要求,会报error
类型的错误
最后修改 package.json
,添加如下的 script
脚本命令:
"scripts": {
// ...
"lint": "eslint ./src"
},
使用 ESlint 进行代码检查的时候,是支持自动修复的,但是并非所有的错误都能够自动修复,只能够修复一部分。
要自动进行修复,只需要添加命令行参数 --fix
即可。