全栈开发技术分享
首页
👉 CSS大揭秘 👈
  • 目录
  • 分类
  • 标签
  • 归档
  • Vue
  • JavaScript
  • 微信开发
  • 移动端H5调试工具
  • 国内十大前端团队网站
  • Nodejs
  • Egg
  • 环境搭建
  • 运维面板
  • 域名配置
  • Nginx
  • 收藏
  • 常用工具
  • 实用技巧
  • 常用命令
  • 友情链接
关于

Dreaming Lee 🍍 ҉҉҉҉҉҉҉҉

开发小菜鸡
首页
👉 CSS大揭秘 👈
  • 目录
  • 分类
  • 标签
  • 归档
  • Vue
  • JavaScript
  • 微信开发
  • 移动端H5调试工具
  • 国内十大前端团队网站
  • Nodejs
  • Egg
  • 环境搭建
  • 运维面板
  • 域名配置
  • Nginx
  • 收藏
  • 常用工具
  • 实用技巧
  • 常用命令
  • 友情链接
关于
  • 代码规范

    • Eslint
      • ESLint 规则总览
      • 第一部分:疑似写错的情况
      • 第二部分:促进最佳实践
      • 第三部分:变量相关
      • 第四部分:代码风格相关
      • 第五部分:ES6 相关
      • ESLint 规则总览 - 代码风格约定
    • Eslint-Plugin-Vue
    • Stylelint
  • uniapp

    • 问题解决

      • 【uniapp】字节小程序BUG - “navigateToMiniProgram/getUserProfile:fail must be invoked by user tap gesture”
  • JavaScript

    • JS验证18位身份证号码
    • JS图片压缩
    • JS调用elementUI图片预览
    • JS图片上传前校验大小、尺寸
  • Vue

    • Vue基础教程

      • Vue教程(1)-基础篇
      • Vue教程(2)-路由篇Vue-Router
      • Vue教程(3)- 状态管理Vuex
    • Vue自定义组件开发

      • Vue实现移动端轮播swiper组件
      • Vue实现switch开关组件
    • Vue扩展

      • Vue接入阿里OSS文件上传
    • Vue学习参考资料
  • 微信开发

    • 微信开发参考资料
    • 微信公众号

      • 微信公众号/订阅号/服务号主动给用户发消息
      • 微信jssdk自定义分享在iOS不生效
    • 微信小程序

      • 微信小程序区分运行环境:开发版/体验版/正式版
      • H5唤醒微信小程序
  • 收藏

    • 国内十大前端团队官网及GitHub
  • 常见问题解决

    • js错误

      • iframe下localStorage禁止访问。“Failed to read the localStorage property from Window”
      • TypeError: Promise.allSettled is not a function
    • IE兼容

      • fixed定位在IE下页面滚动时抖动
  • 工具

    • 移动端H5调试工具
  • 前端
  • 代码规范
Dreaming Lee 🍍 ҉҉҉҉҉҉҉҉
2020-10-12

Eslint

# Eslint

# ESLint 规则总览

# 图例

  • ℹ️ —— 点击此图标可以访问每条规则对应的 ESLint 官方文档。
  • ✅️️ —— 表示此规则属于 ESLint 官方推荐规则。
  • 🛠️️ —— 表示此规则可自动修复。

# 第一部分:疑似写错的情况

# 'for-direction': [2] ℹ️ (opens new window) ✅️

for 判断条件中的变量朝着相反的方向变化(这意味判断永远无法达成),会导致死循环。这通常是写错了。

# 'getter-return': [2] ℹ️ (opens new window) ✅️

属性的 getter 一定要有显式的返回值,即使返回 undefined 也应该显式地写出来。

# 'no-async-promise-executor': [2] ℹ️ (opens new window) ✅️

传给 Promise 构造函数的执行函数不能是异步函数。

# 'no-compare-neg-zero': [2] ℹ️ (opens new window) ✅️

禁止出现 foo === -0 这样的判断,这个判断的行为可能不符合作者的预期。在业务代码中写出这个判断极可能是笔误。

# 'no-cond-assign': [2, 'always'] ℹ️ (opens new window) ✅️

禁止在 if/while/for 等判断条件中写赋值语句,以免错看成判断;也有可能本意是想写判断,但错写成了赋值。

# 'no-constant-condition': [2] ℹ️ (opens new window) ✅️

禁止在 if/while/for 等判断条件中出现永远不变的判断结果。这种代码通常是因为调试代码忘了删除而导致的。

# 'no-control-regex': [2] ℹ️ (opens new window) ✅️

禁止在正则表达式中出现控制字符。没有理由这样做。

# 'no-debugger': process.env.NODE_ENV === 'production' ? [2] : [0] ℹ️ (opens new window) ✅️

禁止在代码中通过 debugger 调用调试器。不过在开发阶段是允许的。

# 'no-dupe-args': [2] ℹ️ (opens new window) ✅️

禁止函数出现重名的参数。出现这种代码通常是因为笔误。

# 'no-dupe-keys': [2] ℹ️ (opens new window) ✅️

禁止对象字面量出现重名的 key。出现这种代码通常是因为笔误。

# 'no-duplicate-case': [2] ℹ️ (opens new window) ✅️

禁止 switch 语句出现重复的 case。出现这种代码通常是因为笔误。

# 'no-empty': [2, { 'allowEmptyCatch': true }] ℹ️ (opens new window) ✅️

禁止出现空代码块。

// ⛔
if (foo) {

} else {
	return false
}
1
2
3
4
5
6

空的 catch 块是允许的。

// 🆗
try {
	doSomething()
} catch (e) {}
1
2
3
4

# 'no-empty-character-class': [2] ℹ️ (opens new window) ✅️

禁止正则表达式中出现空的字符集合(比如 /foo[]bar/ 中的 [])。包含空集合的正则表达式无法匹配任何字符串,很可能是笔误。

# 'no-ex-assign': [2] ℹ️ (opens new window) ✅️

禁止在 catch (e) {...} 块内对捕获到的异常(e)重新赋值。没有理由这样做,很有可能是笔误。

# 'no-extra-boolean-cast': [2] ℹ️ (opens new window) ✅️

禁止不必要的布尔值转换。在 if 语句或三元表达式等的判断条件中,表达式或值会被自动转换为布尔值,无需手动转换。比如 if (!!foo) {...} 与 if (foo) {...} 是等效的。

此时手动转换会让读代码的人困惑。

# 'no-func-assign': [2] ℹ️ (opens new window) ✅️

禁止对已声明的函数重新赋值。我们一般不会主动这样做,很有可能是从别处拷代码过来时出现重名了。

# 'no-import-assign': [2] ℹ️ (opens new window)

禁止对模块导入的绑定重新赋值。这种做法会引发运行时错误。

# 'no-inner-declarations': [2, 'both'] ℹ️ (opens new window) ✅️

禁止在 if () { ... } 等内层代码块内部声明函数或用 var 声明变量。这些做法往往有损代码可读性,比如声明提升可能带来意外的代码行为;或者在不同的 ES 模式下行为不确定或不合法。

// ⛔
if (foo) {
	var a = 1
}

// ⛔
if (foo) {
	function bar() {
		// ...
	}
}
1
2
3
4
5
6
7
8
9
10
11

以下情况不受此规则影响:

  • 通过 let 或 const 声明变量或常量
  • 把函数表达式赋值给变量

# 'no-invalid-regexp': [2] ℹ️ (opens new window) ✅️

禁止向 RegExp() 构造函数传入不合法的字符串,这种做法会引发运行时错误。在日常开发中,建议尽可能使用正则表达式字面量。

# 'no-irregular-whitespace': [2] ℹ️ (opens new window) ✅️

禁止在代码中的出现非常规的空白符(比如零宽空格等)。这些特殊字符可能引发解析错误,或者对正常的调试和重构带来困扰。这些字符往往是从别处拷代码时混进来的,或者是误按快捷键输入的。

如果需要在字符串中包含这些非常规空白符,建议使用其 Unicode 形式。比如 let foo = '\u2008'。

# 'no-misleading-character-class': [2] ℹ️ (opens new window) ✅️

禁止在正则表达式的字符集合中使用多码位的 Unicode 字符,这样做通常无法得到期望的结果。应该在这个场景下使用单码位的 Unicode 字符。

# 'no-obj-calls': [2] ℹ️ (opens new window) ✅️

禁止把 Math、JSON 这样的内置对象作为函数进行调用。虽然它们的首字母是大写的,但它们并不是一个构造函数。

# 'no-regex-spaces': [2] ℹ️ (opens new window) ✅️

禁止正则表达式中出现多个连续空格。因为很难一眼看清空格的数量。

建议在正则表达式中使用 {n} 来表达空格的重复数量,比如 /foo {3}bar/。

# 'no-sparse-arrays': [2] ℹ️ (opens new window) ✅️

禁止通过数组字面量生成稀疏数组(“稀疏数组” 是指那些不是每个坑都填了值的数组)。在日常开发中不太有理由使用这个特性,大多数情况下是多打了逗号导致的,比如本意想写 [1, 2] 但写成了 [1,,2],就产生了一个稀疏数组。

如果确实需要生成一个稀疏数组,可以使用 Array() 来构造,比如 new Array(3) 会生成一个坑数为 3 的稀疏数组。

# 'no-unexpected-multiline': [2] ℹ️ (opens new window) ✅️

防止多行代码被(意外地)解析为连续的运算表达式。在采用 “句末不写分号” 风格的代码中比较容易出现这种情况:当第一行末尾没有分号,而第二行开头是 ( 或 [ 等字符时,第二行会视为紧接上一行代码的延续,这往往与预期不符。

此时需要在这两行代码之间加分号或 void 关键字,以阻断这种 “粘连效应”。

# 'no-unreachable': [2] ℹ️ (opens new window) ✅️

禁止出现不可达的代码,比如 return/throw/break 语句之后的代码是永远不会执行到的。我们一般不会主动这样写,很有可能调试代码忘了删了。

# 'no-unsafe-finally': [2] ℹ️ (opens new window) ✅️

禁止在 finally 块中出现 return/throw 等中止代码流程的语句。因为 finally 块中这些语句的实际执行时机很可能与开发者的预期不符,从而引发 bug。

# 'no-unsafe-negation': [2] ℹ️ (opens new window) ✅️

禁止对 in/instanceof 操作符的左侧值使用(意图不明确的)! 运算。比如我们写 !key in object 的本意可能是 !(key in object) 而不是 (!key) in object,但实际的运算顺序是后者。

# 'use-isnan': [2] ℹ️ (opens new window) ✅️

禁止在检测 NaN 时使用 foo === NaN 或 foo !== NaN 这样的做法,因为这样判断的结果不符合预期。可以使用 isNaN() 函数来完成这个任务。

事实上,在 ES6+ 环境中,建议使用 Number.isNaN() 来检测 NaN,它更健壮一些。

扩展阅读: Number.isNaN() @ MDN (opens new window)

# 'valid-typeof': [2] ℹ️ (opens new window) ✅️

强制在做 typeof 判断时总是与合理的值进行比较。比如 typeof foo === 5 永远都不可能相等,没有比较的意义。我们一般不会主动这样写,但笔误无法避免,比如我们很可能会把 'string' 错写成 'stirng' 或 'String'。

# 第二部分:促进最佳实践

# 'curly': [2, 'multi-line', 'consistent'] ℹ️ (opens new window)

约束 if/while/for 等语句的代码块是否加大括号:

  • 当这些代码块是单条语句且写成一行时,允许不加大括号;其它情况必须加大括号。
  • 另外,对同一个 if/else if/else 链中的所有代码块来说,要求它们在大括号的写法上保持一致。

这是一条跟代码风格有关的规则,但设置它的目的不是为了统一代码风格,而是为了提升代码可读性,减少误解。

是否要写大括号的约束如下:

// ✅ 单行语句,写成一行,可以加大括号
if (!foo) { return false }

// ✅ 单行语句,写成一行,也可以不加大括号
if (!foo) return false

// ✅ 单行语句,另起一行,需要加大括号
if (!foo) {
    return false
}

// ✅ 多行语句,需要加大括号
if (foo) {
    foo++
    return foo
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ⛔
if (!foo)
    return false

// ⛔
if (foo) return {
    foo: foo,
    bar: bar
}
1
2
3
4
5
6
7
8
9

大括号一致性的约束如下:

// ✅ 同一个 if/else if/else 链中的写法要统一
if (foo) foo()
else bar()

// ✅ 同一个 if/else if/else 链中的写法要统一
if (a === 1) {
    a++
    foo(a)
} else {
    foo(b)
}
1
2
3
4
5
6
7
8
9
10
11
// ⛔
if (a === 1) {
    a++
    foo(a)
} else foo(b)
1
2
3
4
5

# 'default-param-last': [2] ℹ️ (opens new window)

函数的可选参数(有默认值的参数)必须是在最后的。如果可选参数排在非可选参数之前,则该参数其实无法实现可选的效果。

# 'dot-location': [2, 'property'] ℹ️ (opens new window)

如果要在 . 操作符这里换行,那么 . 是跟着对象留在上一行,还是跟着方法换到下一行?考虑到链式调用语句的易读性,这条规则要求把 . 放在行首。

// ✅
$('.wrapper > a')
    .first()
    .addClass('foo')
    .html('bar')

// ✅
$('.wrapper > a').first()
    .addClass('foo')
    .html('bar')
1
2
3
4
5
6
7
8
9
10

# 'eqeqeq': [2] ℹ️ (opens new window)

当我们用 == 或 != 来判断两个不同类型的值时,JS 会采用一些不那么直观易记的判断规则。为避免产出无法预料的 bug,这条规则禁止使用 == 和 !=,我们应该总是使用 === 或 !== 来进行判断。

# 'no-caller': [2] ℹ️ (opens new window)

在某些情况下,arguments.caller 和 arguments.callee 很好用,但由于 ES5 的严格模式已经禁用了这两者,我们也不应该再使用它们了。

# 'no-case-declarations': [2] ℹ️ (opens new window) ✅️

这条规则禁止 let/const/function/class 等词法声明出现在 case/default 子句中。先看看这样做有什么问题吧:

// ⛔
switch (foo) {
    case 1:
        let x = 1
        fn(x)
        break
    case 2:
        bar(x)
        break
    default:
        foobar()
}
1
2
3
4
5
6
7
8
9
10
11
12

我们在 case 1 中声明了 x 变量,这个变量在整个 switch 代码块中都是可见的,也话是说 case 2 中传给 bar(x) 的实参就是这个 x,但只有当代码运行到 case 1 分支时 x 才会被初始化,因此当代码运行到 case 2 分支时会产生 ReferenceError。

有可能 case 2 的代码本意是想访问更上层作用域中的 x 变量,因此,如果我们只是想在某个 case 子句中创建一个局部变量,那就需要把子句包进一个代码块中:

// ✅
switch (foo) {
    case 1: {
        let x = 1
        fn(x)
        break
    }
    case 2:
        bar(x)
        break
    default:
        foobar()
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 'no-empty-function': [2] ℹ️ (opens new window)

禁止出现空函数(啥事也不做的函数)。很可能是忘了写函数体。

# 'no-empty-pattern': [2] ℹ️ (opens new window) ✅️

禁止在解构中出现无意义的解构模式:

// ⛔ 不会生成任何变量
let {a: {}} = foo
1
2

这往往是一个笔误,代码的本意很可能是这样的:

// 💭 为变量 a 指定一个默认值
let {a = {}} = foo
1
2

# 'no-eval': [2] ℹ️ (opens new window)

eval() 是 JS 中的一个特殊的函数,它有诸多问题,在日常开发中似乎没有理由使用它。

# 'no-extend-native': [2] ℹ️ (opens new window)

扩展 Object/Array/Function 等原生对象可能产生不可预料的副作用,在日常开发中似乎也没有理由这样做。如果要 polyfill,交给 core.js 或 babel-preset-env 等专门的库或工具来实现,不要自己写。

# 'no-extra-bind': [2] ℹ️ (opens new window)

如果一个函数内部没有用到 this 关键字,则没有必要对它 .bind()。

# 'no-extra-label': [2] ℹ️ (opens new window)

标签(label)可以帮助我们在多层嵌套的循环中 break/continue 指定的循环。但如果不存在嵌套的情况,也就没必要加标签了,此时加标签反而令人困惑。

# 'no-fallthrough': [2] ℹ️ (opens new window) ✅️

“Case 穿透” 是 switch 的一个有意思的特性,但有时候也是个坑。因此完全禁用这种行为。

# 'no-floating-decimal': [2] ℹ️ (opens new window)

禁止浮点数在小数点之前或之后省略 0 的写法。

# 'no-global-assign': [2] ℹ️ (opens new window) ✅️

禁止修改只读的全局变量。

ESLint 怎么知道哪些变量是全局变量并且只读?我们在配置文件中会声明 env 和 globals 字段,ESLint 会通过它们来判断。

# 'no-implicit-coercion': [2, { 'allow': ['!!', '+'] }] ℹ️ (opens new window)

禁用隐式的类型转换,因为代码意图往往不清晰。比如:

// ⛔
var bar = ~foo.indexOf('.')
1
2

这行代码令人摸不着头脑,它的本意是这样的(判断字符串的包含关系):

// 💭
var bar = foo.indexOf('.') !== -1
1
2

还有一些类型转换的方法,相对比较易读,是允许的:

// 🆗
var b = !!foo     // to boolean
var n = +foo      // to number
var s = '' + foo  // to string
1
2
3
4

当然最清晰的写法还是显式转换:

// ✅
var b = Boolean(foo)
var n = Number(foo)
var s = String(foo)
1
2
3
4

# 'no-implied-eval': [2] ℹ️ (opens new window)

setTimeout() 等函数可能会隐式地调用 eval(),禁止这种情况。

// ⛔
setTimeout("alert('foo')", 1000)
1
2

应该使用下面的写法来代替:

// ✅
setTimeout(function() {
    alert('foo')
}, 1000)
1
2
3
4

# 'no-lone-blocks': [2] ℹ️ (opens new window)

禁止不必要的代码块包裹。

# 'no-multi-str': [2] ℹ️ (opens new window)

禁止在字符串中使用转义符来生成多行字符串:

// ⛔ 'foo' 和 'bar' 之间通过转义符生成了一个换行
let str = 'foo\
bar'
1
2
3

应该使用字符串拼接来生成多行字符串,或直接使用 ES6 模板字符串:

// ✅ 字符串拼接
let str = 'foo\n' +
    'bar'

// ✅ 通过数组来拼接多行字符串
let str = [
    'foo',
    'bar'
].join('\n')
1
2
3
4
5
6
7
8
9
// ✅ 模板字符串
let str = `foo
bar`
1
2
3

# 'no-new-func': [2] ℹ️ (opens new window)

禁止使用 Function() 来生成函数,它的问题与 eval() 类似。有些模板引擎会用它来编译模板,但在日常开发中似乎没有理由使用它。

# 'no-octal': [2] ℹ️ (opens new window) ✅️

禁止使用八进制数字字面量,因为不易读。

// ⛔
let i = 010  // 8
1
2

建议使用 ES6 新增的八进制数字字面量写法:

// ✅
let i = 0o10
1
2

# 'no-octal-escape': [2] ℹ️ (opens new window)

禁止在字符串中使用八进制转义序列,因为 ES5 已经弃用此特性,而且这种写法不易读。

# 'no-return-assign': [2, 'always'] ℹ️ (opens new window)

虽然 return 允许接一个赋值表达式,但这种写法令人困惑:

// ⛔
function fn (bar) {
    return foo = bar + 1
}
1
2
3
4

它的效果是返回 bar + 1,但本意很可能是想返回 foo === bar + 1 但写错了。

# 'no-self-assign': [2] ℹ️ (opens new window) ✅️

禁止把一个变量赋值给自己。

// ⛔
foo = foo
1
2
// ⛔ 通过解构把变量赋值给自己
[a, b] = [a, c]
1
2

在某些情况下,我们需要把一个对象的属性赋值给这个属性。这样做看似无意义,但实际上是通过 setter 来触发副作用(比如有些时候可以绕过浏览器 bug 等等)。因此这种情况是允许的。

// 🆗
foo.bar = foo.bar
1
2

# 'no-self-compare': [2] ℹ️ (opens new window)

禁止对两个相同的变量进行比较,这往往是写错了。

# 'no-sequences': [2] ℹ️ (opens new window)

禁用不必要的 , 操作符。绝大多数时候它都是不直观、不易读的。除了 for 循环以外,在日常开发中似乎没有理由使用它。

# 'no-throw-literal': [2] ℹ️ (opens new window)

禁止 throw 一个字面量,应该总是抛出一个 Error 对象。

# 'no-unmodified-loop-condition': [2] ℹ️ (opens new window)

如果循环的判断条件不会发生变化,则在运行时会产生死循环。这种情况应该是写错了。

# 'no-unused-expressions': [2, { 'allowShortCircuit': true, 'allowTernary': true }] ℹ️ (opens new window)

禁止无作用的表达式。一个表达式的计算结果被丢弃,则视为 “无作用”,一般是写错了。

不过代码中有一些比较常见实践也属于这种情况,因此这条规则作为特例放行:

// 🆗 利用短路来实现逻辑判断
a && b()

// 🆗 利用三元表达式来实现逻辑判断
a ? b() : c()
1
2
3
4
5

# 'no-unused-labels': [2] ℹ️ (opens new window) ✅️

标签(label)没有被任何 continue/break 语句用到,将被视为代码写错了。

# 'no-useless-call': [2] ℹ️ (opens new window)

Function#call() 和 Function#apply() 可以指定某个方法执行时的 this 指向,很有用。但如果代码中使用这两个函数但并没改变 this 指向,将被视为代码写错了。

# 'no-useless-catch': [2] ℹ️ (opens new window) ✅️

如果我们在 catch 代码块中只是把捕获到的错误再抛出去,那这一层 catch 其实是没有必要的。禁止这种行为。

# 'no-with': [2] ℹ️ (opens new window) ✅️

禁止使用 with 语句。

# 'prefer-promise-reject-errors': [2] ℹ️ (opens new window)

要求 Promise.reject() 只能抛出 Error 对象。

# 'prefer-regex-literals': [2] ℹ️ (opens new window)

我们可以通过 RegExp() 构造函数来生成正则表达式,但这种写法有坑,因为传给它的字符串需要考虑反斜杠的转义问题,一不小心就会写错。

// ⛔ 需要时刻提醒自己:要写两个反斜杠!!!
const reMobileNumber = new RegExp('^1\\d{10}$')
1
2

因此,如果有可能的话,我们应该用正则表达式字面量来替代这种写法。

// ✅
const reMobileNumber = /^1\d{10}$/
1
2

# 'require-await': [2] ℹ️ (opens new window)

要求 async 函数中总是有 await 语句。

# 第三部分:变量相关

# 'no-delete-var': [2] ℹ️ (opens new window) ✅️

禁止 delete 变量。只应该 delete 对象的某个属性。

# 'no-shadow-restricted-names': [2] ℹ️ (opens new window) ✅️

禁止将受限的名字(比如 NaN、Infinity、undefined 等)作为变量名、参数名。

# 'no-undef': [2] ℹ️ (opens new window) ✅️

禁止引用一个未定义的变量,这可能导致一个 ReferenceError,或者无意中创建了一个全局变量。

# 'no-use-before-define': [2, { 'functions': false }] ℹ️ (opens new window)

禁止在定义变量之前就使用它。因为:

  • 虽然 var 有变量提升效果,但它的初始赋值并不会被提升。为避免误解,禁止这种做法。
  • let 和 const 声明变量之前存在 “短暂死区”,在此区域内使用变量会引发报错。
// ⛔
alert(bar)  // => undefined
var bar = 1

// ✅
var bar = 1
alert(bar)  // => 1

// ✅
var bar
alert(bar)  // => undefined
bar = 1
1
2
3
4
5
6
7
8
9
10
11
12

函数声明的提升相对安全,允许先使用后声明。

// 🆗
foo()

function foo() { /* ... */ }
1
2
3
4

# 第四部分:代码风格相关

# 'new-cap': [2, { capIsNew: false, properties: true }] ℹ️ (opens new window)

要求构建函数必须是首字母大写;如果对象的属性作为构建函数,则这个属性也必须是首字母大写。

不过首字母大写的函数可以单独调用,并不限制它只能用于 new 操作符。

# 'new-parens': [2] ℹ️ (opens new window)

构造函数在调用时必须写小括号。

// ⛔
let person = new Person
1
2
// ✅
let person = new Person()
1
2

# 'no-array-constructor': [2] ℹ️ (opens new window)

禁止通过 Array() 构造函数来创建数组,应该用数组字面量:

// ⛔
let arr = new Array(1, 2, 3)

// ✅
let arr = [1, 2, 3]
1
2
3
4
5

如果你只传一个整数值给 Array() 以便创建一个稀疏数组,是允许的:

// 🆗
let arr = new Array(19)
1
2

# 'no-bitwise': [2] ℹ️ (opens new window)

禁用所有的位运算符。

// ⛔
let a = b & c

// ⛔
if (foo | bar) {/* ... */}
1
2
3
4
5

理论上业务代码中不太可能会用到位运算,写出位运算多半是手滑敲错了。比如上面这两行代码的本意可能是这样的:

// 💭
let a = b && c

// 💭
if (foo || bar) {/* ... */}
1
2
3
4
5

# 'no-new-object': [2] ℹ️ (opens new window)

禁止通过 Object() 构造函数来创建对象,应该用对象字面量:

# 'unicode-bom': [2] ℹ️ (opens new window)

采用 Unicode 编码的文本文件可以在文件的开始用几个字节标注 “字节顺序”(BOM)。

BOM 对 JS 文件没有害处,但对 PHP 文件有非常大的害处(PHP 无法忽略文件开头的那几个 BOM 字节,导致功能异常)。由于我们的系统中默认一律采用 UTF-8,不需要通过 BOM 来指定,因此建议你配置好自己的编辑器,统一关闭生成 BOM 的功能。

# 第五部分:ES6 相关

# 'constructor-super': [2] ℹ️ (opens new window) ✅️

只有派生 class 才允许调用 super()。

# 'no-class-assign': [2] ℹ️ (opens new window) ✅️

禁止给 class 赋值。

# 'no-const-assign': [2] ℹ️ (opens new window) ✅️

禁止给常量赋值。

# 'no-dupe-class-members': [2] ℹ️ (opens new window) ✅️

禁止 class 的方法或属性出现重名。出现这种代码通常是因为笔误。

# 'no-new-symbol': [2] ℹ️ (opens new window) ✅️

Symbol() 看起来像个构造函数,但实际上它是单独调用的。禁止通过 new 操作符来调用它。

# 'no-this-before-super': [2] ℹ️ (opens new window) ✅️

派生 class 的构造方法在调用 super() 之前不允许使用 this 和 super 关键字是,否则会产生 ReferenceError。

# 'require-yield': [2] ℹ️ (opens new window) ✅️

Generator 函数体必须包含 yield 关键字。

# ESLint 规则总览 - 代码风格约定

# 'array-bracket-newline': [2, 'consistent'] ℹ️ (opens new window) 🛠️

指定数组和类似语法结构的中括号内侧是否换行:要求首尾换行行为一致。

# 'array-bracket-spacing': [2, 'never'] ℹ️ (opens new window) 🛠️

指定数组和类似语法结构的中括号内侧是否加空格:不加。

# 'array-element-newline': [2, 'consistent'] ℹ️ (opens new window) 🛠️

指定数组成员之间是否换行:要求同一数组内的行为一致。

# 'block-spacing': [2, 'always'] ℹ️ (opens new window) 🛠️

指定代码块的花括号内侧是否加空格:加空格。

# 'brace-style': [0] ℹ️ (opens new window) 🛠️

[不限] 指定花括号的书写风格。

这条规则目前还没有类似 allowStroustrupIfCommentBetween 的选项,实际使用不太方便,因此暂不开启。

# 'camelcase': [2, { ... }] ℹ️ (opens new window)

要求变量名必须采用驼峰拼写,不得采用 snake_case。不过,解构语法中的属性名是允许 snake_case 的;对象的属性名是允许 snake_case 的;Vue 插件在 Vue 原型上绑定的方法名可以使用 $_camelCase。

# 'capitalized-comments': [0] ℹ️ (opens new window) 🛠️

[不限] 注释的首字母是否大写。

# 'comma-dangle': [2, 'always-multiline'] ℹ️ (opens new window) 🛠️

在由逗号分隔的列表(数组字面量、对象字面量、函数参数列表、模块导入导出清单等)中,结尾是否写逗号。

# 'comma-spacing': [2] ℹ️ (opens new window) 🛠️

指定逗号前后是否加空格:取 ESLint 默认值(逗号前不加空格,逗号后加空格)。

# 'comma-style': [2] ℹ️ (opens new window) 🛠️

指定当需要在逗号处换行时的行为:只能在逗号后换行(即逗号在行末)。

# 'computed-property-spacing': [2] ℹ️ (opens new window) 🛠️

指定对象的计算式属性名的中括号内侧是否加空格:不加。

# 'consistent-this': [0] ℹ️ (opens new window)

[不限] 指定 this 的别名允许哪些命名。

# 'eol-last': [2] ℹ️ (opens new window) 🛠️

要求文件末尾必须有一个行结束符(换行符)。

# 'func-call-spacing': [2] ℹ️ (opens new window) 🛠️

指定函数调用的函数名和小括号之间是否加空格:不加。

# 'func-name-matching': [0] ℹ️ (opens new window)

[不限] 要求函数名与它被赋值到的变量名(或属性名)是否需要保持一致。

# 'func-names': [0] ℹ️ (opens new window)

[不限] 要求函数表达式是否是具名的。

# 'func-style': [2, 'declaration', { allowArrowFunctions: true }] ℹ️ (opens new window)

定义函数有两种方式:(1) 函数声明,(2) 把函数表达式赋值给变量。此规则要求使用前者。

不过,把箭头函数赋值给变量是允许的。

# 'function-call-argument-newline': [2, 'consistent'] ℹ️ (opens new window) 🛠️

指定函数调用的各个参数之间是否换行:要求各参数的行为一致。

# 'function-paren-newline': [2, 'consistent'] ℹ️ (opens new window) 🛠️

指定包裹函数参数的小括号内侧是否换行:要求首尾换行行为一致。

# 'id-blacklist': [0] ℹ️ (opens new window)

[不限] 指定标识符命名的黑名单。

# 'id-length': [2, { ... }] ℹ️ (opens new window)

指定标识符至少要有多长。除了 e x y z w h i j _ $ 等常用的单字符变量名以外,至少要达到两个字符。

对象属性的命名不受此规则影响。

# 'id-match': [0] ℹ️ (opens new window)

[不限] 指定标识符命名要满足的模式。

# 'implicit-arrow-linebreak': [2] ℹ️ (opens new window) 🛠️

指定当箭头函数采用简写语法时,箭头后是否换行:取 ESLint 默认值(不换行)。

# 'indent': [2, 'tab', { 'SwitchCase': 1 }] ℹ️ (opens new window) 🛠️

指定缩进风格:采用 tab 字符作为缩进。switch 语句内的 case 子句需要缩进。

# 'jsx-quotes': [0] ℹ️ (opens new window) 🛠️

[不限] 指定 JSX 中标签属性的引号风格。

# 'key-spacing': [2] ℹ️ (opens new window) 🛠️

指定对象字面量中属性名和属性值之间是否加空格:冒号前不加空格,冒号后加空格。

let obj1 = {
    a: value,
    bcde: 42,
    fg: foobar(),
}

let obj2 = { foo: 1, bar: 2 }
1
2
3
4
5
6
7

当对象字面量写成多行时,允许在冒号后使用连续多个空格来纵向对齐属性值:

let obj1 = {
    a:    value,
    bcde: 42,
    fg:   foobar(),
}
1
2
3
4
5

# 'keyword-spacing': [2] ℹ️ (opens new window) 🛠️

指定关键字前后是否加空格:取 ESLint 默认值(前后都加空格,但在遇到冲突时服从其它加空格规则)。

# 'line-comment-position': [0] ℹ️ (opens new window)

[不限] 指定注释的书写位置是独占一行还是写在代码右侧。

# 'linebreak-style': [2] ℹ️ (opens new window) 🛠️

换行符采用 LF(UNIX 风格)。

# 'lines-around-comment': [0] ℹ️ (opens new window) 🛠️

[不限] 指定注释前后是否要添加空行。

# 'lines-between-class-members': [0] ℹ️ (opens new window) 🛠️

[不限] 指定类成员之间是否要添加空行。

# 'max-depth': [2] ℹ️ (opens new window)

指定代码块允许嵌套的最大层数:取 ESLint 默认值(4 层)。

# 'max-len': [2, { ... }] ℹ️ (opens new window)

指定单行代码允许的最大长度:

  • 单行代码或注释的最大长度为 120 字符。
  • 一级缩进按 4 个字符计算。
  • 位于行末的注释不记在内。
  • 允许 URL 导致的超长情况。
  • 允许正则表达式字面量导致的超长情况。
  • 允许字符串字面量或模板字符串导致的超长情况。

# 'max-lines': [0] ℹ️ (opens new window)

[不限] 指定单个文件允许的最大行数。

# 'max-lines-per-function': [0] ℹ️ (opens new window)

[不限] 指定单个函数允许的最大行数。

这条规则目前还没有类似 ignoreTopLevelFunctions 的选项,实际使用不太方便,因此暂不开启。

# 'max-nested-callbacks': [2] ℹ️ (opens new window)

指定回调函数允许嵌套的最大层数:取 ESLint 默认值(10 层)。

# 'max-params': [2, 5] ℹ️ (opens new window)

指定函数参数允许的最大数量:5 个。

# 'max-statements': [0] ℹ️ (opens new window)

[不限] 指定单个函数允许包含的语句的最大数量。

每个变量声明语句也算一个语句,这条规则很难衡量实际的代码复杂度,因此暂不开启。

# 'max-statements-per-line': [2] ℹ️ (opens new window)

指单行代码允许包含的语句的最大数量:取 ESLint 默认值(每行最多一个语句)。

# 'multiline-comment-style': [0] ℹ️ (opens new window) 🛠️

[不限] 指定多行注释的风格。

# 'multiline-ternary': [0] ℹ️ (opens new window)

[不限] 指定三元运算表达式的换行风格。

# 'new-cap': [0] ℹ️ (opens new window)

(已收入 essential 配置包中。)

# 'new-parens': [0] ℹ️ (opens new window) 🛠️

(已收入 essential 配置包中。)

# 'newline-per-chained-call': [2, { ignoreChainWithDepth: 3 }] ℹ️ (opens new window) 🛠️

指定链式调用的每个方法是否需要换行:需要换行。

如果链式调用深度在 3 级以内,则允许写成一行。

# 'no-array-constructor': [0] ℹ️ (opens new window)

(已收入 essential 配置包中。)

# 'no-bitwise': [0] ℹ️ (opens new window)

(已收入 essential 配置包中。)

# 'no-continue': [0] ℹ️ (opens new window)

[不限] 禁止使用 continue 语句。

# 'no-inline-comments': [0] ℹ️ (opens new window)

[不限] 指定注释是否要独占一行(是否可以与代码写在同一行)。

# 'no-lonely-if': [2] ℹ️ (opens new window) 🛠️

else 块内如果只有一个单独的 if 语句,则应该合并为 else if。

# 'no-mixed-operators': [0] ℹ️ (opens new window)

[不限] 当表达式中连续使用同类型操作符时,需要用括号显式标出运算优先级。

# 'no-mixed-spaces-and-tabs': [2] ℹ️ (opens new window) ✅️️

不允许混用空格和 tab 来实现缩进。

JSDoc 或类似的文档型注释的每行开头的空格不受此规则影响。

# 'no-multi-assign': [0] ℹ️ (opens new window)

[不限] 是否允许连环赋值。

# 'no-multiple-empty-lines': [2, { max: 2 }] ℹ️ (opens new window) 🛠️

指定允许连续空行的数量:取 ESLint 默认值(2 个空行)。

# 'no-negated-condition': [0] ℹ️ (opens new window)

[不限] 是否允许在一分为二的判断条件中出现否定判断条件。

# 'no-nested-ternary': [0] ℹ️ (opens new window)

[不限] 是否允许出现嵌套的三元运算表达式。

# 'no-new-object': [0] ℹ️ (opens new window)

(已收入 essential 配置包中。)

# 'no-plusplus': [0] ℹ️ (opens new window)

[不限] 是否允许出现 ++ 运算符。

# 'no-restricted-syntax': [0] ℹ️ (opens new window)

[不限] 是否禁止某些特定语法。

# 'no-tabs': [0] ℹ️ (opens new window)

[不限] 是否禁用 tab 字符。

# 'no-ternary': [0] ℹ️ (opens new window) 🛠️

[不限] 是否禁用三元运算表达式。

# 'no-trailing-spaces': [2] ℹ️ (opens new window) 🛠️

禁止行末出现空白符(空格、tab 等)。

# 'no-underscore-dangle': [0] ℹ️ (opens new window)

[不限] 是否允许在标识符的头尾使用下划线(_)。

# 'no-unneeded-ternary': [2] ℹ️ (opens new window) 🛠️

禁止出现不必要的三元运算表达式。

# 'no-whitespace-before-property': [2] ℹ️ (opens new window) 🛠️

对象与属性之间不加空格。

foo.bar()

let z = x[y]
1
2
3

# 'nonblock-statement-body-position': [2] ℹ️ (opens new window) 🛠️

当 if、else、while、do-while、for 等语句的主体为单行且没有写成块形式时,需要把整个语句写成一行,不得换行。

if (foo === 1) bar()
1

# 'object-curly-newline': [2, { consistent: true }] ℹ️ (opens new window) 🛠️

指定对象和类似语法结构的大括号内侧是否换行:要求首尾换行行为一致。

# 'object-curly-spacing': [2, 'always'] ℹ️ (opens new window) 🛠️

指定对象和类似语法结构的大括号内侧是否加空格:加空格。

# 'object-property-newline': [2, { allowAllPropertiesOnSameLine: true }] ℹ️ (opens new window) 🛠️

对象字面量的各个属性必须独占一行,除非所有属性都写在同一行。

# 'one-var': [2, 'never'] ℹ️ (opens new window) 🛠️

指定同一作用域中的声明语句是否需要合并:不合并,每个声明语句只声明一个变量。

# 'one-var-declaration-per-line': [2, 'initializations'] ℹ️ (opens new window) 🛠️

当同一条声明语句声明多个变量时,初始化的变量必须独占一行。

# 'operator-assignment': [0] ℹ️ (opens new window) 🛠️

[不限] 是否要求使用 x += 4 简化 x = x + 4。

# 'operator-linebreak': [2, 'after'] ℹ️ (opens new window) 🛠️

只能在运算符的右侧换行。

# 'padded-blocks': [0] ℹ️ (opens new window) 🛠️

[不限] 是否禁止在代码块的内侧插入空行。

# 'padding-line-between-statements': [0] ℹ️ (opens new window) 🛠️

[不限] 是否在语句之间插入空行。

# 'prefer-exponentiation-operator': [0] ℹ️ (opens new window) 🛠️

[不限] 是否要求使用指数运算符 ** 代替 Math.pow()。

⚠️ 注意:此规则的前提是运行环境或解析环境支持 ES2016 语法,比如:

  • 代码会经过 Babel 6+ / Vue CLI 3+ 处理。
  • 代码运行于 Node.js 7+。

# 'prefer-object-spread': [0] ℹ️ (opens new window) 🛠️

[不限] 是否要求使用对象展开语法来代替 Object.assign()。

⚠️ 注意:此规则的前提是运行环境或解析环境支持 ES2016 语法,比如:

  • 代码会经过 Babel 6+ / Vue CLI 3+ 处理。
  • 代码运行于 Node.js 8+。

# 'quote-props': [2, 'consistent'] ℹ️ (opens new window) 🛠️

指定对象字面量的各个属性是否需要加引号:要求所有属性行为一致。

# 'quotes': [2, 'single', { avoidEscape: true }] ℹ️ (opens new window) 🛠️

优先使用单引号。当字符串内容包含单引号时,为避免转义,可以字符串可以使用双引号来包裹。

# 'semi': [2, 'never'] ℹ️ (opens new window) 🛠️

采用 “无分号” 风格。

# 'semi-spacing': [2] ℹ️ (opens new window) 🛠️

指定分号前后是否加空格:取 ESLint 默认值(分号前不加空格,分号后加空格)。

# 'semi-style': [0] ℹ️ (opens new window) 🛠️

[不限] 指定分号的书写位置(句名或句首)。

# 'sort-keys': [0] ℹ️ (opens new window)

[不限] 给对象字面量的属性排序。

# 'sort-vars': [0] ℹ️ (opens new window) 🛠️

[不限] 声明变量时给变量排序。

# 'space-before-blocks': [2] ℹ️ (opens new window) 🛠️

指定代码块之前是否加空格:取 ESLint 默认值(加空格)。

# 'space-before-function-paren': [2, { ... }] ℹ️ (opens new window) 🛠️

指定函数参数的小括号之前是否加空格:

  • 匿名函数:要加。比如: function () {}
  • 具名函数:不加。比如: function foo() {}
  • 异步函数:要加。比如: async () => {}

# 'space-in-parens': [2, 'never'] ℹ️ (opens new window) 🛠️

指定小括号内侧是否加空格:取 ESLint 默认值(不加)。

# 'space-infix-ops': [2] ℹ️ (opens new window) 🛠️

指定中缀操作符的前后否加空格:取 ESLint 默认值(加空格)。

# 'space-unary-ops': [2] ℹ️ (opens new window) 🛠️

指定一元操作符的前后否加空格:取 ESLint 默认值:

  • 单词型操作符(比如 typeof、delete)之后加空格。
  • 符号型操作符(比如 ++、!)前后都不加空格。

# 'spaced-comment': [0] ℹ️ (opens new window) 🛠️

指定注释的 // 之后和 /* */ 的内侧是否需要加空格:加空格。

// this is a comment
/* this is a comment */
1
2

以下情况不受此规则影响:

  • 这种形式的分隔线: //--------
  • 这种形式的分隔线: //========
  • 这种形式的分隔线: //++++++++
  • 这种形式的区段标题: //////////////////// Title ////////////////////

以下特殊字符会视为注释标记的一部分,在它们之后仍然需要加空格:

  • 文档型注释: /** this is a doc comment */
  • 这种形式的特殊注释: /*! this comment remained after minifying */
  • 这种形式的特殊注释: /// <reference path="..." />

# 'switch-colon-spacing': [2] ℹ️ (opens new window) 🛠️

指定 switch 语句中的 case/default 子句的冒号是否加空格:取 ESLint 默认值(冒号前不加空格,冒号后加空格)。

# 'template-tag-spacing': [2] ℹ️ (opens new window) 🛠️

指定模板字符串与它的 tag 函数之间是否加空格:取 ESLint 默认值(不加)。

# 'unicode-bom': [0] ℹ️ (opens new window) 🛠️

(已收入 essential 配置包中。)

# 'wrap-regex': [0] ℹ️ (opens new window) 🛠️

[不限] 指定当正则表达式字面量出现在语句中间时,是否需要加括号来避免视觉上的歧义(被误认为是除法运算)。

上次更新: 2021-05-10 17:15:54
Eslint-Plugin-Vue

Eslint-Plugin-Vue→

最近更新
01
【uniapp】字节小程序BUG - “navigateToMiniProgram/getUserProfile:fail must be invoked by user tap gesture”
06-21
02
七牛云上传自有证书
04-27
03
使用腾讯云申请免费SSL证书
04-27
更多文章>
Theme by Vdoing | Copyright © 2020-2024 | 豫ICP备2020030395号 | 靳立祥 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式