写点什么

自定义 ESLint 规则,让代码持续美丽

  • 2021-04-06
  • 本文字数:3676 字

    阅读完需:约 12 分钟

自定义 ESLint 规则,让代码持续美丽

背景


一段真实的代码发展历史


很久很久以前,有一个需求,然后产出了一段代码,代码优雅而简洁


export const getConfig = (param1, param2) => {  return ...};
复制代码


不久又来了个需求,加个参数扩展,so easy!


export const getConfig = (param1, param2, param3) => {  return ...};
复制代码


经过多次产品需求迭代后,现在的代码



export const getConfig = (param1, param2, param3, param4, param5, param6, param7……) => {  return ...};
复制代码


在产品迭代过程中,上面的 case 一个函数的参数从 2 个发展到了 7 个,优雅的代码逐渐变为不可维护。这是什么问题?这归咎于日益增长的需求,快速响应和代码质量之间的矛盾。


那如何避免呢?


  • 制定代码规范

  • 靠开发同学的自我修养

  • 进行 Code Review

  • 工具提示

  • 发版控制,不允许发版


制定代码规范肯定是需要的,那如何约束代码呢?规范文档宣讲,再凭借开发同学的自我修养?答案是:无法保证。


Code Review ?但难免也有落网之鱼。发版控制?能有效解决但是开发体验不好。


如果我们在开发者写代码的时候就及时给到提示和建议,那开发体验就很棒了,而 ESLint 的自定义规则就可以实现在开发过程中给开发同学友好的提示。


ESLint 原理


ESLint 是一个代码检查工具,通过静态的分析,寻找有问题的模式或者代码。默认使用 Espree  解析器将代码解析为 AST 抽象语法树,然后再对代码进行检查。


看下最简单的一段代码使用 espree 解析器转换成的抽象语法树结构,此处可以使用 astexplorer  快速方便查看解析成 AST 的结构:


代码片段:

var a = 1;
复制代码

转换出的结果:

{  "type": "Program",  "start": 0,  "end": 10,  "range": [    0,    10  ],  "body": [    {      "type": "VariableDeclaration",      "start": 0,      "end": 10,      "range": [        0,        10      ],      "declarations": [        {          "type": "VariableDeclarator",          "start": 4,          "end": 9,          "range": [            4,            9          ],          "id": {            "type": "Identifier",            "start": 4,            "end": 5,            "range": [              4,              5            ],            "name": "a"          },          "init": {            "type": "Literal",            "start": 8,            "end": 9,            "range": [              8,              9            ],            "value": 1,            "raw": "1"          }        }      ],      "kind": "var"    }  ],  "sourceType": "module"}
复制代码


代码转换为 AST 后,可以很方便的对代码的每个节点对代码进行检查。


自定义 ESLint 规则开发


怎么自定义

语法树分析


对目标代码进行语法树解析,可使用 astexplorer 


编写规则


下面是一个规则简单的结构(官方 API 文档说明


module.exports = {  meta: {    docs: {      description: "最多参数允许参数",    },  },  create: function (context) {    return {      FunctionDeclaration: (node) => {        if (node.params.length > 3) {          context.report({            node,            message: "参数最多不能超过3个",          });        }      },    };  },};
复制代码


  • meta(对象)包含规则的元数据

  • create ( function ) 返回一个对象,其中包含了 ESLint 在遍历 JavaScript 代码的抽象语法树 AST ( ESTree 定义的 AST ) 时,用来访问节点的方法

  • context.report ( )  用来发布警告或错误,并能提供自动修复功能(取决于你所使用的配置)


最简单的示例(只使用 node 和 message 参数):


context.report({    node,    message: "参数最多不能超过3个",});
复制代码


使用上面的这个规则,结合编辑器就有了对整个 node 节点的提示,如果需要更精确的错误或警告提示,我们可以使用 loc 参数,API 文档说明 。



如何使用自定义规则


使用自定义的 ESLint 规则,你需要自定义一个 ESLint 的插件,然后将规则写到自定义的 ESLint 插件中,然后在业务代码中添加 ESLint 配置,引入 ESLint 插件。


ESLint 插件

创建


创建一个 ESLint plugin,并创建 一个 ESLint rule

基于 Yeoman generator (https://yeoman.io/authoring/) ,可以快速创建 ESLint plugin 项目。


npm i -g yonpm i -g generator-eslint// 创建一个pluginyo eslint:plugin// 创建一个规则yo eslint:rule
复制代码


创建好的项目目录结构:


  • rules 文件夹存放的是各个规则文件

  • tests 文件夹存放单元测试文件

  • package.json 是你的 ESLint 插件 npm 包的说明文件,其中的 name 属性就是你的 ESLint  插件的名称,命名规则:带前缀 eslint-plugin-



// 示例代码:// lib/rules/max-params.jsmodule.exports = {  meta: {    docs: {      description: "最多参数",    },  },  create: function (context) {    /**     * 获取函数的参数的开始、结束位置     * @param {node} node AST Node      */    function getFunctionParamsLoc(node) {      const paramsLength = node.params.length;      return {        start: node.params[0].loc.start,        end: node.params[paramsLength - 1].loc.end,      };    }    return {      FunctionDeclaration: (node) => {        if (node.params.length > 3) {          context.report({            loc: getFunctionParamsLoc(node),            node,            message: "参数最多不能超过3个",          });        }      },    };  },};
复制代码


// 补充测试用例// /tests/lib/rules/max-params.jsvar ruleTester = new RuleTester();ruleTester.run("max-params", rule, {  valid: ["function test(d, e, f) {}"],  invalid: [    {        code: "function test(a, b, c, d) {}",        errors: [{            message: "参数最多不能超过3个",        }]    },  ],});
复制代码

ESLint 插件安装


在需要的业务代码中安装你的 ESLint 插件。(eslint-plugin-my-eslist-plugin 是你的 ESLint 插件 npm 包的包名)


npm install eslint-plugin-my-eslist-plugin 
复制代码


如果你的 npm 包还未发布,需要进行本地调试:

可使用 npm link 本地调试,npm link 的使用 。


配置


添加你的 plugin 包名(eslint-plugin- 前缀可忽略) 到 .eslintrc 配置文件的 plugins 字段。


.eslintrc 配置文件示例:


{    "plugins": [        "zoo" // 你的 ESLint plugin 的名字    ]}
复制代码

rules 中再将 plugin 中的规则导入。⚠️ ESlint 更新后,需要重启 vsCode,才能生效。( vsCode  重启快捷方式:CTRL +SHITF + P,输入 Reload Window )


此处涉及 ESLint 的规则设置(参考说明


{    "rules": {        "zoo/rule-name": 2    }}
复制代码


效果



更多的应用场景


除了上面说的硬编码的场景,还可以将沉淀出的最佳实践和业务规范通过自定义 ESLint 的方式来提示开发者,这对于多人协助、代码维护、代码风格的一致性都会有很大的帮助。


更多的应用场景有:


  • Input 必须要有 maxlength 属性,防止请求的后端接口数据库异常

  • 代码中不能出现加减乘除等计算,如果需要计算应该引入工具函数,来控制由于前端浮点数计算引起的 Bug

  • 规范限制,单位元的两边的括号要用英文括号,不能用中文括号,来达到交互展示统一的效果

  • 代码中不能使用 OSS 地址的静态资源路径,应该使用 CDN 地址的资源路径

  • ...



头图:Unsplash

作者:七喜

原文:https://mp.weixin.qq.com/s/zDTRB9BQFbzj6SeAM7mVcA

原文:自定义 ESLint 规则,让代码持续美丽

来源:政采云前端团队 - 微信公众号 [ID:Zoo-Team]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2021-04-06 22:073489

评论

发布
暂无评论
发现更多内容

CentOS6搭建nginx+uwsgi+flask

haiger13

签约计划第三季

浅聊偏函数

掘金安东尼

JavaScript 函数式 8月月更

开源一夏|ArkUI如何自定义弹窗(eTS)

坚果

开源 HarmonyOS OpenHarmony 8月月更

FinClip,车载小程序新玩法

Geek_99967b

小程序

《The Google File System》新说

Joseph295

《福格行为模型》:如何养成好习惯?

郭明

读书笔记

《迁移学习导论》第2版,升级内容抢先看!

博文视点Broadview

华为开源:聚焦开源基础软件,共建健康繁荣生态

科技热闻

Build QEMU RISC-V Linux

贾献华

8月月更

语音社交app源码——具备哪些开发优势?

开源直播系统源码

软件开发 语聊房 直播系统源码 语音聊天系统 语音聊天app

一文带你了解 Java 中的构造器

踏雪痕

Java 构造函数 8月月更

8月总结高频vue面试题

helloworld1024fd

Vue

React的理念与V16的架构变化

郭明

React

Rust 入门指南 (用 WASM 开发第一个 Web 页面)

王泰

rust Wasm WebAssenbly ​Rust

LeetCode第三题(Longest Substring Without Repeating Characters)三部曲之三:两次优化

程序员欣宸

Java LeetCode 8月月更

开源一夏 | 查询分页不只有limit,这四种分页方法值得掌握

知识浅谈

开源 8月月更

Jina 实例秀|七夕神器!比你更懂你女友的口红AI

Jina AI

七夕 神经网络架构搜索

第1章:初识数据库与MySQL----MySQL安装

乌龟哥哥

8月月更

再次搞定 Ali 云函数计算 FC

小鑫同学

签约计划第三季

Jina 实例秀|基于神经搜索的网络安全威胁检测(一)

Jina AI

神经网络架构搜索 Python.

C#/VB.NET:在 Word 中设置文本对齐方式

Geek_249eec

C# word VB.NET 文本对齐

关于技术学习的6个观点

郭明

技术人

免费的公共WiFi不要乱连,遭中间人攻击了吧?

wljslmz

网络安全 签约计划第三季 8月月更 中间人攻击

架构实战营模块三作业

zhihai.tu

Java 是否应该使用通配符导入( wildcard imports)

HoneyMoose

【CSS】设置文本样式,包括文本颜色、对齐、缩进、行高等

翼同学

CSS HTML5, CSS3 8月月更

带你造轮子,自定义一个随意拖拽可吸边的悬浮View组件

yechaoa

android 开源 签约计划第三季 8月月更

IDEA 自动导入的配置(Auto import)

HoneyMoose

MySQL之my.cnf配置文件

TimeFriends

8月月更

系统管理-Linux系统文件查找

Albert Edison

Linux centos linux 文件权限控制 find 8月月更

自定义 ESLint 规则,让代码持续美丽_语言 & 开发_政采云前端团队_InfoQ精选文章