Lint工具用于检查代码的语法是否正确、风格是否符合要求。
JavaScript语言的最早的Lint工具,是Douglas Crockford开发的JSLint。由于该工具所有的语法规则,都是预设的,用户无法改变。所以,很快就有人抱怨,JSLint不是让你写成正确的JavaScript,而是让你像Douglas Crockford一样写JavaScript。
JSHint可以看作是JSLint的后继者,最大特定就是允许用户自定义自己的语法规则,写在项目根目录下面的.jshintrc
文件。
JSLint和JSHint同时检查你的语法和风格。另一个工具JSCS则是只检查语法风格。
最新的工具ESLint不仅允许你自定义语法规则,还允许用户创造插件,改变默认的JavaScript语法,比如支持ES6和JSX的语法。
ESLint最初是由Nicholas C. Zakas 于2013年6月创建的开源项目。它的目标是提供一个插件化的javascript代码检测工具。
快速上手
安装npm模块:
1 | npm install eslint --save-dev |
在测试之前,我们首先编辑一个测试文件:
1 | // main.js |
使用命令行测试:
1 | npx eslint ./main.js |
执行后出现以下提示:
1 | ops! Something went wrong! :( |
这是说eslint未找打一个配置文件,可以使用eslint --init
为你的项目初始化一个配置文件。
执行eslint --init
之后会有很多选项可供选择:
1 | # 你希望如何使用eslint? |
配置文件初始化结束,就可以在项目根目录看到eslintrc.js
这样的配置文件:
1 | module.exports = { |
我们暂时不用管这个配置文件,再次使用eslint
来检测代码:
1 | npx eslint ./main.js |
然后我们发现命令行打印了这样的错误:
1 | D:\Test\eslint-test\main.js |
这是语法错误,因为consologe.log缺少)
导致,我们手动补充上,再次执行检测,发现错误变成了6个:
1 | D:\Test\eslint-test\main.js |
在语法错误的情况下,这些错误没有检测出来,语法错误修正后,剩下的错误就是问题代码和代码风格错误。
对于代码风格问题,我们可以使用--fix
的扩展命令进行修复,修复之后,还有两个报错:
1 | D:\Test\eslint-test\main.js |
而身下的这两个就是问题代码提示了,no-unused-vars
是提示我们name
这个变量定义了却未使用,而no-undef
是提示run
这个变量未定义。
eslint主要进行三方面的检测:
- 语法检测。会阻断其他类型的检测。需要手动修复
- 问题代码检测。需要手动修复。
- 代码风格检测。使用
--fix
命令进行自动修正。
关于命令行的更多使用请参考:命令行选项。
配置文件
虽然我们使用eslint --init
进行了配置文件初始化,但有时候我们有一些自定义的需求,就需要重新修改配置文件。
环境 - env
一个环境定义了一组预定义的全局变量。可用的环境包括:
browser
- 浏览器环境中的全局变量。node
- Node.js 全局变量和 Node.js 作用域。commonjs
- CommonJS 全局变量和 CommonJS 作用域 (用于 Browserify/WebPack 打包的只在浏览器中运行的代码)。shared-node-browser
- Node.js 和 Browser 通用全局变量。es6
- 启用除了 modules 以外的所有 ECMAScript 6 特性(该选项会自动设置ecmaVersion
解析器选项为 6)。worker
- Web Workers 全局变量。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
- Java 8 Nashorn 全局变量。serviceworker
- Service Worker 全局变量。atomtest
- Atom 测试全局变量。embertest
- Ember 测试全局变量。webextensions
- WebExtensions 全局变量。greasemonkey
- GreaseMonkey 全局变量。
这些环境并不是互斥的,所以你可以同时定义多个。
可以在源文件里、在配置文件中或使用 命令行 的 --env
选项来指定环境。
1 | { |
全局变量globals
要在配置文件中配置全局变量,请将 globals
配置属性设置为一个对象,该对象包含以你希望使用的每个全局变量。
1 | { |
- writable:允许重写变量。
- readonly:只读变量。
解析器选项 - parserOptions
ESLint 允许你指定你想要支持的 JavaScript 语言选项。默认情况下,ESLint 支持 ECMAScript 5 语法。你可以覆盖该设置,以启用对 ECMAScript 其它版本和 JSX 的支持。
注意,支持 ES6 语法并不意味着同时支持新的 ES6 全局变量或类型(比如 Set
等新类型)。对于 ES6 语法,使用 { "parserOptions": { "ecmaVersion": 6 } }
;对于新的 ES6 全局变量,使用 { "env":{ "es6": true } }
. { "env": { "es6": true } }
自动启用es6语法,但 { "parserOptions": { "ecmaVersion": 6 } }
不自动启用es6全局变量。
解析器选项可以在 .eslintrc.*
文件使用 parserOptions
属性设置。可用的选项有:
ecmaVersion
- 默认设置为 3,5(默认), 你可以使用 6、7、8、9 或 10 来指定你想要使用的 ECMAScript 版本。你也可以用使用年份命名的版本号指定为 2015(同 6),2016(同 7),或 2017(同 8)或 2018(同 9)或 2019 (same as 10)sourceType
- 设置为"script"
(默认) 或"module"
(如果你的代码是 ECMAScript 模块)。ecmaFeatures
- 这是个对象,表示你想使用的额外的语言特性:globalReturn
- 允许在全局作用域下使用return
语句impliedStrict
- 启用全局 strict mode (如果ecmaVersion
是 5 或更高)jsx
- 启用 JSXexperimentalObjectRestSpread
- 启用实验性的 object rest/spread properties 支持。(重要:这是一个实验性的功能,在未来可能会有明显改变。 建议你写的规则 不要 依赖该功能,除非当它发生改变时你愿意承担维护成本。)
1 | { |
扩展配置extends
一个配置文件可以被基础配置中的已启用的规则继承。
extends
属性值可以是:
- 指定配置的字符串(配置文件的路径、可共享配置的名称、
eslint:recommended
或eslint:all
) - 字符串数组:每个配置继承它前面的配置
检测规则rules
ESLint 附带有大量的规则。你可以使用注释或配置文件修改你项目中要使用的规则。要改变一个规则设置,你必须将规则 ID 设置为下列值之一:
"off"
或0
- 关闭规则"warn"
或1
- 开启规则,使用警告级别的错误:warn
(不会导致程序退出)"error"
或2
- 开启规则,使用错误级别的错误:error
(当被触发的时候,程序会退出)
规则配置比较多,可参考别的文件是怎么配置的。
插件 -plugins
完全插件化正是eslint
的设计初衷,所以插件的使用也是很简单的。在配置文件里配置插件时,可以使用 plugins
关键字来存放插件名字的列表。插件名称可以省略 eslint-plugin-
前缀。
1 | { |
配置注释Configuration Comments
除了使用配置文件,eslint
还支持使用配置注释的方式把规则来嵌入源码中。
为了在文件注释里配置规则,使用以下格式的注释,在下面这个例子里,eqeqeq
规则被关闭,curly
规则被打开,定义为错误级别
1 | /* eslint eqeqeq: "off", curly: "error" */ |
如果一个规则有额外的选项,你可以使用数组字面量指定它们,比如:
1 | /* eslint quotes: ["error", "double"], curly: 2 */ |
更多配置文件的修改项请参考:ESLint - 配置文件。
结合自动化工具的使用
比如结合gulp
的使用,我们只需要安装gulp-eslint这个插件即可。
gulp是管道流的操作模式,我们只需要在编译js
之前进行eslint检测即可:
1 | const {src, task} = require('gulp'); |
结合webpack的使用
在webpack中也是一样的逻辑,我们可以安装eslint的loader,也可以使用eslint的插件。
值得注意的是,
eslint-loader
目前已弃用,作者推荐使用eslint-webpack-plugion
来代替。
安装:
1 | npm install eslint-webpack-plugin --save-dev |
配置:
1 | const ESLintPlugin = require('eslint-webpack-plugin'); |
更多使用细节请参考:webpack-eslint-plugin。