前言
今天的晨读文章是腾讯@ Nature Wake提交分享的。
沈皛是一名刚开始工作的前端实习生。第一次发展团队,难免有些紧张。在导师的安排下,我得到了项目的git许可,开始克隆。
$ git clone git @ github . com:company/project . git
沈皛开始品味他同事的准则。最后,通过不懈的努力,他发现了一个老王两年前写的bug。向导师汇报后,沈皛开始修改。年轻人意气用事,不仅修复老王的bug,还重构了这部分代码,使用了前两天刚从书里学来的策略模式,去掉了一些不必要的if else逻辑。沈潇洒地摸了摸自己稀疏的头发,得意地准备提交代码,又想到第一天就展示自己的超级编码能力。然后一件可怕的事情发生了,代码无法通过lint工具的测试,他急得跑去问导师,导师告诉他只需根据控制台的警告修改代码即可。沈皛反驳说,这个lint工具必须让我去掉分号。上学的时候老师教我分号是必须的,没有分号的代码并不完美。导师无奈地笑了笑,打开沈皛的实习成绩表,检查了一下团队合作的“差”。
沈皛很不服气,写了一篇博客,贴在CSDN上,获得了大量阅读。
JSLint徽标
JSLint可以说是Java最早的Lint工具,由道格拉斯·克洛克福特(《Java语言的本质》的作者)开发。从《Java语言的本质》的风格可以看出,道格拉斯是一个不能容忍眼睛有瑕疵的人,所以JSLint也继承了这个特点。JSLint的所有规则都是道格拉斯自己定义的。可以说这是一款带有道格拉斯个人风格的线头工具。如果你想使用它,你必须接受它的所有规则。值得称赞的是,JSLint还在更新,它还提供了一个节点版本:node-jslint。
JSHint
JSHint徽标
因为JSLint因为它的规则让很多人感到被压迫,安东·科瓦列夫(现在在Medium工作)开发了基于JSLint的JSHint。JSHint在JSLint的基础上提供了丰富的配置项,给了开发者很大的自由。JSHint从一开始就保持了开源软件的风格,由社区驱动,发展迅速。早期的jQuery也使用JSHint进行代码检查,但是现在已经转移到ESLint了。
ESLint
ESLint徽标
ESLint由尼古拉斯c .扎卡斯(Java高级编程的作者)于2013年6月创建。出现是因为zakas想用JSHint添加一个自定义规则,但是发现JSHint不支持,所以自己开发了一个。
ESLint,被称为下一代JS Linter工具,灵感来源于PHP Linter,将源代码解析成AST,然后检测AST来判断代码是否符合规则。eslit使用esprima将源代码解析成AST,然后你可以使用任何规则来检查AST是否符合预期,这就是eslit具有高度可伸缩性的原因。
早期源代码:
varast =esprima.parse(text,{loc:true,range:true}),
walk = astw(ast);
walk(函数(节点){
api.emit(node.type,node);});returnmessages
不过当时ESLint没有火,因为源代码需要转换成AST,运行速度输给了JSHint,JSHint已经有了完善的生态(编辑器支持)。ESLint真正火的是ES6的出现。
ES6发布后,由于添加了大量的语法,JSHint无法在短时间内提供支持,ESLint只需要一个合适的解析器来检查Lint。此时,巴别尔为ESLint提供了支持,开发了巴别尔-ESLint,使ESLint成为支持ES6语法最快的Lint工具。
谷歌趋势
2016年,eslit集成了另一个Lint工具:JSCS,它与eslit同时诞生,因为它与eslit的相似之处在于它通过生成AST来检测规则。
诚品整合JSCS
从此,ESLint主导了JS Linter领域,成为前端领域的主流工具。
林特工具的意义
让我们思考一个问题:Lint是对代码质量的保证还是对工程师的约束?
那么,我们来看看ESLint官网的介绍:
代码检查是一种静态分析,通常用于发现有问题的模式或代码,不依赖于具体的编码风格。对于大多数编程语言,都会有代码检查。一般来说,编译器都有内置的检查工具。
Java是动态弱类型语言,在开发中容易出错。因为没有编译器,为了发现Java代码错误,通常需要在执行过程中不断调试。和ESLint一样,程序员可以在编码的过程中发现问题,而不是在执行的过程中。
因为Java这种神奇的语言,不仅给我们带来了灵活性,也埋下了一些漏洞。比如= =中涉及的弱类型转换真的很让人苦恼,这一点也是一件让人困惑的事情。Lint工具很好地解决了这个问题,只是禁止你使用= =,这限制了语言的灵活性,但是带来了相当大的好处。
还有,作为一种动态语言,由于缺少编译过程,一些编译过程中本来可以发现的错误只有在运行之后才能发现,这给我们的调试工作增加了一些负担,而Lint工具相当于给语言增加了编译过程,在代码运行之前进行静态分析,找出错误。
综上所述,Lint工具的优势:
避免低级bug,找出可能发生的语法错误。使用未声明变量、修改 const 变量……提示删除多余的代码。声明而未使用的变量、重复的 case ……确保代码遵循最佳实践。可参考 airbnb style、java standard统一团队的代码风格。加不加分号?使用 tab 还是空格? 使用方式说了这么多,我们来看看ESLint实际上是如何使用的。
初始化
如果您想在现有项目中引入ESLint,可以直接运行以下命令:
#全局安装ESLint
$ npm install -g eslint
#输入项目
$ CD ~/Code/esLint-演示
#初始化package.json
$ npm init -f
#初始化ESLint配置
$ eslint - init
使用eslint —init后,会出现很多用户配置项。详情请参考eslint cli的源代码。
经过一系列的问答,你会发现在你的文件夹根目录下已经生成了一个eslintrc.js文件。
图像配置模式
ESLint可以通过两种方式进行配置:
使用注释把 lint 规则直接嵌入到源代码中这是最简单粗暴的方式,直接使用源代码中ESLint认可的标注方法来定义Lint规则。
/* ESL int eqeqeqq:" error " */varnum = 1
num =='1 '
当然,我们通常使用注释来暂时禁止一些严格的lint规则的警告:
/* eslint-disable */
Alert('此注释放在文件顶部,lint警告不会出现在整个文件中')/* eslit-enable */
报警('重新启用线头报警')/* eslimt-禁用eqeqeqeq */
警报('仅禁止一个或多个规则')/* eslimt-disable-下一行*/
警报(“当前行禁止棉绒警告”)
报警('当前行禁止掉毛警告')//eslimt-禁用-行
使用配置文件进行 lint 规则配置在初始化过程中,一个选项是使用什么文件类型进行lint配置(您希望您的配置文件采用什么格式?):
{
类型:“列表”,
名称:“格式”,
消息:“您希望您的配置文件采用什么格式?”,
默认:“Java”,
选择:[“Java”、“YAML”、“JSON”]}
官方总共提供了三个选项:
Java (eslintrc.js)YAML (eslintrc.yaml)JSON (eslintrc.json)此外,还可以在package.json文件中添加eslintConfig字段进行配置。
纵观ESLint源代码,我们可以看到其配置文件的优先级如下:
常量配置文件名=[
" . eslintrc.js ",
" . eslintrc.yaml ",
" . eslintrc.yml ",
" . eslintrc.json ",
".eslintrc ",
" package . JSON "];. eslintrc.js & gt. eslintrc.yaml >。. eslintrc.yml >。. eslintrc.json & gt。eslintrc >。package.json
当然,您也可以使用cli自己指定配置文件路径:
项目级和目录级配置
我们有以下目录结构。这时候在根目录下运行ESLint,我们会得到两个配置文件:。这两个配置文件会合并,但是src/.eslintrc.js优先级更高。
目录结构
但是,只要我们在src/.ESLintrc.js: true中配置“root”,eslint就会把src目录当成根目录,不会去查配置。
{
“root”:true }配置参数
让我们细细品味ESLinte的配置规则。
分析器配置{
//解析器类型
// espima(默认),babel-eslint,@ type-eslint/parse
" parse":"esprima ",
//解析器配置参数
" parseOptions":{
//代码类型:(默认),模块
" sourceType ":",
// es版本号,默认为5,也可以是年份,比如2015(同6)
“ecamVersion”:6、
// es功能配置
"电子邮件功能":{
“全局返回”:true,//允许在全局范围内使用返回语句
“隐含严格”:真。//启用全局严格模式
“JSX”:真//启用jsx
},
}}
parser @type-ESLint/parse主要是代替现有的TSLint。由于ESLint生态的繁荣和ESLint中更多的配置项,TS团队不得不放弃TSLint,转而实现一个eslint解析器。同时,解析器已经
{
“解析程序”:{
"电子邮件功能":{
“jsx”:真
},
“useJSXTextNode”:true,
“项目”:/tsconfig.json ",
" tsconfigRootDir ":"../../",
" extraFileExtensions":["。vue"]
}}环境和全局变量
ESLint会检测未声明的变量并发出警告,但是有些变量是我们介绍的库声明的,需要在配置中提前声明。
{
" globals":{
//将jQuery对象声明为全局变量
" $":false// true表示变量可写,而false表示只读
}}
在globals中逐个声明有点麻烦。这时候就需要使用env了,env是一个环境定义的一组全局变量的预置(类似巴别塔的预置)。
{
" env":{
“amd”:没错,
“commonjs”:真,
“jquery”:真
}}
可选环境有很多,预设值都是在这个文件中定义的。您可以从源代码中发现,预设变量都是从全局包中引用的。
包封/包围(动词envelop的简写)
环境规则设置
ESLint自带大量规则,可以在配置文件的rules属性中配置想要的规则。每个规则接受一个具有以下值的参数:
“off” 或 0:关闭规则“warn” 或 1:开启规则,warn 级别的错误 (不会导致程序退出)“error” 或 2:开启规则,error级别的错误(当被触发的时候,程序会退出)例如,我们首先编写一个使用等式的代码,然后以不同的方式配置eqeq规则。
// demo.jsvarnum =1
num =='1 '
Eqeqeq规则验证
这里使用命令行配置,如果您只想检查某个规则的单个文件,可以使用命令行配置。
然而,事情往往没有我们想象的那么简单。ESLint的规则不仅仅是关闭和打开那么简单,每个规则都有自己的配置项。如果需要配置规则,需要使用参数数组。
让我们看看报价规则。根据官网,支持字符串和对象两种配置项。
引号{
"规则":{
//以数组形式配置规则
//第一个参数是是否启用规则
//以下参数是规则的配置项
"引号":[
“错误”,
“单身”,
{
“回避逃避”:真
}
]
}}
根据上述规则:
//bad varstr = " test ' ESL int ' rule "//good varstr = ' test " ESL int " rule '扩展
扩展就是直接用别人写的lint规则,方便快捷。扩展通常支持三种类型:
{
" extensions ":[
“eslint:推荐”,
“插件:反应/推荐”,
“eslint-config-standard”,
]}
eslint: 开头的是 ESLint 官方的扩展,一共有两个:eslint:recommended 、eslint:all。plugin: 开头的是扩展是插件类型,也可以直接在 plugins 属性中进行设置,后面一节会详细讲到。最后一种扩展来自 npm 包,官方规定 npm 包的扩展必须以 eslint-config- 开头,使用时可以省略这个头,上面案例中 eslint-config-standard 可以直接简写成 standard。如果您对您的配置感到满意,您也可以将您的lint配置发布到npm包,只需将该包命名为ESLint-config-xxx,并在package.json的peerDependencies字段中声明您所依赖的ESLint的版本号
插件使用插件
虽然官方提供了上百条规则可供选择,但这还不够,因为官方的规则只能检查标准的Java语法。如果你写JSX或者Vue单文件组件,ESLint的规则就开始无奈了。
这时候就需要安装ESLint的插件,定制一些具体的规则进行检查。ESLint插件与扩展有相同的固定命名格式,从eslint-plugin-开始,使用时可以省略。
NPM install-save-dev ESL int-plugin-vue ESL int-plugin-react {
"插件":[
" react "//ESL int-plugin-react
" vue ",//eslit-plugin-vue
]}
或者在扩展中引入插件。plugin前面提到过:最初,扩展是加载插件。
{
" extensions ":[
“插件:反应/推荐”,
]}
通过扩展加载插件的规则如下:
ext plugin = ` plugin:$ { PlugInName }/$ { config name } `
对比上面的情况,pluginName是react,也就是之前安装的eslit-plugin-react包,推荐配置名。那么这个配置名从何而来呢?
可以看看eslint-plugin-react的源代码。
module.exports ={
//用户定义的规则
规则:所有规则,
//可用的扩展
配置:{
//插件:react/推荐
建议:{
插件:['react']
规则:{...}
},
//插件:react/all
全部:{
插件:['react']
规则:{...}
}
}}
配置名称是由插件配置的configs属性定义的,这里的配置实际上是ESLint的扩展。这样,插件和扩展都可以被加载。
开发插件
ESLint官方提供Yeoman的模板(generator-eslint),方便开发者使用。
#安装模块
npm安装-g yo发电机-eslint
#创建目录
mkdir eslint-plugin-demo
cd eslint-plugin-demo
#创建模板
yo eslint:插件
eslint:插件
Eslint:插件目录
创建项目后,您可以开始创建规则。幸运的是,生成器-eslint不仅可以生成插件的模板代码,还具有创建规则的模板代码。打开之前创建的eslint-plugin-demo文件夹,在这个目录下添加一个规则。我希望这个规则可以检测到我的代码中是否有控制台,所以我将这个规则命名为disable-console。
yo eslint:规则
eslint:规则
Eslint:规则目录
接下来,让我们来看看如何指定ESLinte的一个规则:
打开lib/rules/disable-console.js,可以看到默认的模板代码如下:
module.exports ={
meta:{
文档:{
deion:“禁用控制台”,
类别:“填写我”,
推荐:false
},
架构:[]
},
创建:函数(上下文){
//变量应该在这里定义
返回{
//给我方法
};
}};
简要介绍参数(详见官方文件介绍):
meta:规则的一些描述信息 descrition(string):规则的简短描述 category(string):规则的类别(具体类别可以查看官网) recommended(boolean):是否加入 eslint:recommended docs:规则的描述对象 schema(array):规则所接受的配置项create:返回一个对象,该对象包含 ESLint 在遍历 Java 代码 AST 时,所触发的一系列事件勾子。在详细解释如何创建规则之前,我们先来谈谈AST(抽象语法树)。ESLint使用一个名为Espree的Java解析器将Java代码解析成一个AST。然后深入遍历AST,每个规则都会监控匹配过程。只要类型匹配,就会检查相应的规则。为了方便查看AST的每个节点类型,这里提供了一个网站,可以清楚地查看一段代码解析成AST: astexplorer后的外观。如果你想找到所有AST节点的类型,你可以检查发情期。
astexplorer
astexplorer
可以看到console.log属于ExpressionStatement中的CallExpression。
{
" type":"ExpressionStatement ",
" expression":{
"类型":" CallExpression ",
"被呼叫者":{
"类型":" MemberExpression ",
" object":{
“类型”:“标识符”,
"名称":"控制台"
},
" property":{
“类型”:“标识符”,
" name":"log "/>
试验
最后,只需介绍插件,打开规则。
// eslintrc.js
module.exports ={
插件:['演示'],
规则:{
demo/disable-console:[
错误',['信息']
],
}}
使用插件演示的最佳配置
最佳配置
业界有很多针对Java的编码规范推荐,以下两个比较有名:
airbnb stylejava standard同时,这里也推荐AlloyTeam的eslint-config-alloy。
但是,代码规范应该由团队成员制定,以确保每个人都能接受。如果真的有人不同意,少数人只能服从多数人。虽然这一节的标题叫做最佳配置,但在软件行业中没有一个方案是最佳方案。甚至java标准也不是java标准的编码标准。只是叫这个名字而已,合适的才是最好的。
最后,安利将结合ESLint和bearer,不仅统一编码标准,而且统一编码风格。具体做法可以参考我的文章:用eslit+bearer统一前端代码风格。
摘要
看到这里,我们来做个总结。Java中linter工具的开发历史并不算短。ESLint之所以能成为后来者,主要是因为JSLint和JSHint使用自上而下的方法解析代码,早期的Java语法几千年都没有更新。这种方法可以以更快的速度解析代码,并找到可能的语法错误和不规则代码。但是ES6发布后,Java语法发生了很多变化,如箭头函数、模板字符串、扩展运算符等。随着这些语法的发布,JSLint和JSHint在不更新解析器的情况下无法检测到ES6的代码。而ESLint则采取了不同的方式,使用AST对代码进行静态分析,保留了很强的可扩展性和灵活的配置能力。这也告诉我们,在日常的编码过程中,一定要考虑后续的扩展能力。
正是因为这种强大的可扩展性,使得行业内的很多Java编码规范可以快速登陆到各个团队,团队定制的代码规范也可以对外共享。
最后,希望你已经了解了eslimt带来的好处,掌握了eslimt的用法,能够将eslimt引入到现有的项目中,提高项目的代码质量。
参考
ESLint 官网JS Linter 进化史ESLint 工作原理探讨他曾经分享过
【第1458号】元素的施工工艺
【1395号】Deep V8发动机:“小整数”有多小?
【第1010号】回顾ESLint的成功
ESLint工作原理探讨。
作者分享了“前端开发的高级核心知识”课程
1.《eslint 【第1684期】 深入理解ESLint》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《eslint 【第1684期】 深入理解ESLint》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/fangchan/1369129.html