因为我的项目是基于 Electron 平台的 Web 应用,使用 Vue 3 实现,而且用了 TypeScript,所以,在引入 ESLint 的时候,要考虑好几种规范的问题。
文章目录
- 零、简介
- 1. 规则
- 2. 配置文件
- 3. 共享配置
- 4. 插件
- 5. 解析器
- 6. 自定义处理器
- 一、在项目引入 ESLint
- 二、使用配置文件
- 1. 指定环境
- 2. 层级关系
- 3. 扩展
- 4. 忽略文件
- 三、在 Vue + Electron 项目中引入
- 总结
零、简介
ESLint 是一个可配置的 JavaScript 代码检查工具。它帮助你发现并修复 JavaScript 代码中的问题。这些问题可能包括潜在的运行时错误、未遵循最佳实践或风格问题等。
1. 规则
规则是 ESLint 的核心构建模块。规则用于验证你的代码是否符合某种特定的期望,以及如果不符合期望应该采取什么措施。规则还可以包含特定于该规则的额外配置选项。
例如,分号规则(semi
)允许你指定 JavaScript 语句是否应该以分号(;)结束。你可以设置规则,始终要求使用分号,或者要求语句永远不要以分号结束。
ESLint 包含数百个内置规则供你使用。你也可以创建自定义规则,或者通过插件使用其他人创建的规则。
2. 配置文件
ESLint 配置文件是一个地方,你可以在这里为你的项目设置 ESLint 的配置。你可以在配置文件中包含内置规则、指定你希望如何执行这些规则、带有自定义规则的插件、可共享的配置,以及你希望规则应用到哪些文件等等。
3. 共享配置
可共享配置(Shareable Configurations)是通过 npm
分享的 ESLint 配置。
通常,可共享配置用于使用 ESLint 的内置规则来强制执行风格指南。例如,可共享配置 eslint-config-airbnb-base
实现了流行的 Airbnb JavaScript 风格指南。
4. 插件
ESLint 插件是一个 npm
模块,它可以包含一组 ESLint 规则、配置、处理器和环境。通常,插件会包含自定义规则。插件可以用来强制执行风格指南,并支持 JavaScript 扩展(如 TypeScript)、库(如 React)和框架(如 Angular)。
插件的一个流行用例是强制执行框架的最佳实践。例如,@angular-eslint/eslint-plugin
包含了使用 Angular 框架的最佳实践。
5. 解析器
ESLint 解析器的作用是将代码转换成抽象语法树(AST),这样 ESLint 就可以对其进行评估。默认情况下,ESLint 使用内置的 Espree 解析器,它与标准的 JavaScript 运行时和版本兼容。
自定义解析器允许 ESLint 解析非标准的 JavaScript 语法。通常,自定义解析器作为可共享配置或插件的一部分包含在内,因此你不需要直接使用它们。
例如,@typescript-eslint/parser
是 typescript-eslint
项目中包含的一个自定义解析器,它允许 ESLint 解析 TypeScript 代码。这种解析器使得 ESLint 能够处理 TypeScript 特有的语法结构,从而在 TypeScript 项目中提供有效的代码检查和风格指导。
6. 自定义处理器
处理器的作用是从其他类型的文件中提取 JavaScript 代码,然后让 ESLint 对这些提取出来的 JavaScript 代码进行语法检查。此外,处理器还可以在 ESLint 解析 JavaScript 代码之前对其进行操作,比如转换或者预处理。
例如,eslint-plugin-markdown
插件包含了一个自定义的处理器,它允许你在 Markdown 文件的代码块内对 JavaScript 代码进行 lint 检查。这意味着,即使 JavaScript 代码嵌入在 Markdown 文件中,你也可以使用 ESLint 来检查这些代码的质量和风格,确保它们遵循你设定的规则。
这种处理器的使用扩展了 ESLint 的应用范围,使其不仅能够检查传统的 .js
文件,还能够处理其他格式文件中的 JavaScript 代码,从而为开发者提供了更全面的代码质量保障。
一、在项目引入 ESLint
假设你的项目已经有了 package.json
文件(一般都有),在项目里首次引入 ESLint 使用:
npm init @eslint/config
在项目的根目录里,有 ESLint 的配置文件,可以是三种格式的,js
,yml
,json
,我推荐使用 json
,因为如果你使用 js
的话,可能有模块标准的问题,比如你是 CommonJS 还是 ES Module 呢?跟项目自身的标准是否兼容?不如用 yml
或者 json
这种纯数据的格式。
ESLint 规则大概是这样的:
{
"rules": {
"semi": ["error", "always"],
"quotes": ["error", "double"]
}
}
上面的配置里面,有两条规则,第一条是关于分号(;
)的,error
是报错的级别,可选的值还有 warn
和 off
分别是警告和关闭。后面的 always
的意思是,总是使用分号的意思,就是这条规则的设定值。第二条规则是 quotes
关于引号的,后面写着 double
的意思是总是使用双引号。
二、使用配置文件
ESLint 配置文件是一个地方,你可以在这里为你的项目设置 ESLint 的配置。你可以在配置文件中包含内置规则、指定你希望如何执行这些规则、带有自定义规则的插件、可共享的配置,以及你希望规则应用到哪些文件等等。
1. 指定环境
一个环境,提供了预定义的全局变量。例如,咱们的项目里用到了 Electron 和 Vue,而且,原理上是有 Chromium 环境的,所以我们设置:
{
"env": {
"browser": true,
"node": true,
"es6": true
}
}
环境并不是互斥的。所以,如果你的代码里用到了多种环境的话,都可以设上。
2. 层级关系
可以在配置文件里,加一个 root: true
告诉 ESLint,这已经是顶层配置文件了,让 ESLint 不要再向上级目录搜寻配置了。
如果我们的某个子目录使用另外一种规则,我们也可以在子目录里放置一个 .eslintrc.json
配置文件,并设定这个,这样就会阻断 ESLint 使用根目录的配置规则。
3. 扩展
我们确实可以使用 rules
键来指定大量的规则,不过,我们更多还是使用 extends
来扩展。比如:
"extends": [
'eslint:recommended',
'plugin:vue/vue3-essential',
'@vue/eslint-config-typescript',
'@vue/eslint-config-prettier/skip-formatting',
'.eslintrc-auto-import.json',
]
这里扩展了很多东西,一个是官方推荐的规则集,第二个是 Vue 3 的插件,第三、四个可能是“共享配置”,而最后一个则是根目录里的另一个配置文件,可以说,这个扩展是无所不能。
4. 忽略文件
有时候,我们会在目录里放一些别的文件,比如我在项目里放入了一个 blog
目录,这里使用 Hexo 的生成器维护的一个文档站点,并用 GitHub Actions 自动发布到 GitHub Pages。这里也引用了大量的 js 代码,但是这些代码本质上跟我的项目无关,所以,需要忽略掉这个目录,可以写成:
{
"ignorePatterns" : [ "blog/"]
}
这样 ESLint 在扫描的时候,就会跳过这个目录,这个模式的配置,支持 blob
语法,如 src/**/__tests__/*
这种模式。
三、在 Vue + Electron 项目中引入
经过研究,我发现,在 Vue 的项目里,我们还是只能用 js
格式作为 eslint 的配置文件:
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = {
root: true,
env: {
node: true,
browser: true,
es6: true,
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:vue/vue3-essential',
'@vue/eslint-config-typescript',
'@vue/eslint-config-prettier/skip-formatting',
'.eslintrc-auto-import.json',
],
parserOptions: {
ecmaVersion: 'latest',
},
ignorePatterns: ['blog/'],
}
首先看第一行,这个配置文件的第一行 /* eslint-env node */
是一个 ESLint 的环境指令。它告诉 ESLint 这个文件是在 Node.js
环境中运行的,因此 ESLint 应该预定义所有 Node.js 全局变量,例如 process
和 __dirname
。这样,当你在代码中使用这些全局变量时,ESLint 不会报告 “未定义的变量” 错误。
第二行 require('@rushstack/eslint-patch/modern-module-resolution')
是在引入一个名为 @rushstack/eslint-patch/modern-module-resolution
的模块。这个模块是 Rushstack
的 ESLint 补丁,它改变了 ESLint 的模块解析机制,使其能够更好地支持现代的 JavaScript 模块解析规则,例如 Node.js 的 exports/imports
字段,或者 package.json
中的 exports
字段。这样可以帮助 ESLint 更准确地找到和解析项目中的模块。
也就是为了加载这个补丁,如果我们换成 json
格式的话,就没办法写 require
语句了。而且,看了官方的文档,下一代的配置文件格式,也是 js
格式的。
这里我们用的是官方创建项目的模板里带的一些推荐规则,都是以插件的形式提供的。我觉得这样的形式很好,其实编码规范的事情无所谓好坏,关键是每个人都去做。然后真的形成统一的风格,prettier
那个工具也是一样的,更加极端一点,直接内置很多规则在里面,就是为了节省团队的时间,大家省得去讨论哪种样式更好,而是用了这个工具后,就立刻接受了一整套规则,并且跟工具强制绑定。
我看有的项目还会配置 husky
,在 git 的 commit 环节注入检查和格式化,使得代码强制风格一致。让协作变得更为简单。
总结
本文介绍了 ESLint 的一般性用法,以及其配置文件的组成部分,最后介绍了在 Vue + Electron 的项目里如何配置 ESLint。