V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iugo
V2EX  ›  程序员

ESLint 自带规则部分笔记 (JavaScript 教材书?)

  •  
  •   iugo ·
    iugo · 2020-03-10 18:01:20 +08:00 · 1730 次点击
    这是一个创建于 1520 天前的主题,其中的信息可能已经有所发展或是发生改变。

    是想写全的: https://github.com/zsqk/zsqk/issues/120

    以后有时间了补.


    在 TypeScript 之前, 学习 JavaScript/ECMAScript(简称 JS) 最好的老师就是 ESLint.

    是 ESLint 让我学习 JS, 并使用 JS 到现在的.

    大多数情况下我都是不建议自己完善规则的, 因为 Airbnb 的规则已经足够好用了, React 也有自己的规则建议. 并且 TypeScript 能做的更多.

    最近在整理微信小程序的项目, 在为这个项目完善 ESLint 规则的时候, 顺便也整理一份文字出来, 讲讲我这样设置的原因.

    我的简短文字更像是笔记, 希望大家对照着 ESLint 自带的规则 来看.

    被推荐的规则, 建议大家遵循, 同时建议没看过的同学在有空时翻看一下.

    针对没有添加到 eslint:recommended 的, 下面逐一说:

    避免错误

    no-await-in-loop 不允许在循环中嵌套 await.

    🟡 没有使用该规则.

    我的原因很简单, 就是当想避免同时并发时, 在循环里 await wait('100ms');fetch('something'); 还是有意义的.

    no-console 不允许控制台输出

    🟢使用该规则: error.

    如果真是希望长期留存输出, 建议大家通过一个函数进行包裹, 然后仅在该函数中使用, 然后通过注释 disable-eslint 来避免报错.

    no-extra-parens 不使用没必要的括号.

    🟢使用该规则: error.

    这里有一些小知识点, 比如算术运算符是遵循数学的, 乘除号优先级一样, 但逻辑运算符可不是. 推荐大家看看MDN 关于运算符优先级的相关文档, 比如 && 是优先于 || 的.

    no-template-curly-in-string 普通字符串中不使用参数占位符

    🟢 使用该规则: error.

    为了避免本来使用重音符但使用了引号的情况, 要求普通字符串中不能出现参数占位符. 是一点限制, 但基本不会有人故意在普通字符串中非要使用参数占位符, 如果非要, 那就用编码吧, 比如 '\u0024{}'.

    [7.0] no-useless-backreference

    🟡 没有使用该规则.

    这是最近才添加的新规则, 关于字符串正则的, 我们很少写正则.

    因为 7.0 版本还在测试, 直接进入 404, 可以通过这里看文档.

    require-atomic-updates 涉及异步时, 优先执行异步

    🟢 使用该规则: error.

    虽然我们尽量写纯函数, 避免这种用法是可能的. 之所以会出现这样的问题, 也算是因为 JavaScript 的糟粕吧, 没有指针.

    最佳实践

    accessor-pairs 要求 Get 和 Set 同时出现

    🟢 使用该规则: error.

    如果只 Set, 没有 Get, 那么使用 Set 就是毫无意义的. 不过反之则可能是真实需求, 所以使用默认规则只限制前者即可.

    array-callback-return 数组某些方法的回调函数要求一定有返回值

    🟢 使用该规则: error.

    我们遇到过本该使用 for 却使用 map 的代码. 该规则能一定程度上避免问题, 但无法检测出有人随便返回了一个值的情况. 所以还是要大家统一思想啊, 尽量写明确, 简洁, 清晰的代码.

    block-scoped-var 无视 var 的作用域 hoisting

    🟡 没有使用该规则.

    在没有 let/const 时, 这个功能有用. 在 ES6 之后, 使用 no-var 就可避免这种语言问题.

    class-methods-use-this 类的方法必须使用 this

    🟢 使用该规则: error.

    如果一个类的方法没有使用到 this, 那么写成静态方法或者纯函数更好.

    complexity 嵌套复杂度

    🟢 使用该规则: ["error", 10]

    尽量将每个函数写小一点, 增加代码可读性. 但考虑到整体团队和项目具体的情况, 需要选择一个合适的值.

    consistent-return 一致性的返回

    🟢 使用该规则: error.

    帮助我们思考, 这个函数为什么要这样用, 该不该这样用, 同时避免一些低级错误如 map 的特殊情况忘了返回默认值.

    curly 要求写大括号

    🟢 使用该规则: error.

    主要算是代码风格上的要求. 但也是因为 JS 的大括号省略规则可读性差, 还是写个大括号吧.

    default-case 要求 switch 必须有 default

    🟢 使用该规则: error.

    主要是为了避免手误.

    [7.0] default-case-last 要求 switch 的 default 必须在末尾

    🟢 使用该规则: error.

    从语义上理解, 将兜底方案放在末尾是可读性最佳的. 可以通过这里看文档.

    default-param-last 函数有默认值的参数必须在最后

    🟢 使用该规则: error.

    在 JS 中函数可以有多个参数, 一般前面的必填, 后面的选填. 否则就会造成使用不便, 每次请求的时候都要传个无效值, 如 foo(undefined, 1). 有默认值的参数都是可选, 所以放在最好方面函数的使用.

    另外, 如果有多个可选参数, 建议使用 foo(need, options = {}) 的方式定义函数, 将可选参数都放入 options 内.

    dot-location 属性点号的位置

    🟢 使用该规则: ["error", "property"].

    这是关于风格一致性的约束. 不过实际中我们很少针对对象属性换行, 因为需要换行的时候, 一定是比较长了, 但我们需要避免这么长的命名出现. 如果真的需要, 我们希望在行首能知道, 同时要有缩进.

    dot-notation 必须使用点号来访问属性

    🟢 使用该规则: error.

    如果我们使用驼峰式命名, 那么这个一般是必要的. 但特殊情况下我们要处理后端直接返回的下划线风格命名时, 比如 SQL 列名, 就会出现问题, 建议遇到实际情况并且需要, 再使用 allowPattern 选项来允许特殊情况.

    eqeqeq 必须使用全等

    🟢 使用该规则: error.

    首先, 非全等并不会更快, 因为非全等是做了隐性的类型转换. 其次, 所有隐性的类型转换都是不建议的, 只会让错误更容易发生(哪怕只提升了 0.00001% 的错误概率), 并不能提高开发效率.

    在一些情况下, 有人希望使用 == null 来同时判断 null 与 undefined. 但我不建议这样做, 如果需要这样的判断, 单独做一个函数, 在函数内进行 disable rule 就行了.

    grouped-accessor-pairs 要求 Get/Set 相邻

    🟢 使用该规则: error.

    这是一个代码可读性的问题, 一个属性的 Get/Set 要相邻. 这个大家应该都同意吧.

    guard-for-in 谨慎使用 for in

    🟢 使用该规则: error.

    在大多数业务代码中, 都不需要使用 for in, 建议大家使用 for of 替代. for in 会遍历原型链, 一是没必要的慢, 二是很多时候我们不知道原型链中有什么.

    现实情况可能是大家不知道这些个 for 循环都有什么区别, 尤其是被网上的一些代码带偏了. ☹️

    max-classes-per-file 强制规定一个文件里面类的数量

    🟢 使用该规则: error.

    以前 React 没有 Hooks 时经常写类, 现在前端很少写类了. 后端 Node.js 在数据操作上, 还是有类的. 每种数据一个类, 一个文件, 管理起来很方便.

    no-alert 禁止使用 alert 等直接涉及 UI 的函数

    🟡 没有使用该规则.

    虽然历史原因是全局的, 但实际这些应该是 Window 的方法. 平时基本不会这些函数. 微信小程序等也是没有这些 Web API 的. 虽然会与 UI 界面不符, 但我真的希望浏览器能把这个功能做好, 我想用. 🌞

    no-caller 禁止匿名函数内部自调用

    🟢 使用该规则: error.

    出于性能考虑, 在 ES6 之后, arguments 就是不被推荐的了. 解决方法就是给函数命名.

    no-constructor-return 禁止构造函数的返回

    🟢 使用该规则: error.

    在构造函数中设置 return 是没有意义的. 如果出现, 一般都是写错了.

    no-div-regex 避免可能与除法混淆的正则写法

    🟢 使用该规则: error.

    使用引号来表示字符串, 使用 / 来表示正则. / 同时也可以表示除号, 这种一个符号两种用法在特定情况下会让人不容易理解. 可能出现歧义时, 我也建议使用 new RegExp 来表示正则.

    no-else-return 不使用没必要的 else

    🟢 使用该规则: error.

    梳理一下逻辑, 使用最简单有效并且可读的做法. 这个例子在我初学时对我影响很大. 初学时, 最大的疑问就是, 什么才算好代码?

    no-empty-function 避免空函数

    🟢 使用该规则: error.

    一般只有在未完成的时候才会保留空函数, 这个规则考虑到了该情况, 如果函数内有一些注释, 则不会报错.

    no-eq-null 禁止与 null 进行非全等比较

    🟡 没有使用该规则.

    不是说这个规则没用, 是因为 eqeqeq 规则已经做了限定.

    no-eval 禁止将字符串当作代码执行

    🟢 使用该规则: error.

    函数如其名. 这样做是非常不安全的.

    no-extend-native 禁止扩展原生对象

    🟢 使用该规则: error.

    对于大多数业务代码来说, 不要修改标准库, 任何情况下都可以找到替代方案.

    no-extra-bind 禁止不必要的绑定

    🟢 使用该规则: error.

    fn.bind() 的目的是用来在函数运行时指定 this 而不是使用当前 this, 如果函数内没有用到 this, 就没有任何意义.

    no-extra-label 禁止使用不必要的标签

    🟡 没有使用该规则.

    我们会通过 no-labels 来禁用标签, 所以这条规则没有使用.

    no-floating-decimal 禁止浮点数省略 0

    🟢 使用该规则: error.

    怎么说呢, 我认为这也是 JS 的语法糟粕. 不过还好, 在项目中我暂时没有遇到有人这么写代码.

    no-implicit-coercion 禁止隐晦的类型转换

    🟢 使用该规则: error.

    依然是 JS 的语法糟粕. 但类似 '' + something 的写法我还是见过的.

    no-implicit-globals 禁止隐晦的全局声明

    🟡 没有使用该规则.

    no-var 规则开启的时候, 这条规则失去了原有的意义. 而且现在项目都是模块化的代码, 所以没必要使用这条规则.

    no-implied-eval 禁止使用隐性 eval

    🟢 使用该规则: error.

    类似 no-eval 规则.

    no-invalid-this 禁止无效的 this 引用

    🟢 使用该规则: error.

    很多时候, 无效的 this 引用并不是说 this 是 undefined, 而是没必要这样去引用 this. 比如浏览器中, 全局使用 this 等同于 window, 使用 window 就好, 没必要使用 this. 还是让 this 只出现的类中吧.

    no-iterator 禁止使用 __iterator__ 属性

    🔵 可选使用该规则.

    在 ES6 以后, 使用迭代器来替代 __iterator__ 的功能. 禁用主要因为 __iterator__ 并不是一个标准.

    no-labels 禁用标签

    🟢 使用该规则: error.

    我从来没有见过有人使用 label 语法, 这语法本身的含义也让我困惑. 不过还好, 我知道, 它没用, 完全可以被更简单清晰的语法替代.

    no-lone-blocks 禁用不必要的大括号

    🟢 使用该规则: error.

    大多数情况下, 应该是手误提醒. 但在我开发的经验中, 没有遇到这种情况. 不过需要注意的是, 任何大括号都会创建一个作用域, 虽然这点在特殊情况下可能会有用, 但一般都可以使用另一种写法而没必要特意创建一个作用域.

    no-loop-func 禁止在循环中声明函数

    🟢 使用该规则: error.

    在循环中声明函数一般是为了将循环中的变量传入到函数中执行. 但我们不应该滥用闭包, 纯函数就能避免潜在的问题. 比如除了避免使用 var 的方法外, 我们还可以在使用 var 时这样做:

    let funcs = [];
    let t = v => (() => v);
    for (var i = 0; i < 10; i++) {
        funcs[i] = t(i);
    }
    

    我不是在鼓励大家使用 var, 而是在鼓励大家写纯函数并且善用闭包而不是滥用闭包.

    no-magic-numbers 禁止使用魔术标识符

    🟢 使用该规则: error.

    在这里, "魔术" 的意思是不知道是怎么回事儿, 但就是起作用了. 该规则主要是希望使用更良好命名的常量来规范代码. 触发该规则的大多数情况是在开发初期, 为了方便快捷而为之, 但无论如何, 良好的命名对整体工作都是有利而无害的.

    no-multi-spaces 禁止多个空格

    🟢 使用该规则: error.

    主要是代码风格上的规范. 让代码整体上可读性更好. 如果经常触发该规则, 可能是键盘的空格键坏了. 😛

    no-multi-str 禁止多行字符串

    🟢使用该规则: error.

    普通字符串的多行一般都是出错了. 如果在字符串中手动添加了换行符, 现在一般使用模板字符串来做字符串的多行, 这是一个比换行符更简单直观的办法.

    no-new 禁止单独使用 new

    🟢 使用该规则: error.

    如果不为赋值, 没必要使用 new. 如果构造函数中有什么想要做的, 写成纯函数更好.

    no-new-func 禁止使用 Function

    🔵 可选使用该规则.

    没必要把一个简单的事情做复杂, 尤其是 Function 的参数还有 eval 的味道.

    no-new-wrappers 禁止在原生类型上使用 new

    🟢 使用该规则: error.

    在做类型转换的时候 Number 等还是比较常用的, 但需要注意的时候, 这些时候都不能在前面加 new. 为了防止意外, 这条规则还是有意义的.

    no-octal-escape 禁止出现八进制字符转义

    🟢 使用该规则: error.

    在一些特殊情况下, 我们会使用字符转义. 现在基本所有编程语言都不支持八进制字符了, 均为 Unicode 或十六进制. 虽然 Unicode 会使用十六进制来表示, 但建议统一使用 Unicode, 即 /u 开头.

    no-param-reassign 禁止修改函数的参数

    🟢 使用该规则: error.

    在我看到的代码中, 这条规则非常不容易被遵守. 有些时候从性能考虑, 我们想直接修改函数外的变量. 但其中很多时候, 我们都在冒潜在的风险, 因为我们不知道将来谁还会使用这个函数.

    我建议还是将此规则打开, 如果需要, 在函数处写好注释然后临时关闭该规则.

    no-proto 禁止使用 __proto__

    🟢 使用该规则: error.

    这是已被标准丢弃的用法, 但我曾多次看到互联网上有古老的代码使用了这一特性. 目前这一功能仅应该在兼容库中看到, 而我们使用的东西早已不支持 IE6, IE8 了.

    图例:

    🟢 使用该规则. 🟡 没有使用该规则. 🔵 业务代码基本不会触发该规则, 选择性使用.

    6 条回复    2020-03-12 13:52:03 +08:00
    Yumwey
        1
    Yumwey  
       2020-03-10 20:14:31 +08:00
    为什么不直接看 airbnb?
    loading
        2
    loading  
       2020-03-10 20:22:49 +08:00
    ESLint 可以设置风格,常见的有:

    - Google
    - Airbnb
    - Idiomatic.JS
    - StandardJS
    iugo
        3
    iugo  
    OP
       2020-03-11 09:55:18 +08:00
    @Yumwey
    @loading

    当然好呀, 我也说了:

    "大多数情况下我都是不建议自己完善规则的, 因为 Airbnb 的规则已经足够好用了, React 也有自己的规则建议. 并且 TypeScript 能做的更多."

    只是在我们团队内部, 我觉得大家应该知其然, 知其所以然. 记录一下我的想法. 就像有论语译注, 也会有论语新解, 也还有李二娃的论语笔记.
    iugo
        4
    iugo  
    OP
       2020-03-11 10:09:22 +08:00
    刚好写到了 no-restricted-properties 这个规则, 这个一定是基于项目的, 项目升级后, 某些属性不再建议大家使用, 需要团队内部了解该规则, 针对性配置该规则.

    这是通用的规则配置做不到的.

    但我一定不是说通用的规则配置不好, 很好, 很建议. 只是当团队进入到某一阶段, 仅仅使用通用的规则配置已经不满足需求了, 我们需要详细了解还有哪些规则, 甚至在必要时自定义规则.
    RockShake
        5
    RockShake  
       2020-03-11 11:27:02 +08:00
    当团队已经有代码规范自定义要求, 这是一个团队成熟度的表现, 蛮佩服的
    iugo
        6
    iugo  
    OP
       2020-03-12 13:52:03 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5598 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 07:42 · PVG 15:42 · LAX 00:42 · JFK 03:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.