本文正在参加「金石计划」
朋友,作为一个合格的代码工程师,你有代码洁癖吗?相信很多人的简历上都会有提到这个点,那面试官问你针对代码洁癖你做了哪些尝试的时候,你一定会联想到ESLint和Prettier等等...
特别是对于多人合作的项目,代码规范难以统一,代码质量参差不齐,这个时候,你就一定会寻求ESLint和Prettier的帮助,这可以提高团队合作的开发效率,一定程度的提升代码的质量。
这篇文章将会带领你弄清ESlint的前世今生,弄清ESLint 与 Prettier的区别,教你如何处理ESLint 与 Prettier的冲突,还会教你在ts项目中如何配置ESLint,只顾埋头写业务的朋友们有福气了,这篇文章将会带你一起轻松的弄清ESLint和Prettier能为我们前端开发做什么!
本篇不涉及具体的使用步骤,想看具体使用步骤的朋友请参考别的文章哟。
追根溯源 ESlint
JSLint 与 JSHint 的由来
ESLint 的诞生与翻身
番外:AST 是什么
抽象语法树 (Abstract Syntax Tree),简称 AST,它是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。
js 执行的第一步是读取 js 文件中的字符流,然后通过词法分析生成 token,之后再通过语法分析( Parser )生成 AST,最后生成机器码执行。
整个解析过程主要分为以下两个步骤:
- 分词:将整个代码字符串分割成最小语法单元数组
- 语法分析:在分词基础上建立分析语法单元之间的关系
JS Parser 是 js 语法解析器,它可以将 js 源码转成 AST,常见的 Parser 有 esprima、traceur、acorn、shift 等。
深入了解AST请参考下文
ESLint 与 Prettier
ESLint解决了什么问题
一、代码质量问题:使用方式有可能有问题(problematic patterns)
二、代码风格问题:风格不符合一定规则 (doesn’t adhere to certain style guidelines)
各种 Linters 是按照规则(Rules)去检查代码的,遇到不符合规则的代码就会提示你,有的规则还能自动帮你解决冲突。
这些规则也分为两类:
一、Formatting rules(风格规则)
- 例如 ESlint 的 max-len 规则,设置单行长度不能超过 80 字符
- 例如 ESLint 的 keyword-spacing 规则,关键字前后必须有空格
二、Code-quality rules(质量规则)
- 例如 ESLint 的no-unused-vars规则,不允许没用的变量定义出现
有了 ESLint 为什么还需要 Prettier
ESLint 主要解决的是代码质量问题。另外一类代码风格问题并没有完完全全做完,因为这些问题"没那么重要",代码质量出问题意味着程序有潜在 Bug,而风格问题充其量也只是看着不爽。
而 Prettier 是一个支持很多语言的代码格式化工具, 对应的是各种 Linters 的 Formatting rules 这一类规则。而且你用了 Prettier 之后,就不会再违反这类规则了!不需要你自己手动修改代码。
官网用了一个“贬义”的单词来形容它 opinionated,翻译过来就是固执己见的。
ESLint Prettier 同时使用的冲突处理
由于ESLint也处理了一些代码风格相关的内容,所以在这两者一并使用的时候会有一些冲突,可以参考以下步骤来规避。(仅供参考,具体项目具体配置)
- 除了eslint之外,下载三个npm包
npm i prettier eslint-plugin-prettier eslint-config-prettier
- 插件配置
eslint插件以eslint-plugin-开头,使用时可以省略
使用eslint-plugin-prettier插件,会调用prettier对你的代码风格进行检查。
原理:先使用prettier对你的代码进行格式化,然后与格式化之前的代码进行对比,如果出现了不一致,这个地方就会被prettier进行标记。
// .eslintrc.js
{
"plugins": ["prettier"]
}
- 规则配置(可选)
被标记后Prettier并不会有任何提示,我们还需要对标记后的代码进行报错处理,在rules中进行添加配置。
如果不希望Prettier影响项目打包,我们也可以将prettier的报错由error改为warn。
// .eslintrc.js
{
"rules": {
"prettier/prettier": "error",
}
}
- extends扩展
如果每条规则都需要团队协商配置还是比较繁琐的,在项目开始配置时,我们可以先使用一些业内已经成熟的、大家普遍遵循的编码规范(最佳实践);我们可以通过extends字段传入一些规范,接收String/Array。
extends可以使用以下几种类型的扩展:
- eslint:开头的ESLint官方扩展,有两个:eslint:recommended(推荐规范)和eslint:all(所有规范)。
- plugin:开头的扩展是插件类型扩展
- eslint-config:开头的来自npm包,使用时可以省略eslint-config-,比如可以直接写成standard
- @:开头的扩展和eslint-config一样,是在npm包上面加了一层作用域scope
// .eslintrc.js
{
"extends": ["plugin:vue/recommended", "plugin:prettier/recommended"],
}
安装后一个插件中会有很多同类型扩展可供选择,比如vue就有以下几种扩展:
- plugin:vue/base:基础
- plugin:vue/essential:必不可少的
- plugin:vue/recommended:推荐的
- plugin:vue/strongly-recommended:强烈推荐
针对扩展中的规则,我们也能够通过rules来对它进行覆写
// .eslintrc.js
{
"extends": [
"plugin:vue/recommended"
],
"rules": {
// 覆写规则
"vue/no-unused-vars": "error"
}
}
不过需要注意的是,很多规范不仅需要安装扩展本身,还需要配合插件,比如eslint-config-standard,我们还需要安装下面几个插件才能有效:
npm i eslint-config-standard -D
npm i eslint-plugin-promise eslint-plugin-import eslint-plugin-node -D
Prettier 与 ESLint 之间的关系
Prettier 并不会取代各种 Linters,而是能避免你的代码和这些 Linters 定义的 Formatting rules 冲突。
Linters 检查出来违反 Code-quality rules 的情况后还需要你自己根据业务逻辑和语法手动修改。
Prettier 帮你格式化代码,但是不会帮你挑出潜在的错误。
ESLint Rules检索表
示例
{
"rules": {
"semi": ["error", "always"],
"quotes": ["error", "double"]
}
}
"semi" 和 "quotes" 是 ESLint 中 规则 的名称。第一个值是错误级别,可以使下面的值之一:
- "off" or 0 - 关闭规则
- "warn" or 1 - 将规则视为一个警告(不会影响退出码)
- "error" or 2 - 将规则视为一个错误 (退出码为1)
为什么 TS 项目要使用 ESLint
- 框架问题: TSLint 执行规则的方式存在一些框架问题,从而影响性能,而修复这些问题会破坏现有的规则。
- 性能: ESLint 的性能更好,并且社区用户通常拥有 ESLint 的规则配置(比如 React 和 Vue 的配置),而不会拥有 TSLint 的规则配置。
2019 年 1 月,TypeScript 官方决定全面采用 ESLint。之后也发布typescript-eslint 项目,以集中解决 TypeScript 和 ESLint 兼容性问题。而之前的两个 lint 解决方案都将弃用:
- typescript-eslint-parser 已停止维护
- 在完成 ESLint 功能后,将弃用 TSLint 并帮助用户迁移到 ESLint
ESlint 处理 TS 遇到问题
因为 ts 编译器和 ESLint 在开始各自的工作之前都会将代码转换成 AST(抽象语法树),而两种语法树是不兼容的。这时,我们可以使用 typescript-eslint ,它为 ESLint 提供了专门解析 ts 代码的编译器,来解决 TypeScript 和 ESLint 兼容性问题。
- @typescript-eslint/parser 为 ESLint 提供解析器。
- @typescript-eslint/eslint-plugin 作为 ESLint 默认规则的补充,提供了一些额外的适用于 ts 语法的规则。
以下是在vue3+ts项目中使用eslint+prettier的eslint配置文件参考。
// .eslintrc.js
module.exports = {
parser: "vue-eslint-parser",
extends: ["plugin:vue/recommended", "plugin:prettier/recommended"],
parserOptions: {
parser: "@typescript-eslint/parser",
ecmaVersion: 2018,
sourceType: "module",
},
plugins: ["vue", "@typescript-eslint"],
rules: {
"vue/multi-word-component-names": "off",
"vue/valid-v-for": "off",
},
}
以上就是本篇全部内容,感谢观看,希望有帮助到你。