ESlint 简介

ESlint 简介

1.什么是ESlint?

ESLint最初是由Nicholas C. Zakas 于2013年6月创建的开源项目。它的目标是提供一个插件化的javascript代码检测工具。

安装使用

你可以使用 npm 安装 ESLint:

$ npm install eslint --save-dev

紧接着你应该设置一个配置文件:

$ ./node_modules/.bin/eslint --init

之后,你可以在任何文件或目录上运行ESLint如下:

$ ./node_modules/.bin/eslint yourfile.js

也可以在全局而不是本地安装 ESLint (使用 npm install eslint --global)。但是,你使用的任何插件或可共享配置都必须安装在本地。

Configuration

注意:如果你之前使用的版本低于 1.0.0,请查看 迁移指南。

运行 eslint --init 之后,.eslintrc 文件会在你的文件夹中自动创建。你可以在 .eslintrc 文件中看到许多像这样的规则:

`{
    "rules": {
        "semi": ["error", "always"],
        "quotes": ["error", "double"]
    }
}`

“semi” 和 “quotes” 是 ESLint 中 规则 的名称。第一个值是错误级别,可以使下面的值之一:

“off” or 0 - 关闭规则
“warn” or 1 - 将规则视为一个警告(不会影响退出码)
“error” or 2 - 将规则视为一个错误 (退出码为1)
这三个错误级别可以允许你细粒度的控制 ESLint 是如何应用规则(更多关于配置选项和细节的问题,请查看配置文件)

你的 .eslintrc 配置文件可以包含下面的一行:

    "extends": "eslint:recommended"

由于这行,所有在 规则页面 被标记为 “” 的规则将会默认开启。另外,你可以在 npmjs.com 搜索 “eslint-config” 使用别人创建好的配置。只有在你的配置文件中扩展了一个可分享的配置或者明确开启一个规则,ESLint 才会去校验你的代码。

Next Steps

  • 学习 ESLint 的高级配置。
  • 熟悉 命令行选项。
  • 探索将 ESLint 集成 到其它工具,比如 编辑器,构建工具等等。
  • 没有找到适合的规则?创建自定义规则。
  • 通过 贡献代码 让 ESLint 变得更好。

学习 ESLint 的高级配置。
熟悉 命令行选项。
探索将 ESLint 集成 到其它工具,比如 编辑器,构建工具等等。
没有找到适合的规则?创建自定义规则。
通过 贡献代码 让 ESLint 变得更好。

一、JSLint JSHint ESLint

C 语言诞生之初,程序员编写的代码风格各异,在移植时会出现一些因为不严谨的代码段导致无法被编译器执行的问题。于是在 1979 年,一款叫 lint[1] 的程序被开发出来,能够通过扫描源代码检测潜在的错误。此后 lint 的功能不断完善,类似的工具相继出现。不仅可以检测代码中的潜在 Bug,还能做一些类型检查。

1、JavaScript 为什么需要 lint

起初 JavaScript 被开发出来的目的只是用在 Web 页面里实现一些简单的交互(例如表单提交)。随着互联网发展,网站需要展示的内容更加丰富,交互也变得复杂,前端项目也越来越庞大;2009 年,NodeJS 的诞生使得 JavaScript 可以跑在服务端,更是让其地位更加突出。在 2017 年 GitHub 开发语言排行榜中,JavaScript 毫无疑问排在第一位。[2]

再加上 JavaScript 本身设计上存在许多缺陷[3],代码不严谨也可能就会触发神奇的错误。例如 == 和 === 的混用,可能会产生类型不一致引起的 Bug,经验不足的开发者很难察觉出异常。

2002 年,Douglas Crockford (译注:《JavaScript 语言精粹》的作者)开发了可能是第一款针对 JavaScript 的语法检测工具 —— JSLint[4],并于 2010 年开源。

2、JSLint 和 JSHint

JSLint 面市后,确实帮助许多 JavaScript 开发者节省了不少排查代码错误的时间。但是 JSLint 的问题也很明显——几乎不可配置,所有的代码风格和规则都是内置好的;再加上 Douglas Crockford 老爷子推崇道系「爱用不用」的优良传统,不会向开发者妥协开放配置或者修改他觉得是对的规则。于是 Anton Kovalyov 吐槽:「JSLint 是让你的代码风格更像 Douglas Crockford 的而已」[5],并且在 2011 年 Fork 原项目开发了 JSHint。

JSHint 的特点就是可配置,同时文档也相对完善,而且对开发者友好。很快大家就从 JSLint 转向了 JSHint

3、ESLint 的诞生

起初几年,JSHint 一直是前端代码检测工具的首选,包括 Nicholas C. Zakas (《JavaScript高级程序设计》作者)也是 JSHint 的用户。但在 2013 年,Zakas 大佬发现 JSHint 已经无法满足自己定制化规则的需求,而且和 Anton 讨论后达成共识这根本在不可能在 JSHint 上实现。同时 Zakas 还设想发明一个基于 AST 的 lint,可以动态执行额外的规则,同时可以很方便的扩展规则。[6]

2013 年的 6 月份,Zakas 发布了全新的 lint 工具——ESLint[7]。

几乎同一时间,另一款和 ESLint 实现机制类似的代码风格检测工具——JSCS[8]——也诞生了。

4、可扩展性的胜利

ESLint 的出现并没有撼动 JSHint 的霸主地位。由于前者是利用 AST 处理规则,用 Esprima 解析代码,执行速度要比只需要一步搞定的 JSHint 慢很多;其次当时已经有许多编辑器对 JSHint 支持完善,生态足够强大。真正让 ESLint 逆袭的是 ECMAScript 6 的出现。

2015 年 6 月,ES2015 规范正式发布。但是发布后,市面上浏览器对最新标准的支持情况极其有限。如果想要提前体验最新标准的语法,就得靠 Babel 之类的工具将代码编译成 ES5 甚至更低的版本,同时一些实验性的特性也能靠 Babel 转换。这时 JSHint 就略尴尬,ES2015 变化很大,短期内无法完全支持。ESLint 可扩展的优势一下就体现出来了,不仅可以扩展规则,甚至连解析器也能替换。Babel 团队就为 ESLint 开发了 babel-eslint[9] 替换默认解析器,让 ESLint 率先支持 ES2015 语法。

也是在 2015 年,React 的应用越来越广泛,诞生不久的 JSX 也愈加流行。ESLint 本身也不支持 JSX 语法。还是因为可扩展性,eslint-plugin-react[10] 的出现让 ESLint 也能支持当时 React 特有的规则。

2016 年,JSCS 开发团队认为 ESLint 和 JSCS 实现原理太过相似,而且需要解决的问题也都一致,最终选择合并到 ESLint,并停止 JSCS 的维护。[11]

至此,ESLint 完美躺赢,替代 JSHint 成为前端主流工具。[12]

二、ESLint入门

1.安装

npm install -g eslint

2.准备一个js文件来测试一下

function merge () {
  var ret = {};
  for (var i in arguments) {
    var m = arguments[i];
    for (var j in m) ret[j] = m[j];
  }
  return ret;
}

console.log(merge({a: 123}, {b: 456}));

3.执行eslint merge.js
这时是没有输出结果的,原因是没有指定配置文件。现在添加一个.eslintrc.js,使用内置配置

module.exports = {
  extends: 'eslint:recommended',
};

重新执行eslint merge.js可以看到输出了 2 个错误:

/example/merge.js
  10:1  error  Unexpected console statement  no-console
  10:1  error  'console' is not defined      no-undef

✖ 2 problem (2 error, 0 warnings)

这两条提示信息还是足够我们搞清楚是怎么回事的:

  • Unexpected console statement no-console - 不能使用console
  • ‘console’ is not defined no-undef - console变量未定义,不能使用未定义的变量

针对第 1 条提示,我们可以禁用no-console规则。将配置文件.eslintrc.js改为这样:

  extends: 'eslint:recommended',
  rules: {
    'no-console': 'off',
  },
};

说明:配置规则写在rules对象里面,key表示规则名称,value表示规则的配置。每条规则有 3 个等级:off、warn和error。off表示禁用这条规则,warn表示仅给出警告,并不会导致检查不通过,而error则会导致检查不通过。可以参考规则说明文档

重新执行检查还是提示no-undef:

/example/merge.js
  10:1  error  'console' is not defined  no-undef

✖ 1 problem (1 error, 0 warnings)

✖ 1 problem (1 error, 0 warnings)
这是因为 JavaScript 有很多种运行环境,比如常见的有浏览器和 Node.js,另外还有很多软件系统使用 JavaScript 作为其脚本引擎,比如 PostgreSQL 就支持使用 JavaScript 来编写存储引擎,而这些运行环境可能并不存在console这个对象。另外在浏览器环境下会有window对象,而 Node.js 下没有;在 Node.js 下会有process对象,而浏览器环境下没有。

所以在配置文件中我们还需要指定程序的目标环境:

module.exports = {
  extends: 'eslint:recommended',
  env: {
    node: true,
  },
  rules: {
    'no-console': 'off',
  },
};

再重新执行检查时,已经没有任何提示输出了,说明merge.js已经完全通过了检查。

4.使用共享的配置文件
上文我们以eslint:recommended为基础配置,然后在此之上修改no-console这条规则。而在大多数时候,我们可能会根据自己个人或团队的习惯,定制更多的规则,比如限定缩进是 2 个空格和使用单引号的字符串等。而如果每一个项目都要这样写到.eslintrc.js文件上,管理起来会比较麻烦。

我们可以将定义好规则的.eslintrc.js文件存储到一个公共的位置,比如public-eslintrc.js:

module.exports = {
  extends: 'eslint:recommended',
  env: {
    node: true,
  },
  rules: {
    'no-console': 'off',
    'indent': [ 'error', 2 ],
    'quotes': [ 'error', 'single' ],
  },
};

然后将原来的.eslintrc.js文件改成这样:

module.exports = {
  extends: './public-eslintrc.js',
};

为了验证这样的修改是否生效,将merge.js中的var ret = {};这一行前面多加一个空格,再执行 ESLint 检查:

/example/merge.js
  2:4  error  Expected indentation of 2 space characters but found 3  indent

✖ 1 problem (1 error, 0 warnings)

这时候提示的是缩进只能为 2 个空格,而文件的第 2 行却发现了 3 个空格,说明公共配置文件public-eslintrc.js已经生效了。

5.代码格式化

为了让你对规则有个更好的理解,ESLint 对其进行了分门别类。
所有的规则默认都是禁用的。在配置文件中,使用 “extends”: “eslint:recommended” 来启用推荐的规则,报告一些常见的问题,在下文中这些推荐的规则都带有一个对勾标记。
命令行的 --fix 选项用来自动修复规则所报告的问题(目前,大部分是对空白的修复),在下文中会有一个扳手的图标。

使用上述配置,将merge.js中的var ret = {};这一行前面多加一个空格。然后执行eslint merge.js --fix,可以发现merge.js文件被修改了,新添加的空格被去除了。我们可以利用这个特性来自动格式化项目代码,这样就可以保证代码书写风格的统一。

5.例外情况
尽管我们在编码时怀着严格遵守规则的美好愿景,而凡事总有例外。定立 ESLint 规则的初衷是为了避免自己犯错,但是我们也要避免不顾实际情况而将其搞得太过于形式化,本末倒置。

ESLint 提供了多种临时禁用规则的方式,比如我们可以通过一条eslint-disable-next-line备注来使得下一行可以跳过检查:

// eslint-disable-next-line
var a = 123;
var b = 456;

在上面的示例代码中,var a = 123不会受到检查,而var b = 456则右恢复检查,在上文我们使用的eslint-config-lei的配置规则下,由于不允许使用var声明变量,则var b这一行会报告一个error。

我们还可以通过成对的eslint-enable和eslint-disable备注来禁用对某一段代码的检查,但是稍不小心少写了一个eslint-disable就可能会导致后面所有文件的检查都被禁用,所以我并不推荐使用。

详细使用方法可以参考文档:Disabling Rules with Inline Comments - 使用行内注释禁用规则

6.总结
刚开始接触 ESLint 时觉得太难,是因为过太过于迷信权威。比如 Airbnb 公司的 JavaScript 风格,在 GitHub 上受到了很大的好评,其实我自己也非常认可这样的编码风格。但每个团队都会根据自己的的实际情况来定制不同的东西,我们并不能随便照搬过来。所以当使用eslint-config-airbnb这个配置进行 ESLint 检查时,满屏都是error和warning,从而觉得这东西根本没啥卵用。

另外我也犯了「大忌」:直接使用eslint-config-airbnb这种某个公司高度定制化的配置,而不是eslint:recommended这样保守的。而且是直接用来检查整个项目好几十个 JS 文件,可想而知那是怎样的画面(本文最后版本的merge.js文件使用airbnb的配置,总共 12 行的代码就提示了 8 个问题:✖ 8 problems (7 errors, 1 warning))。

本文的目的是让读者以一个比较低的姿态开始接触 ESLint,先学会简单地配置规则,如果要更深入地定制自己的规则,建议阅读
规则说明文档
ESLint 规则详解(一)
ESLint 规则详解(二)

作者:合肥懒皮
链接:https://www.jianshu.com/p/933b6b6a84c9
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值