JS代码检查工具ESLint介绍与使用方法
ESLint不但提供一些默认的规则,也提供用户自定义规则来约束所写的JavaScript代码。
发展历史
DouglasCrockford大神根据自己的理念用JavaScript写了一个JavaScript代码规范检查工具,这就是JSLint。后来非常流行,也的确帮助了广大的JavaScript程序员。但是,大神对于自己的代码规范不做丝毫的妥协,对开源社区的反馈的回应也不礼貌。于是,JSLint从一个帮助程序员规范代码,避免Bug的工具,变成了一个让代码像Crockford的工具。在最不信神的IT界,这当然不能忍了
2011年,一个叫AntonKovalyov的前端程序员借助开源社区的力量弄出来了JSHint,该工具的思想基本上和JSLint是一致的,但具有以下几点优势:1、可配置规则。2、社区支持度高。3、可定制结果报表
起初几年,JSHint一直是前端代码检测工具的首选。但在2013年,Zakas大佬发现JSHint已经无法满足自己定制化规则的需求,而且和Anton讨论后达成共识这根本在不可能在JSHint上实现。同时Zakas还设想发明一个基于AST的lint,可以动态执行额外的规则,同时可以很方便的扩展规则
2013年的6月份,Zakas发布了全新的lint工具——ESLint。ESLint的出现并没有撼动JSHint的霸主地位。由于前者是利用AST处理规则,用Esprima解析代码,执行速度要比只需要一步搞定的JSHint慢很多;其次当时已经有许多编辑器对JSHint支持完善,生态足够强大。真正让ESLint逆袭的是ECMAScript6的出现
2015年6月,ES2015规范正式发布。但是发布后,市面上浏览器对最新标准的支持情况极其有限。如果想要提前体验最新标准的语法,就得靠Babel之类的工具将代码编译成ES5甚至更低的版本,同时一些实验性的特性也能靠Babel转换。这时JSHint就略尴尬,ES2015变化很大,短期内无法完全支持。ESLint可扩展的优势一下就体现出来了,不仅可以扩展规则,甚至连解析器也能替换。Babel团队就为ESLint开发了babel-eslint替换默认解析器,让ESLint率先支持ES2015语法
也是在2015年,React的应用越来越广泛,诞生不久的JSX也愈加流行。ESLint本身也不支持JSX语法。还是因为可扩展性,eslint-plugin-react的出现让ESLint也能支持当时React特有的规则
至此,ESLint完美躺赢,替代JSHint成为前端主流工具
ESLint详细配置
注释配置
有两种主要的方式来配置ESLint,其中一种就是注释配置,使用JavaScript注释把配置信息直接嵌入到一个代码源文件中
可以在文件中使用以下格式的块注释来临时禁止规则出现警告
/*eslint-disable*/ alert('foo'); /*eslint-enable*/
也可以对指定的规则启用或禁用警告:
/*eslint-disableno-alert,no-console*/ alert('foo'); console.log('bar'); /*eslint-enableno-alert,no-console*/
如果在整个文件范围内禁止规则出现警告,将/*eslint-disable*/块注释放在文件顶部:
/*eslint-disable*/ alert('foo');
文件配置
另一种是文件配置,使用JavaScript、JSON或者YAML文件为整个目录和它的子目录指定配置信息
ESLint支持几种格式的配置文件
JavaScript-使用.eslintrc.js然后输出一个配置对象。
YAML-使用.eslintrc.yaml或.eslintrc.yml去定义配置的结构。
JSON-使用.eslintrc.json去定义配置的结构,ESLint的JSON文件允许JavaScript风格的注释。
(弃用)-使用.eslintrc,可以使JSON也可以是YAML。
package.json-在package.json里创建一个eslintConfig属性,在那里定义配置。
如果同一个目录下有多个配置文件,ESLint只会使用一个。优先级顺序如下
1.eslintrc.js
2.eslintrc.yaml
3.eslintrc.yml
4.eslintrc.json
5.eslintrc
6 package.json
除了配置一个独立的.eslintrc.*文件,也可以直接在package.json文件里的eslintConfig字段指定配置,ESLint将自动在要检测的文件目录里寻找它们,紧接着是父级目录,一直到文件系统的根目录
{ "name":"mypackage", "version":"0.0.1", "eslintConfig":{ "env":{ "browser":true, "node":true } } }
或者使用-c选项传递命令行将文件保持到任意地方
eslint-cmyconfig.jsonmyfiletotest.js
配置语言
ESLint允许指定想要支持的JavaScript语言选项。默认情况下,ESLint支持ECMAScript5语法。可以覆盖该设置,以启用对ECMAScript其它版本和JSX的支持
ecmaVersion-默认设置为3,5(默认),可以使用6、7、8或9来指定想要使用的ECMAScript版本。也可以用使用年份命名的版本号指定为2015(同6),2016(同7),或2017(同8)或2018(同9)
sourceType-设置为"script"(默认)或"module"(如果代码是ECMAScript模块)
ecmaFeatures-这是个对象,表示想使用的额外的语言特性:
globalReturn-允许在全局作用域下使用return语句
impliedStrict-启用全局strictmode(如果ecmaVersion是5或更高)
jsx-启用JSX
experimentalObjectRestSpread-启用实验性的objectrest/spreadproperties支持
配置示例
"parserOptions":{ "ecmaVersion":6, "sourceType":"module", "ecmaFeatures":{ "jsx":true } }
配置环境
一个环境定义了一组预定义的全局变量。这些环境并不是互斥的,可以同时定义多个。可用的环境包括
browser-浏览器环境中的全局变量。
node-Node.js全局变量和Node.js作用域。
commonjs-CommonJS全局变量和CommonJS作用域
shared-node-browser-Node.js和Browser通用全局变量。
es6-启用除了modules以外的所有ECMAScript6特性(该选项会自动设置ecmaVersion解析器选项为6)
worker-WebWorkers全局变量。
amd-将require()和define()定义为像amd一样的全局变量。
mocha-添加所有的Mocha测试全局变量。
jasmine-添加所有的Jasmine版本1.3和2.0的测试全局变量。
jest-Jest全局变量。
phantomjs-PhantomJS全局变量。
protractor-Protractor全局变量。
qunit-QUnit全局变量。
jquery-jQuery全局变量。
prototypejs-Prototype.js全局变量。
shelljs-ShellJS全局变量。
meteor-Meteor全局变量。
mongo-MongoDB全局变量。
applescript-AppleScript全局变量。
nashorn-Java8Nashorn全局变量。
serviceworker-ServiceWorker全局变量。
atomtest-Atom测试全局变量。
embertest-Ember测试全局变量。
webextensions-WebExtensions全局变量。
greasemonkey-GreaseMonkey全局变量。
可以在JavaScript文件中使用注释来指定环境
/*eslint-envnode,mocha*/
也可以在配置文件里指定环境,使用env关键字指定想启用的环境,并设置它们为true
{ "env":{ "browser":true, "node":true } }
如果想在一个特定的插件中使用一种环境,确保提前在plugins数组里指定了插件名,然后在env配置中不带前缀的插件名后跟一个/,紧随着环境名
{ "plugins":["example"], "env":{ "example/custom":true } }
配置插件
ESLint支持使用第三方插件。在使用插件之前,必须使用npm安装它。
在配置文件里配置插件时,可以使用plugins关键字来存放插件名字的列表。插件名称可以省略eslint-plugin-前缀
{ "plugins":[ "plugin1", "eslint-plugin-plugin2" ] }
注意:由于Node.js的require函数的行为,全局安装的ESLint实例只能使用全局安装的ESLint插件,本地安装的版本,只能用本地安装的插件。不支持混合本地和全局插件
配置规则
ESLint附带有大量的规则。可以使用注释或配置文件修改项目中要使用的规则。要改变一个规则设置,必须将规则ID设置为下列值之一:
"off"或0-关闭规则
"warn"或1-开启规则,使用警告级别的错误:warn(不会导致程序退出)
"error"或2-开启规则,使用错误级别的错误:error(当被触发的时候,程序会退出)
为了在文件注释里配置规则,使用以下格式的注释:
/*eslinteqeqeq:"off",curly:"error"*/
也可以在配置文件中进行规则配置
{ "rules":{ "eqeqeq":"off", "curly":"error", "quotes":["error","double"] } }
配置定义在插件中的一个规则的时候,必须使用插件名/规则ID的形式
{ "plugins":[ "plugin1" ], "rules":{ "eqeqeq":"off", "curly":"error", "quotes":["error","double"], "plugin1/rule1":"error" } }
也可以使用这种格式的注释配置
/*eslint"plugin1/rule1":"error"*/
配置继承
一个配置文件可以被基础配置中的已启用的规则继承
值为"eslint:recommended"的extends属性启用一系列核心规则,这些规则报告一些常见问题。这个推荐的子集只能在ESLint主要版本进行更新
"extends":"eslint:recommended"
插件是一个npm包,通常输出规则。一些插件也可以输出一个或多个命名的配置。要确保这个包安装在ESLint能请求到的目录下
{ "plugins":[ "react" ], "extends":[ "eslint:recommended", "plugin:react/recommended" ], "rules":{ "no-set-state":"off" } }
extends属性值可以是基本配置文件的绝对路径或相对路径。ESLint解析基本配置文件的相对路径相对使用的配置文件,除非那个文件在主目录或非ESLint安装目录的父级目录。在这些情况下,ESLint解析基本配合文件的相对路径相对于被检测的项目目录(尤其是当前工作目录)
{ "extends":[ "./node_modules/coding-standard/eslintDefaults.js", "./node_modules/coding-standard/.eslintrc-es6", "./node_modules/coding-standard/.eslintrc-jsx" ], "rules":{ "eqeqeq":"warn" } }
配置忽略
可以通过在项目根目录创建一个.eslintignore文件告诉ESLint去忽略特定的文件和目录
.eslintignore文件是一个纯文本文件,其中的每一行都是一个glob模式表明哪些路径应该忽略检测
例如,以下将忽略所有的JavaScript文件:
**/*.js
如果没有发现.eslintignore文件,也没有指定替代文件,ESLint将在package.json文件中查找eslintIgnore键,来检查要忽略的文件
{ "name":"mypackage", "version":"0.0.1", "eslintConfig":{ "env":{ "browser":true, "node":true } }, "eslintIgnore":["hello.js","world.js"] }
NodeJS配置eslint规则
下面来介绍NodeJS环境下如何配置airbnb-base的eslint规则
1、本地安装eslint、eslint-config-airbnb-base、eslint-plugin-import
npminstall--save-deveslint npminstall--save-deveslint-config-airbnb-base npminstall--save-deveslint-plugin-import
注意:最好使用npm,而不是cnpm安装。因为在使用本地安装的eslint时,会使用其安装路径。而npm和cnpm的安装路径不一致
2、安装成功后,package.json文件中增加如下字段
"devDependencies":{ "eslint":"^4.19.1", "eslint-config-airbnb-base":"^12.1.0", "eslint-plugin-import":"^2.12.0" }
3、在根目录下设置.eslintrc.js配置文件
module.exports={ "extends":["airbnb-base"], "env":{ "es6":true, "node":true }, "rules":{ "comma-dangle":["error","never"],//要求或禁止末尾逗号:不允许逗号 "indent":["error",2],//JavaScript代码强制使用一致的缩进:2格缩进 "semi":["error","never"],//不使用分号 "arrow-parens":["error","as-needed"],//箭头函数的参数可以不使用圆括号 "linebreak-style":"off",//取消换行符\n或\r\n的验证 "object-curly-newline":["error",{"consistent":true}],//花括号内的换行符不一定要格式一致 "function-paren-newline":"off",//不验证函数括号内的换行 "import/extensions":"off",//取消对文件扩展名的验证 "no-param-reassign":"off",//允许对函数参数进行再赋值 "no-underscore-dangle":"off",//允许在标识符中使用下划线 "no-use-before-define":"off",//允许变量和函数在定义前使用 "no-unused-expressions":"off",//允许使用未使用过的表达式,以此来支持a&&a()的代码形式 "no-console":"off",//启用console控制台 "consistent-return":"off",//关闭函数中return的检测 "no-shadow":"off",//可以使用同名变量, "newline-per-chained-call":"off",//取消方法链调用中的换行符的检测 "import/newline-after-import":"off" } }
4、在命令行工具中使用命令,对文件进行lint校验
PSD:\blog\api\node_modules\.bin>./eslint../../index.js D:\blog\api\index.js 16:1error'a'isnotdefinedno-undef ✖1problem(1error,0warnings)
React使用eslint
1、安装eslint-config-airbnb配置合集
npminstall--save-deveslint-config-airbnb
Airbnb包括了以下三个插件
eslint-plugin-import eslint-plugin-react eslint-plugin-jsx-a11y
2、在根目录下创建.eslintrc.js配置文件
module.exports={ //指定校验的ECMAScript的版本及特性 "parserOptions":{ "ecmaVersion":7,//ECMAScript版本,7为ES7 "sourceType":"module",//默认script,如果代码是ECMAScript模块,设置为module "ecmaFeatures":{//使用额外的语言特性 "jsx":true//启用JSX } }, //当访问未定义的变量时,no-undef规则将发出警告 //指定脚本的运行环境。每种环境都有一组特定的预定义全局变量 "env":{ "es6":true, "node":true, "browser":true, }, //当访问未定义的变量时,no-undef规则将发出警告 //脚本在执行期间访问的额外的全局变量 "globals":{ "document":true, "navigator":true, "window":true, "node":true }, //使用第三方airbnb开发配置合集 "extends":"airbnb", //eslint-config-airbnb包括了以下3个插件 "plugins":[ "react", "jsx-a11y", "import" ], //定义自己的规则 "rules":{ "comma-dangle":["error","never"],//要求或禁止末尾逗号:不允许逗号 "indent":["error",2],//JavaScript代码强制使用一致的缩进:2格缩进 "semi":["error","never"],//不使用分号 "arrow-parens":["error","as-needed"],//箭头函数的参数可以不使用圆括号 "react/jsx-filename-extension":[1,{"extensions":[".js",".jsx"]}],//reajs文件的后缀名为.js或.jsx均可 "linebreak-style":"off",//取消换行符\n或\r\n的验证 "object-curly-newline":["error",{"consistent":true}],//花括号内的换行符不一定要格式一致 "function-paren-newline":"off",//不验证函数括号内的换行 "import/extensions":"off",//取消对文件扩展名的验证 "import/no-unresolved":"off",//取消自动解析路径,以此开启alias的别名路径设置 "no-shadow":"off",//取消变量声明覆盖的验证,保证mapDispatchToProps的正确使用 "no-param-reassign":"off",//允许对函数参数进行再赋值 "no-underscore-dangle":"off",//允许在标识符中使用下划线 "no-use-before-define":"off",//允许变量和函数在定义前使用 "no-unused-expressions":"off",//允许使用未使用过的表达式,以此来支持a&&a()的代码形式 "jsx-a11y/anchor-is-valid":["error",{"components":["Link"],"specialLink":["to"]}],//允许正常地使用Link "import/no-extraneous-dependencies":"off",//使用history/createBrowserHistory引入包时,不会报错 "no-console":"off"//启用console控制台 } };
Vue使用eslint
使用vue-cli创建项目时,如果使用eslint,会有如下图所示的选项,选择使用standard还是airbnb规范
以standard规范创建成功后,package.json文件,会出现如下字段
"eslint":"^4.15.0", "eslint-config-standard":"^10.2.1", "eslint-friendly-formatter":"^3.0.0", "eslint-loader":"^1.7.1", "eslint-plugin-import":"^2.7.0", "eslint-plugin-node":"^5.2.0", "eslint-plugin-promise":"^3.4.0", "eslint-plugin-standard":"^3.0.1", "eslint-plugin-vue":"^4.0.0",
与此同时,在根目录下自动生成.eslintrc.js配置文件
//https://eslint.org/docs/user-guide/configuring module.exports={ root:true, parserOptions:{ parser:'babel-eslint' }, env:{ browser:true }, extends:[ //https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention //considerswitchingto`plugin:vue/strongly-recommended`or`plugin:vue/recommended`forstricterrules. 'plugin:vue/base', //https://github.com/standard/standard/blob/master/docs/RULES-en.md 'standard' ], //requiredtolint*.vuefiles plugins:['vue'], //addyourcustomruleshere rules:{ //allowasync-await 'generator-star-spacing':'off', //allowdebuggerduringdevelopment 'no-debugger':process.env.NODE_ENV==='production'?'error':'off', } }
如果需要更改为更严格的验证,可以下载并使用airbnb规范
npminstall--save-deveslint-config-airbnb-base
在extends字段中,将standard更改为airbnb-base,将plugin:vue/base更改为plugin:vue/recommended
extends:[ 'plugin:vue/recommended', 'airbnb-base' ],
添加一些自定义的规则,最终的配置文件如下所示
//https://eslint.org/docs/user-guide/configuring module.exports={ root:true, parserOptions:{ parser:'babel-eslint' }, env:{ browser:true }, extends:[ //https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention //considerswitchingto`plugin:vue/strongly-recommended`or`plugin:vue/recommended`forstricterrules. 'plugin:vue/recommended', //https://github.com/standard/standard/blob/master/docs/RULES-en.md 'airbnb-base' ], //requiredtolint*.vuefiles plugins:['vue'], //addyourcustomruleshere rules:{ //allowasync-await 'generator-star-spacing':'off', //allowdebuggerduringdevelopment 'no-debugger':process.env.NODE_ENV==='production'?'error':'off', "linebreak-style":"off",//取消换行符\n或\r\n的验证 "semi":["error","never"],//不使用分号 "arrow-parens":["error","as-needed"],//箭头函数的参数可以不使用圆括号 "comma-dangle":["error","never"],//不允许末尾逗号 "consistent-return":"off",//关闭函数中return的检测 "object-curly-newline":["error",{"consistent":true}],//花括号内的换行符不一定要格式一致 "global-require":"off",//取消对require的验证,使得可以使用require来加载图片的相对路径 "function-paren-newline":"off",//不验证函数括号内的换行 "import/no-unresolved":"off",//取消自动解析路径,以此开启alias的别名路径设置 "no-param-reassign":"off",//允许对函数参数进行再赋值 "import/extensions":"off",//取消对文件扩展名的验证 "max-len":"off",//取消行的最大长度的验证,使SVG不用重新调整格式 "no-underscore-dangle":"off",//允许标识符中有下划线,从而支持vue中插件的使用 "no-console":"off",//启用console控制台 "no-unused-expressions":"off",//允许使用未使用过的表达式,以此来支持a&&a()的代码形式 "no-shadow":"off",//取消变量声明覆盖的验证 'vue/attribute-hyphenation':0,//取消对元素特性只能使用中划线或小驼峰形式的验证 'vue/max-attributes-per-line':0//取消元素有多个特性时,每个特性独占一行的验证 } }
更多关于JS代码检查工具ESLint的文章大家可以看看下面的相关链接
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。