我正在参加「掘金·启航计划」
一、前言
大家好,我是story,一直想写一篇关于项目工作流的文章,因为它的重要性是不言而喻的,可以指导我们更好把代码从形式上写的优美而规范。我也通过很多博客学习过很多的用法和内容,但是大部分文章可能都只是提供了一部分的代码和配置,用法上看这些文章跟着走当然没有问题,但是实际上要灵活变通,深刻理解,我认为还有所欠缺,这篇文章我希望谈谈自己对项目工作流的理解,一是自我总结,二是帮助他人。下面我们就一起来聊聊吧!
二、ESLint
正如官网所说ESLint
是一个可组装
的JavaScript
和JSX
检查工具。默认情况下,ESLint是仅支持对JS或者JSX的检测和校验。可组装的意思是指我们可以通过对ESLint进行各种各样的配置然后使其按照我们想要的方式进行配置。
为什么出现?
一个工具的出现一定有它的原因,ESLint也是一样的,在程序员写代码的时候,我们时常会犯一些总是无法避免的问题,比如定义了变量但是没有去使用它、局部变量使用和全局变量一样的变量名、函数已经被return了,但依然会写一写代码等等。以上属于语法问题,虽说可能不会影响实际的执行,但是他是不符合我们对于规范代码的追求的;其次随着项目的大型化,团队开发的场景越来越多,避免不了团队中好几个人一起开发一个项目,但每个人的代码风格可能各不相同,有的人喜欢加分号,有的人不喜欢加分号等,在代码的格式上,萝卜白菜各有所爱;
于是ESLint在2013
年开始出现了,它是基于Node.js
的,通过Javascript
去编写,它提供了最为主要的几个功能,可以让我们通过命令行
的方式去校验我们所有的代码,有两个核心功能,一是校验
,告知我们那个地方犯了什么错误,二是修复
可以帮助我们尽可能的按照某种规则修复这些错误;并且最为重要的是,它也提供了由我们去决定和定义该使用什么样的规则进行校验和修复;
接下来我们看一下通过命令行如何进行使用
温馨提示
:在实操的时候,建议关掉VSCode中ESLint以及prettier插件,清除掉所有setting.json中的配置;保持实验环境的一致性,当然如果你hold
的住则不用;
先按照下面的命令进行项目准备:
mkdir learn-eslint && cd learn-eslint
npm init -y
npm i eslint -g 或者 npm i eslint -D
复制代码
eslint依赖在全局安装或者本地项目安装都是可以的,只是使用命令行命令时有所区别;全局安装可以直接使用
eslint 命令
复制代码
本地安装则是
npx eslint 命令
复制代码
npx
是npm提供的一个全局命令,它可以帮助你在本地依赖(node_modules)下寻找bin目录下的可执行文件;然后基于node执行这个可执行文件;以下我们使用本地安装的方式进行演示;
安装好依赖之后,默认情况下,ESLint只支持JS或者JSX的校验;创建以下的目录结构;
|-- package.json
|-- src
|-- index.js
|-- index.jsx
复制代码
// index.js
var a = '小鹏'
复制代码
// index.jsx
var fun = function (){
return "小鹏"
}
复制代码
要想真正校验我们的语法,我们需要定义一个规则,在检测的过程中ESLint支持多种格式的配置文件:
- javascript -- .eslintrc.js
- ymal -- .eslintrc.yaml
- json -- eslintrc.json
- package.json -- 在package.json里创建一个eslintConfig属性
如果同一个目录下有多个配置文件,ESLint只会使用一个。优先级顺序如下:
- .eslintrc.js
- .eslintrc.yaml
- .eslintrc.json
- .eslintrc
- package.json
接下来创建一个eslintrc.json的文件;配置一些内容
|-- .eslintrc.json
|-- package.json
|-- src
|-- index.js
|-- index.jsx
复制代码
在json文件中,ESLint的配置是以一个javascript对象的方式进行配置的,其中rules这个属性可以配置一些自定义的规则,这也符合ESLint的官网所描述的ESLint
是一个可组装
的JavaScript和JSX检查工具,具体的规则大家可以自行查看。我们根据以上的规则配置以下两个规则:
// .eslintrc.json
{
"rules":{
"semi": "error", // 要求或禁止使用分号
"no-unused-vars": "error" // 禁止出现未使用过的变量
}
}
复制代码
可以看到,我们之前定义过的index.js
以及index.jsx
中代码全部违反了以上的规则,接下来ESLint就可以通过命令行的方式去进行检验。eslint支持golb路径语法,所以以下命令代表检测项目根目录src下所有的js和jsx文件;
npx eslint src/**
复制代码
效果如下:
报错信息映入眼帘,违反了我们规则的代码都被检测出来了,信息中有给我们提供行号,以及为什么报错,因此我们只需要根据相应的错误修改代码只至正确就好了;
当然,如果一个一个改那得改到猴年马月去!根据提示我们可以使用--fix
让ESLint帮助我们根据规则进行修复!
npx eslint src/** --fix
复制代码
命令行提示
代码
效果如上,错误已经修复了一部分,代码的分号ESLint已经帮助我们加上了,但是有些错误,ESLint还是不会帮助我修复,比如定义了未使用的变量,这个确实也可以理解,因为它不可能帮着我们把定义了得变量给删了呀;因为这样破坏性太强了;但是总的来说,已经帮助我们修复了很大一部分的错误了;
总结:所以到这里我们可以小小总结一下,ESLint依赖具备两个重要的作用:
- 检测出我们代码中的错误
- 部分修复我们代码中的错误
当然以上的过程都是基于我们自己定制的规则;下面可以聊一聊ESLint相关的配置
{
"root": true, // 是否向上查询父级的eslint配置
"parser": "", // 解析器
"env": {...}, // 环境
"extends": [], // 扩展
"parserOptions": {
// EsLint 对于不同的 Parser(解析器)配置的语言检查规则。
"ecmaVersion": "", // ES版本
"sourceType": "" // 模块化方案
},
"plugins": [], // 插件
"overrides":[ // 覆盖配置
{ ... }
]
}
复制代码
以上是我们常用到的一些ESLint配置;
下面重点说一些主要的属性:
parser
这个是ESLint的解析器配置,我们可以指定使用什么解析器来进行解析代码,因为ESLint的校验过程实际上是将我们的代码转化为抽象语法数,然后再遍历抽象语法树,对每个节点进行规则判断,和删减代码,然后再转为代码作为输出,因此需要解析器;默认的解析器为estree
,我们也可以使用其他解析器,比如esprima
、Babel-ESLint
、@typescript-eslint/parser
;比如我们我们需要ESLint来校验TS语法,就需要使用@typescript-eslint/parser
解析器了;extends
扩展和plugin
插件的区别,扩展的本质其实就是一份配置,使用扩展就相当于继承了一份完整的配置;而插件是定义一些新的规则,使用插件后还需要在rules
中自己配置规则,但是大部分插件都有自己的建议扩展;
这不ESLint配置会自带默认的额建议规则;
{
"env":{
"node":true,
"browser":true
},
"extends":["eslint:recommended"]
}
复制代码
我们只需要这样配置,规则中带√的就都帮我们预置好了;
运行
npx eslint src/**
复制代码
说明规则生效了;
以上我们讲解了依赖的作用;接下来我们还可以利用VSCode插件来帮助我们提示代码;因为每次如果通过命令行的方式来进行修复和检验的话就特别被动,效率也没有特别高,如果在边写代码就能边看到错误提示的话,那将特别好,可以在写代码的时候就将错误尽量的避免。
在VSCode插件市场中搜索这个插件,下载安装,已经下载过的就启用这个插件;
插件一旦生效会根据当前目录的规则,其实也就是我们之前定义的配置文件.eslintrc.json里面的规则对我们的代码进行校验,如果有错误就直接飘红;
当前的配置文件内容为
{
"env":{
"node":true,
"browser":true
},
"extends":["eslint:recommended"],
"rules": {
"semi":"error"
}
}
复制代码
鼠标放上去就可以看到错误类型,然后根据相应的错误类型我们去修改代码就行;或者执行命令
npx eslint src/** --fix
复制代码
但是这样开发代码总会有点难受;还是离不开命令行,于是我们可以借助vscode本身格式化的能力;我们都知道VSCode自己是具备格式化代码的能力的,就是说每次在ctrl+S保存的时候我们自己可以定义按照什么样的规则进行格式化;而幸运的是,ESLint插件也提供了这样的规则接口给VSCode;但是我们网上很多博客都是粘了一大堆settings.json的配置,但是本质上我们只需要新增很简单的一句配置就行;
"editor.codeActionsOnSave": {
"source.fixAll":true
},
复制代码
or
"editor.codeActionsOnSave": {
"source.fixAll.eslint":true
},
复制代码
这个配置加入VSCode中settings.json中;并保存;
然后回到index.js文件中,ctrl+S保存代码后,就会按照ESLint的规则进行格式化;如果还是没作用,把vscode关闭重启一下;就必然会生效;
好了,以上便是ESLint在工作流中最为普遍和简单的用法,当然还有更多高级的用法,有机会后面再聊;所以做一个小小的总结:
- ESLint依赖的能力是通过命令行来对代码进行校验和修复;
- ESLint的VSCode插件是帮助开发者即时提示代码错误;
- 插件和VSCode本身共同合作帮助我们保存时格式化代码;
三、Prettier
Prettier相较于ESLint我认为会相对好理解一些;根据官网的描述,Prettier是一个具有以下特点的格式化工具;
- 一个“有态度”的代码格式化工具
- 支持大量编程语言
- 已集成到大多数编辑器中
- 几乎不需要设置参数
有态度
是由英语单词opinionated
翻译过来的;
从这个介绍来看,Prettier其实是比较蛮横的一个工具;它设计的初心就是各位程序员,你别也别争谁的代码格式更好看了,都听我的吧,我来定义什么是真正的美,你们把主要心思放在业务上,剩下的事交给我就好了;
虽然比较霸道总裁,但确实是这样的,这也就是为什么Prettier对外暴露的自定义配置是很少的,不像ESLint那样配置多的吓人;
不同的是Prettier支持格式化的类型很多,包括.js、.jsx、.ts、.vue、.css、.sass等等。而ESLint如果需要支持除javascript以外的语言则需要额外的插件甚至是解析器才可以;
此外为什么已经有了ESLint还需要有Prettier的存在呢?
不得不承认,在某些方面他们两个的功能其实是有一定的重合的,但是不同是更多的;Prettier侧重解决代码的风格问题,ESLint侧重解决代码质量问题;他们的关系就像下面这样:
所以为了解决所有问题,从工程化的角度来看,他们都是值得使用的,甚至是不可或缺的;
那接下来就来看一下如何使用Prettier吧;
还是一样为了保持环境的干净,请将刚刚我们添加的下面这一段settings.json注释掉;
"editor.codeActionsOnSave": {
"source.fixAll":true
},
复制代码
如果已经下载了prettier插件就先禁用掉;
mkdir learn-prettier && cd learn-prettier
npm init -y
npm i prettier -g 或者 npm i prettier -D
复制代码
创建如下的工作目录
|-- package-lock.json
|-- package.json
|-- .prettierrc
|-- src
|-- index.css
|-- index.js
|-- index.vue
复制代码
// index.vue
<template>
<div>
<span> <button></button> </span>
</div>
</template>
<script>
export default {
data(){
return {}
},
methods:{
onClick(){
console.log("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
}
}
}
</script>
复制代码
//index.js
const a = "aaaaaaaaaaaaaaaaaaaaaaaaaaa"
const b = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
复制代码
// index.css
.a { width:100px} .b{ color:#333}
复制代码
相信你看到这样的代码格式很想打人,但是我们为了方便测试效果,只好这样夸张一点;接着我们添加下面两个简单的配置;
//.prettierrc
{
//使用单引号(singleQuote: <bool>)
"semi":true,
// 一行代码的最大字符数,默认是80(printWidth: <int>)
"printWidth": 80,
}
复制代码
运行命令
npx prettier --check .
复制代码
这个命令会帮我们报告那些文件格式有问题,但并不会修复格式;
运行命令
npx prettier --write .
复制代码
看着个这个说明已然帮助我们修复好了相应的格式问题;并且还算比较好看;
接下来,就像ESLint一样,我们尝试借助插件自动的修复格式;下载并安装下面的插件;
在VSCode中的settings.json中新增下面的配置
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
复制代码
以上两个配置缺一不可;然后返回文件,将任意文件打乱保存,就可以按照prettier的默认格式化代码了;效果如下:
四、Prettier与ESLint的冲突解决
既然Prettier和ESLint他们之间功能有重合的部分,那么他们就一定会存在打架的时候,这个时候怎么办呢?我们需要借助两个依赖,他们分别是:
npm i eslint-config-prettier eslint-plugin-prettier -D
复制代码
在ESLint配置的文件中加上extends
的扩展prettier
,如下:
{
"env":{
"node":true,
"browser":true
},
"extends":["eslint:recommended", "prettier"],
}
复制代码
经过以上的配置,他俩就不会打架了,因为这个扩展会覆盖前面的扩展,不同的部分,会按照prettier的格式去进行校验,因此可以通过此扩展避免打架,重合的部分按照prettier的规则进行;
{
"env":{
"node":true,
"browser":true
},
"extends":["eslint:recommended", "prettier"],
"plugins":["prettier"],
"rules":{
"prettier/prettier":"error"
}
}
复制代码
插件的作用是违反prettier规则的部分统一按照eslint的报错进行输出,因为prettier的VSCode插件是不会帮你去在写代码的时候报错的;因此通过ESLint报错输出是很合适的;
五、总结
好了,以上便是整体的我们ESLint+Prettier工作流的全部内容,通过以上的配置,我们可以很轻松的将prettier和eslint运用起来;如果出现配置有问题的地方,可在评论区留言;
bye!