本文作者:IMWeb Terrance 原文出处:IMWeb社区 未经同意,禁止转载 In computer programming, lint was the name originally given to a particular program that flagged some suspicious and non-portable constructs (likely to be bugs) in C language source code. The term is now applied generically to tools that flag suspicious usage in software written in any computer language.
代码检查很重要,原因有三:
通常,代码编辑器(或IDE)的插件会帮我们做一些静态语法检查的工作,但是如何自定义语法规则,如何集成到开发流程中,仍然需要我们花一些时间去了解。
这里主要针对前端领域的js、css代码静态分析来进行总结。
In order to help people write standard-compliant code from the start and avoid wasting time during code reviews, a set of ESLint configuration files have been added to the code base so that JavaScript can be analyzed automatically.This automatic linting can happen either while coding, in a code editor, or when using the command line.
提到ESLint,你大概会想到JSLint、JSHint或者JSCS,那么他们有什么区别呢?
使用方法如下:
eslint foo.js
foo.js
0:0 warning File ignored because of your .eslintignore file. Use --no-ignore to override.
✖ 1 problem (0 errors, 1 warning)
因为ESlint被实现为一个npm包,我们可以选择局部或全局方式进行安装。
安装之后,可以执行eslint --init来生成一个默认的配置文件.eslintrc
注意:如果ESlint使用到了相关插件和共享配置文件,也必须安装在本地。
包括之前提到的.eslintrc文件,ESlint共支持6种格式的配置文件,其使用的优先级和说明如下:
1.parserOptions
我们可以在这里开启对JSX语法的支持,但请注意这并不代表支持React语法,在React项目中应该使用eslint-plugin-react插件。
"parserOptions": {
"ecmaVersion": 6, // ES6,等同于2015
"sourceType": "module", // 使用ES的模块机制,而不是nodejs的
"ecmaFeatures": { // 拓展语言特性
"jsx": true //支持JSX语法
}
}
2.parser
常用的解析器有espree、Babel-ESLint、esprima。
3.env
支持25种运行环境,每一个环境都定义了一套预置全局对象,不同的环境可以组合使用。
3.globals
定义一组全局对象,可以制定其是否可写(默认true),注意需要开启no-global-assign规则来使false值生效。
4.plugins
每一个ESlint插件都是一个npm包,命名以“eslint-plugin-”开头,如eslint-plugin-react
或@jquery/eslint-plugin-jquery
,插件中可以定义Rules、Env、Configs和Testing等。如果要创建一个plugin,推荐使用Yeoman的generator-eslint
5.extends
扩展的使用方式主要有如下几种:
6.rules
对每条rule的错误处理,分为三种off/0
、warn/1
、error/2
ESLint将Rule分为以下几类:
配置文件中rules的写法是<规则名称>:<处理级别>,<传入参数>,举个栗子:
"rules": {
// enable additional rules
"indent": ["error", 4],
"linebreak-style": ["error", "unix"],
"quotes": ["error", "double"],
"semi": ["error", "always"],
// override default options for rules from base configurations
"comma-dangle": ["error", "always"],
"no-cond-assign": ["error", "always"],
// disable rules from base configurations
"no-console": "off",
}
具体可参考规则文档
7.settings
考虑到不同的rule可能会存在一些公共部分,我们可以在这里进行集中定义,便于后期维护,举个栗子:
"settings": {
"sharedData": "Hello"
}
8.overrides
在这里,我们可以使用glob规则来定义哪些文件(不)需要使用eslint来进行静态代码分析,另外几乎所有的配置项都可以在这里定义,并且拥有最高优先级。
"overrides": [
{
"files": [ "bin/*.js", "lib/*.js" ],
"excludedFiles": "*.test.js",
"rules": {
"quotes": [ 2, "single" ]
}
}
]
9.root
定义配置文件所在目录是否为根目录,Boolean类型,如果为true,则不再使用上层中的ESLint配置文件,举个栗子:
home
└── user
├── .eslintrc <- Always skipped if other configs present
└── projectA
├── .eslintrc <- Not used
└── lib
├── .eslintrc <- { "root": true }
└── main.js
放置位置同.eslintrc文件,定义了哪些文件需要忽略,取消忽略某个文件在前面添加!另外也可以直接在package.json中的eslintIgnore属性中进行配置。
除了可以在配置文件中定义规则,还可以在代码中添加注释的方式进行灵活的规则变更,直接看栗子吧:
/* eslint-env node, mocha */
/* global var1:false, var2:false */
/* eslint quotes: ["error", "double"], plugin1/rule1: 2 */
/* eslint-disable */
alert('foo');
/* eslint-enable */
/* eslint-disable no-alert, no-console */
alert('foo');
console.log('bar');
/* eslint-enable no-alert, no-console */
alert('foo'); // eslint-disable-line
// eslint-disable-next-line
alert('foo');
alert('foo'); // eslint-disable-line no-alert, quotes, plugin1/rule1
// eslint-disable-next-line no-alert, quotes, plugin1/rule1
alert('foo');
常用的命令行如下:
// 指定配置文件
eslint --config ~/my-eslint.json file.js
// 关闭配置文件
eslint --no-eslintrc file.js
// 指定运行环境
eslint --env browser,node file.js
// 指定需要进行代码检查的文件后缀
eslint . --ext .js --ext .JSX
// 定义全局变量
eslint --global require,exports:true file.js
// 将stdin作为代码源,指定解析器
echo '3 ** 4' | eslint --stdin --parser-options=ecmaVersion:7
// 使用缓存,指定缓存文件位置
eslint "src/**/*.js" --cache --cache-location "/Users/user/.eslintcache/"
// 指定插件
eslint --plugin eslint-plugin-mocha file.js
// 关闭warning输出
eslint --quiet file.js
// 指定报告输出文件
eslint --output-file ./test/test.html
//修复部分问题
eslint --fix
优先级:注释配置 > 命令行配置 > 文件配置
sass声称是世界上最成熟、稳定和强大的专业级CSS扩展语言,随着其语法规则的丰富,书写sass出错的概率也会随之增大,下面针对sass的代码检查工具——SassLint进行介绍。
SassLint同样被实现为一个npm包,我们可以选择局部或全局方式进行安装。
1.Options
2.Files
使用glob规则定义哪些文件需要进行代码检查,举个栗子:
files:
include: 'sass/**/*.s+(a|c)ss'
ignore:
- 'sass/vendor/**/*.scss'
- 'sass/tests/**/*.scss
3.Rules 对每条rule的错误处理,同样分为三种off/0
、warn/1
、error/2
,格式如下:
rules:
indentation:
- 2
-
size: 2
和ESLint差不多,直接看栗子吧:
// sass-lint:disable border-zero
p {
// sass-lint:disable-block border-zero
border: none;
content: "hello"; // sass-lint:disable-line quotes
}
// sass-lint:enable border-zero
// sass-lint:disable-all
a {
border: none; // Failing result reported
}
// sass-lint:enable-all
这里唯一需要特别注意的两个地方是:
sass-lint --config app/config/.sass-lint.yml '**/*.scss' --verbose --no-exit --ignore 'tests/**/*.scss, dist/other.scss'
1.如何在一个项目中引入一套ESLint或SassLint?
首先可以多了解一些被共享出来的成熟ESLint或SassLint标准、插件包等,根据团队或着自己的需要进行一定的修改,如果规则或应用场景比较复杂,可以考虑另外开发插件包。
2.如何平衡文件配置和注释配置?
文件配置往往是团队共同商讨制定出来的,凝聚了大多数人的智慧,所以原则上应该遵守这些规则,尽量不要在代码中添加注释配置。当这些规则无法满足当前的代码需要时,可以使用注释配置进行局部修改,但禁止对整个文件进行忽略。在问题积累得比较多的时候,可以在团队中提出来,集中修改插件或配置文件。
3.如何保证提交到版本库中的代码都通过了静态代码分析?
如果使用Git,那么Git Hook会是一个非常好的选择,可以定义在执行commit、push等操作的时候执行一些lint检查,如果存在error则禁止代码提交或上传。(不过个人仍然可以显示地用--no-verify来跳过检查)