写点什么

自定义 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:073672

评论

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

Flink的函数体系

阿泽🧸

flink 三周年连更

使用MASA全家桶从零开始搭建IoT平台(三)管理设备的连接状态

MASA技术团队

IoT MASA .NET 7

音视频八股文(11)-- ffmpeg avio 内存输入和内存输出。内存输出有完整代码,网上很少有的。

福大大架构师每日一题

c ffmpeg 福大大

AI 大底座,大模型时代的答卷

Baidu AICLOUD

大模型训练

Java 如何在 Array 和 Set 之间进行转换

HoneyMoose

小程序开发中的插件、组件、控件,傻傻分不清楚

没有用户名丶

平台工程助力企业提升研发效能

SEAL安全

研发效能 平台工程

网易伏羲RL4RS荣获SIGIR2023 Resource Paper,推动深度学习技术创新

网易伏羲

LED显示屏行业发展步伐

Dylan

发展 科技 LED显示屏

文盘Rust —— rust连接oss | 京东云技术团队

京东科技开发者

rust OSS 对象存储 rust语言 企业号 5 月 PK 榜

Java 如何在 Array 和 List 之间进行转换

HoneyMoose

怎样成为优秀的后端工程师

越长大越悲伤

后端、 java‘

万字长文——Go 语言现代命令行框架 Cobra 详解

江湖十年

golang 后端 命令行 命令行工具

Java实现多用户即时通信系统

timerring

Java

只需要六步!快速开启专属的风控系统

极客天地

持续交付下的分层自动化测试

单东东

DevOps 持续交付 持续测试 测试自动化 junit5

2分钟快速上手流水线的创建与运行

华为云开发者联盟

开发 华为云 华为云开发者联盟 企业号 5 月 PK 榜

什么是人工智能领域的深度学习?

汪子熙

人工智能 深度学习 强化学习 三周年连更

从原理到应用,人人都懂的ChatGPT指南 | 京东云技术团队

京东科技开发者

人工智能 AI ChatGPT4 企业号 5 月 PK 榜

探讨AIGC的崛起历程,浅析其背后技术发展

华为云开发者联盟

人工智能 华为云 AIGC 华为云开发者联盟 企业号 5 月 PK 榜

云原生日志收集机制和日志处理流程规范

穿过生命散发芬芳

日志分析 三周年连更

ChatGPT 中文指令指南,教会你如何使用chatgpt实现中文你想要的答案

汀丶人工智能

ChatGPT

并发编程:ErrGroup的正确使用

Jack

怎么在 vue 中使用 form 清除校验状态?

海拥(haiyong.site)

三周年连更

测试环境

乌龟哥哥

三周年连更

使用NineData定制企业级数据库规范

NineData

数据库 dba 企业管理工具 数据库开发工具 企业级数据库规范

Zebec 生态旗下 NFT协议 PlazaDAO宣布进军BRC20生态,有什么规划?

股市老人

简单好用的网页设计工具:EverWeb中文版

真大的脸盆

Mac 网页设计 Mac 软件 网页布局 网页制作

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