起初 JavaScript 被开发出来的目的只是用在 Web 页面里实现一些简单的交互(例如表单提交)。随着互联网发展,网站需要展示的内容更加丰富,交互也变得复杂,前端项目也越来越庞大;2009 年,NodeJS 的诞生使得 JavaScript 可以跑在服务端,更是让其地位更加突出。在 2017 年 GitHub 开发语言排行榜中,JavaScript 毫无疑问排在第一位
再加上 JavaScript 本身设计上存在许多缺陷,代码不严谨也可能就会触发神奇的错误。例如 == 和 === 的混用,可能会产生类型不一致引起的 Bug,经验不足的开发者很难察觉出异常。
2002 年,Douglas Crockford (译注:《JavaScript 语言精粹》的作者)开发了可能是第一款针对 JavaScript 的语法检测工具 —— JSLint,并于 2010 年开源。
JSLint 面市后,确实帮助许多 JavaScript 开发者节省了不少排查代码错误的时间。但是 JSLint 的问题也很明显——几乎不可配置,所有的代码风格和规则都是内置好的;再加上 Douglas Crockford 老爷子推崇道系「爱用不用」的优良传统,不会向开发者妥协开放配置或者修改他觉得是对的规则。于是 Anton Kovalyov 吐槽:「JSLint 是让你的代码风格更像 Douglas Crockford 的而已,并且在 2011 年 Fork 原项目开发了 JSHint。
JSHint 的特点就是可配置,同时文档也相对完善,而且对开发者友好。很快大家就从 JSLint 转向了 JSHint。
起初几年,JSHint 一直是前端代码检测工具的首选,包括 Nicholas C. Zakas (《JavaScript高级程序设计》作者)也是 JSHint 的用户。但在 2013 年,Zakas 大佬发现 JSHint 已经无法满足自己定制化规则的需求,而且和 Anton 讨论后达成共识这根本在不可能在 JSHint 上实现。同时 Zakas 还设想发明一个基于 AST 的 lint,可以动态执行额外的规则,同时可以很方便的扩展规则。
2013 年的 6 月份,Zakas 发布了全新的 lint 工具——ESLint
几乎同一时间,另一款和 ESLint 实现机制类似的代码风格检测工具——JSCS——也诞生了
ESLint 的出现并没有撼动 JSHint 的霸主地位。由于前者是利用 AST 处理规则,用 Esprima 解析代码,执行速度要比只需要一步搞定的 JSHint 慢很多;其次当时已经有许多编辑器对 JSHint 支持完善,生态足够强大。真正让 ESLint 逆袭的是 ECMAScript 6 的出现。
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 特有的规则。
2016 年,JSCS 开发团队认为 ESLint 和 JSCS 实现原理太过相似,而且需要解决的问题也都一致,最终选择合并到 ESLint,并停止 JSCS 的维护。
至此,ESLint 完美躺赢,替代 JSHint 成为前端主流工具。
参考文章
https://www.jianshu.com/p/933b6b6a84c9
npm安装
npm install eslint --save-dev
没有配置文件是没法进行检查的,我们要新建一个配置文件.eslintrc.js
module.exports = {
extends: 'eslint:recommended',
};
extends: 'eslint:recommended'
表示使用ESLint默认的配置,默认配置可以参考页面:https://cn.eslint.org/docs/rules/
我们新建一个用来测试的myfile.js
文件
let kk = 9
console.log(window)
console.log('kk', kk == -0)
console.log('bool', !!!kk)
// 前面是一个tab和两个空格
console.log('space tab')
运行检查命令
./node_modules/.bin/eslint myfile.js
运行结果:
1:5 error Parsing error: Unexpected token kk
报这个错是因为ESLint识别不了let
,ESLint默认的ECMA解析器的版本是5(可设置为3,5,6(2015),7(2016),8(2017)),我们需要配置ecmaVersion或者直接配置env即可,修改后的.eslintrc.js
module.exports = {
env: {
browser: true,
es6: true
},
extends: 'eslint:recommended'
};
一个环境定义了一组预定义的全局变量,es6
启用除了 modules 以外的所有 ECMAScript 6 特性,该选项会自动设置 ecmaVersion 解析器选项为 6。brower
让解析器就可以识别出window、console等浏览器才有的一些全局变量。详细的全局变量配置可见:https://cn.eslint.org/docs/user-guide/configuring#specifying-environments
再运行一次检查命令
./node_modules/.bin/eslint myfile.js
运行结果:
5:19 error Do not use the '==' operator to compare against -0 no-compare-neg-zero
7:22 error Redundant double negation no-extra-boolean-cast
10:1 error Mixed spaces and tabs no-mixed-spaces-and-tabs
可以通过修改配置文件,全局的修改检查规则
module.exports = {
env: {
browser: true,
es6: true
},
extends: 'eslint:recommended',
rules: {
"no-mixed-spaces-and-tabs": "off"
}
};
运行检查命令,结果为:
5:19 error Do not use the '==' operator to compare against -0 no-compare-neg-zero
7:22 error Redundant double negation no-extra-boolean-cast
可见no-mixed-spaces-and-tabs
检查已经没有了
有时候,在开发过程中,有些代码检查会导致代码编译不通过,导致项目无法启动。我们需要临时的屏蔽掉某些行的代码检查,我们可以通过注释的方式进行。在myfile.js
中,我们加上如下的注释
// eslint-disable-next-line
console.log('kk', kk == -0)
运行检查命令,结果为:
7:22 error Redundant double negation no-extra-boolean-cast
可见console.log('kk', kk == -0)
该行导致的no-compare-neg-zero
报错已经没有了
除此之外,ESLint还支持通过注释屏蔽某段代码甚至整个文件的代码检查,详细可见:https://cn.eslint.org/docs/user-guide/configuring#disabling-rules-with-inline-comments
跳过某个文件的检查,可以通过新建一个
.eslintignore
文件,在里面写上需要跳过检查的文件路径即可,类似.gitignore
文件。或者也可以在package.json
中增加一个数据类型为数组的eslintIgnore
字段,将需要跳过检查的文件路径写在里面
通过运行eslint --fix
命令,ESLint可以为我们自动修改代码来让我们的代码符合规则。但是并不是所有被检查出来的错误都可以被修复,在官网规则页面中,只有带有黄颜色扳手的检查项可以被自动修复。其中 no-extra-boolean-cast
是可以被自动修复的,我们试一下
执行命令:
./node_modules/.bin/eslint myfile.js --fix
可见js内容自动发生了变化
console.log('bool', !kk)
多余的!
被自动删除掉了
ESLint基础的包,提供了基础ESLint最基础的能力,必须安装
ESLint有默认的js解析器,它默认解析器和核心规则仅支持最新的最终ECMAScript标准,不支持Babel提供的实验性(例如新功能)和非标准(例如Flow或TypeScript类型)语法。
babel-eslint是允许ESLint在由Babel转换的源代码上运行的解析器。
注意:仅在使用Babel转换代码时才需要使用babel-eslint。(默认解析器支持所有非实验语法以及JSX,如果没有使用babel则不需要使用babel-eslint)。
举个例子
myfile.js
const a = 1
.eslintrc.js
module.exports = {
extends: 'eslint:recommended'
};
执行检查,检查结果:
1:1 error Parsing error: The keyword 'const' is reserved
现在我们通过npm安装上babel-eslint,在.eslintrc.js
中加上相关配置
module.exports = {
parser: "babel-eslint",
extends: 'eslint:recommended'
};
执行检查,检查结果:
1:7 error 'bb' is assigned a value but never used no-unused-vars
可见const已经通过了检查,只是bb
变量定义了没有使用报错(babel会将const转成var,从而通过检查)
该解析器使我们可以处理vue文件的和
。
如果在模板中使用复杂的指令和表达式,我们很容易犯错误。该解析器和
eslint-plugin-vue
规则配合会帮助我们检查出错误
举个例子
myfile.vue
<template>
<div class="my-class">div>
template>
<script>
export default {
data: {
title: 'fine'
}
}
script>
.eslintrc.js
module.exports = {
extends: 'eslint:recommended'
};
执行检查,检查结果:
1:1 error Parsing error: Unexpected token <
可见ESLint无法识别出.vue
文件里面的内容,这个时候我们就需要用到vue-eslint-parser
,我们先通过npm安装,然后修改.eslintrc.js
.eslintrc.js
module.exports = {
parser: "vue-eslint-parser",
extends: ['eslint:recommended']
};
执行检查,检查结果:
6:0 error Parsing error: The keyword 'export' is reserved
报错已经变了,可见ESLint已经识别出了和
标签,我们接着往下看
Vue.js的官方ESLint插件。
这个插件使我们可以使用ESLint 检查.vue文件的和
,配合
vue-eslint-parser
一起使用
还是接着上面的例子,我们通过npm安装eslint-plugin-vue
之后,修改.eslintrc.js文件代码如下:
module.exports = {
parser: "vue-eslint-parser",
extends: ['plugin:vue/recommended']
};
执行检查,检查结果:
2:3 warning Require self-closing on HTML elements () vue/html-self-closing
7:3 error `data` property in component must be a function vue/no-shared-component-data
可见现在ESLint已经可以对.vue
文件的
和
标签里面的vue语法和规范问题作出检查
如果在ESLint配置里通过ruls配置Vue校验规则不生效的话,尝试关闭Vetur的校验:vetur.validation.template: false
。Vetur官方文档有做介绍,不过笔者没有碰到这种情况,所以vetur.validation.template
这个配置笔者都是默认的true
,没做修改
2. vscode插件介绍
2.1 Vetur
没有安装任何插件的VSCode,打开.vue文件是没有任何高亮的,就像打开一个纯文本文档。Vetur可以为.vue文件提供语法高亮、代码片段、质量提示&错误、格式化/风格、智能提示等一些特性
2.2 Beautify
VSCode内部已经使用了js-beautify,但是它能修改的地方并不多,有些你想修改的样式偏好可能无法支持,Beautify插件解决了这个问题,能够按照项目.jsbeautifyrc
文件中配置的样式偏好格式化你的代码
由于Vetur插件已经内置了js-beautify,而且在设置中支持修改js-beautify的样式偏好设置,所以VSCode只要安装了Vetur插件就能很好的格式化
部分的代码
Beautify插件可以用来格式化html、js和css代码,一般我们用来格式化html文件,如果我们要用它来格式化代码,需要在项目根目录添加.jsbeautifyrc
配置文件
2.3 Prettier
Prettier是一个“有主见”的代码格式化程序。它通过分析代码并使用自己的规则重新打印它来强制使用一致的样式
它支持的文件类型有JavaScript、TypeScript、Flow、JSX、JSON、CSS 、SCSS、Less、
HTML、Vue、Angular、GraphQL、Markdown、YAML,我们一般用来格式化JavaScript、TypeScript和CSS代码
2.4 ESLint
ESLint插件可以让VSCode在你编码过程中,实时的通过黄颜色或者红颜色波浪线提醒你不符合ESLint配置的警告或者错误,并且在提示错误的同时,通过弹窗给你修复方案供你选择。使用该插件需要你本地或者全局安装了eslint包,并且在项目根目录下配置了.eslintrc.js
文件
ESLint插件会在你编辑代码过程中实时地根据.eslintrc.js
文件中配置的规则检测你的代码,并提醒warning和error
3. VSCode配置
VSCode的配置可以通过settings.json文件进行配置,VSCode提供了两种设置方式
- 用户设置: 这种方式进行的设置,会应用于该用户打开的所有工程,在系统对应的用户文件夹下的某个指定路径会创建一个settings.json配置文件,用于保存用户设置
- 工作空间设置:工作空间是指使用VSCode打开的某个文件夹,在该文件夹下会创建一个名为.vscode的隐藏文件夹,里面包含着仅适用于当前目录的settings.json配置文件,工作空间的设置会覆盖用户的设置
Vue开发项目的VSCode配置推荐:
{
// 保存文件时是否自动格式化
"editor.formatOnSave": true,
// 一个tab缩进所占的空格数
"editor.tabSize": 2,
// VSCode保存文件时的操作
"editor.codeActionsOnSave": {
// 保存文件时,是否自动修复ESLint提示的可自动修复的问题
"source.fixAll.eslint": true
},
// vue文件中区域用的内部formatter名称
"vetur.format.defaultFormatter.html": "js-beautify-html",
// 所有内部默认fomatter的配置
"vetur.format.defaultFormatterOptions": {
"prettier": {
// 每行的字符个数,超过就自动换行
"printWidth": 1000,
// 是否在某些情况下换行:不换行
"proseWrap": "never",
// 是否使用单引号代替双引号
"singleQuote": true,
// 如果对象中有一个属性被单引号括起来,则所有的属性都用单引号括起来
"prettier.quoteProps": "consistent",
// 句末尾是否增加分号
"semi": false
},
"js-beautify-html": {
// 每行的字符个数,超过就自动换行
"wrap_line_length": 160,
// 一个缩进tab所占的空格数
"indent_size": 2,
// 属性的换行规则:每个属性都强制换行
"wrap_attributes": "force-expand-multiline"
}
},
// 句末尾是否增加分号
"prettier.semi": false,
// 是否在jsx中使用单引号代替双引号
"prettier.jsxSingleQuote": true,
// 是否使用单引号代替双引号
"prettier.singleQuote": true,
// 如果对象中有一个属性被单引号括起来,则所有的属性都用单引号括起来
"prettier.quoteProps": "consistent",
// 要禁用prettier插件的语言列表
"prettier.disableLanguages":[
"vue"
]
}