前言:为什么需要代码规范
代码规范的意义
在ECMAScript之中,所有的代码都是由语句来构成的。语句表明执行过程中的流程、限定与约定,形式上可以是单行语句或一对大扩后{}
扩起来的复合语句,在语法描述中,复合语句整体可以作为一个单行语句处理。
JavaScript代码规范校验工具
1、种类介绍
JavaScript之中提供有如下几种代码规范校验工具
- JSLint:古老,不可配置,不可扩展,不可禁用许多特性的校验
- JSHint:可配置的JSLint的版本;
- JSCS:代码样式检查,只捕获与代码格式相关的问题,而不是潜在的bug或错误,已经和ESLint合并
- ESLint:易于扩展、可自定义规则,可以插件形式安装更多的规则;
2、JSLint——检测JavaScript语法规范
2.1、JSLint 简介与安装
在前端JavaScript之中有一个不错的工具叫做JSLint,可以检测代码规范化、压缩JS、CSS等,也是一款JavaScript验证工具,在定位错误并确保基本指南得以遵循时,非常有用,它还可以帮助我们避免许多种bug,极大缩短了开发时间。
如果你安装了NodeJS,可以使用如下的方式来安装JSLint。
npm install -g jslint
使用JSLintjslint spa.js
或使用Grunt或Gulp来在命令行中直接运行,在package.json
中添加
"devDependencies": {
"gulp-jslint": "*",
"gulp": "^3.6.2"
}
定义JSLint任务
var
jslint = require('gulp-jslint'),
gulp = require('gulp');
gulp.task('jslint', function () {
return gulp.src([
'./controllers/*.js',
'./models/*.js',
'./*.js'
]).pipe(jslint({
node: true,
nomen: true,
sloppy: true,
plusplus: true,
unparam: true,
stupid: true
}));
});
gulp.task('default', ['jslint']);
JSLint的特点
- 对代码的规则要求比较严格
- 可配置的选项很少
2.2、JSLint规范内容
- 必须使用分号作为语句结尾
- 函数必须使用
"use strict"
严格模式来定义,并且)
与{
之间必须有空格,函数的声明不能放在类似if的块中,需要放在外部函数的顶部。 - 在
-
、+
、=
、*
、\
后面要出现空格 - 不能使用tab和空格混用
- 行末不能有多余的空格
- 字符串要使用双引号
- 变量不能被重复定义
- 使用
===
来代替==
- 请删除
debugger
语句 - 在
case
或break
之前需要break
- 尽量不要使用
eval()
3、JSHint规范
3.1、JSHint简介
JSLint的语法要求严格,于是很多人就觉得没有必要这么严格,后来就在JSLint的基础之上,构建来一个新的代码检查工具JSHint。
JSHint的优点如下:
- 可配置规则
- 社区支持度高
- 可定制结果报表
3.2、JSHint的配置分类
- Enforcing(增强):如果这些属性设置为true,JSHint会对代码进行严格对检测,比如是否使用来严格模式、变量驼峰式命名、是不是for-in循环里面必须有hashOwnProperty等等。
- Relaxing(松弛):如果这些属性设置为true,JSHint会容忍规则中定义等情况出现,比如是否使用分号,是否支持下一代ES语法等等;
- Environments(环境):如果这些属性设置为true,代表代码所处的环境;
- globals(全局变量):自定义的一些全局变量
3.3、增强
bitwise 禁用位运算符
camelcase 使用驼峰命名(camelCase)或全大写下划线命名(UPPER_CASE)
curly 在条件或循环语句中使用{}来明确代码块
eqeqeq 使用===和!==替代==和!=
es3 强制使用ECMAScript 3规范
es5 强制使用ECMAScript 5规范
forin 在for in循环中使用Object.prototype.hasOwnProperty()来过滤原型链中的属性
freeze 禁止复写原生对象(如Array, Date)的原型
immed 匿名函数调用必须(function() {}());而不是(function() {})();
indent 代码缩进宽度
latedef 变量定义前禁止使用
newcap 构造函数名首字母必须大写
noarg 禁止使用arguments.caller和arguments.callee
noempty 禁止出现空的代码块
nonew 禁止使用构造器
plusplus 禁止使用++和–-
quotemark 统一使用单引号或双引号
undef 禁止使用不在全局变量列表中的未定义的变量
unused 禁止定义变量却不使用
strict 强制使用ES5的严格模式
trailing 禁止行尾空格
maxparams 函数可以接受的最大参数数量
maxdepth 代码块中可以嵌入{}的最大深度
maxstatement 函数中最大语句数
maxcomplexity 函数的最大圈复杂度
maxlen 一行中最大字符数
3.4、松弛
asi 允许省略分号
boss 允许在if,for,while语句中使用赋值
debug 允许debugger语句
eqnull 允许==null
esnext 允许使用ECMAScript 6
evil 允许使用eval
expr 允许应该出现赋值或函数调用的地方使用表达式
funcscope 允许在控制体内定义变量而在外部使用
globalstrict 允许全局严格模式
iterator 允许__iterator__
lastsemic 允许单行控制块省略分号
laxbreak 允许不安全的行中断
laxcomma 允许逗号开头的编码样式
loopfunc 允许循环中定义函数
maxerr JSHint中断扫描前允许的最大错误数
multistr 允许多行字符串
notypeof 允许非法的typeof操作
proto 允许 proto
smarttabs 允许混合tab和space排版
shadow 允许变量shadow
sub 允许使用person[‘name’]
supernew 允许使用new function() {…}和new Object
validthis 允许严格模式下在非构造函数中使用this
noyield 允许发生器中没有yield语句
3.5、环境
browser Web Browser (window, document, etc)
browserify Browserify (node.js code in the browser)
jquery jQuery
node Node.js
qunit QUnit
typed Globals for typed array constructions
worker Web Workers
wsh Windows Scripting Host
3.6、全局变量
globals: {
jQuery: true,
console: true,
module: true
}
4、ESLint——检测ECMAScript语法规范(重点掌握)
1、ESLint的哲学
- 在ESLint中,一切都是可插拔的,规则之间相互独立;
- 每条规则非零则为开启,零为关闭;
- ESLint不倾向于任何一种代码风格,默认关闭所有设定,被捆绑的规则都是具有普遍性的
2、如何使用
- 直接使用npm来安装使用
npm install -g eslint
eslint -init
执行之后,会询问你几个问题,然后生成一个.eslintrc文件
问题如下:
what style of indentation do you use ? Spaces
what quotes do you use for strings?Double
What line endings do you use?Unix
Do you require semicolons?No
Are you using ECMAScript 6 features?Yes
Whree wile your code run? Node?Browser?
检测文件使用如下方式
eslint xxx.js
- 使用gulp-eslint方式
1、安装gulp-eslint
npm install gulp-eslint
2、在gulpfile.js中调用eslint;
const {src, task} = require('gulp');
const eslint = require('gulp-eslint');
task('default', () => {
return src(['scripts/*.js'])
// eslint() attaches the lint output to the "eslint" property
// of the file object so it can be used by other modules.
.pipe(eslint())
// eslint.format() outputs the lint results to the console.
// Alternatively use eslint.formatEach() (see Docs).
.pipe(eslint.format())
// To have the process exit with an error code (1) on
// lint error, return the stream and pipe to failAfterError last.
.pipe(eslint.failAfterError());
});
// 或者
gulp.src(['**/*.js','!node_modules/**'])
.pipe(eslint({
rules: {
'my-custom-rule': 1,
'strict': 2
},
globals: [
'jQuery',
'$'
],
envs: [
'browser'
]
}))
.pipe(eslint.formatEach('compact', process.stderr));
ESLint的配置
ESLint的配置都写在 .eslintrc
文件之中
1、指定环境
1.1、指定语言,比如支持ES6语法和JSX:ecmaFeatures
属性
1.2、指定解析器:parser
属性
所有都解析器都是npm
包,默认使用都Espree
,官方推荐都有 Esprima
,Esprima-FB
,Babel-ESLint
;Babel-ESLint
可以自动支持ES6,不需要专门写env:{es6:true}
由于Babel-ESLint
会把代码先变成ES6,所以不在ES5里都属性依然需要在ecmaFeatures
属性设置一下
1.3、指定环境
可以写在env
属性里,也可以写在需要支持都特定文件里面;
1.4、自定义插件
写在 .eslintrc
文件之中的plugin
属性里,第三方插件使用之前要先安装,默认插件不需要安装;
2、指定全局变量
写在 .eslintrc
文件之中的global
属性里面,防止被no-undef报错
3、指定规则
3.1、规则的值
有规则除了值,还可以有更多都定制;
3.2、想要配置某个插件自己的规则
{
"plugins": [
"plugin1"
],
"rules": {
"eqeqeq": 0,
"curly": 2,
"quotes": [2, "double"],
"plugin1/rule1": 2
}
}
4、关于配置文件
4.1、配置好后如何使用
方法一:使用命令行
eslint -c myconfig.json mytest.js
方法二:通过.eslintrc
和package,json
文件
需要lint的文件夹中,eslint会找这两个文件,然后逐级向上级目录寻找,直到项目根目录为止;
4.2、配置文件的层叠和等级
先用根文件夹的 .eslintrc
或 package.json
里的 eslintConfig
,再用内部的.eslintrc
和被检查文件夹越靠近的配置,优先级越高;同层级中,.eslintrc
优先级比 package.json
高
4.3、eslint是如何找到.eslintrc
?
默认情况下,eslint 会在所有父级文件夹中寻找配置文件,一直找到根目录为止。
如果希望 eslint 不要继续往外寻找配置文件了则这样配置:"root": true
4.4、配置文件的优先级
4.5、配置文件可以扩展
写在 .eslintrc
文件的 extends
属性里
可以是文件路径,能达到类似模块化的效果。比如一些基础设置可以写在扩展文件里;extends
的值也可以是数组,里面是多个 .eslintrc
文件路径;
还可以把 .eslintrc
做成 npm
包,给基友们共享
扩展文件里也可以写扩展(会被 eslint
递归调用)
4.6、怎么在配置里写注释package.json
不能写注释.eslintrc
中,根据情况可以写 js 或 yaml 风格的注释
4.7、忽略检查的文件和目录
写在根目录下,.eslintignore
文件里,格式为纯文本
ESLint 运行前会先检查.eslintignore
只看第一个全局变量用 minimatch
匹配
4.8、具体的规则,我这里就不过多的描述了
相关参考资料如下
https://eslint.org/docs/user-guide/getting-started
https://github.com/adametry/gulp-eslint