前言:为什么需要代码规范

代码规范的意义

在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

使用JSLint
jslint 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规范内容

  1. 必须使用分号作为语句结尾
  2. 函数必须使用"use strict"严格模式来定义,并且){之间必须有空格,函数的声明不能放在类似if的块中,需要放在外部函数的顶部。
  3. -+=*\后面要出现空格
  4. 不能使用tab和空格混用
  5. 行末不能有多余的空格
  6. 字符串要使用双引号
  7. 变量不能被重复定义
  8. 使用===来代替==
  9. 请删除debugger语句
  10. casebreak之前需要break
  11. 尽量不要使用eval()

3、JSHint规范

3.1、JSHint简介

JSLint的语法要求严格,于是很多人就觉得没有必要这么严格,后来就在JSLint的基础之上,构建来一个新的代码检查工具JSHint。

JSHint的优点如下:

  • 可配置规则
  • 社区支持度高
  • 可定制结果报表

3.2、JSHint的配置分类

  1. Enforcing(增强):如果这些属性设置为true,JSHint会对代码进行严格对检测,比如是否使用来严格模式、变量驼峰式命名、是不是for-in循环里面必须有hashOwnProperty等等。
  2. Relaxing(松弛):如果这些属性设置为true,JSHint会容忍规则中定义等情况出现,比如是否使用分号,是否支持下一代ES语法等等;
  3. Environments(环境):如果这些属性设置为true,代表代码所处的环境;
  4. 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、如何使用

  1. 直接使用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
  1. 使用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,官方推荐都有 EsprimaEsprima-FBBabel-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

方法二:通过.eslintrcpackage,json文件
需要lint的文件夹中,eslint会找这两个文件,然后逐级向上级目录寻找,直到项目根目录为止;

4.2、配置文件的层叠和等级
先用根文件夹的 .eslintrcpackage.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

10-05 13:31