写点什么

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

评论

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

那些年用星环产品解决的业务难点…

星环科技

征文 星环科技

都2021年了,你还在用Jenkins?赶快看看这些替代方案吧

编程菌

Java 编程 程序员 计算机 技术宅

阿里资深架构师熬夜纯手写的238页微服务容器化开发实战笔记

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

iOS App注入SDK调试

GrowingIO技术专栏

ios sdk 逆向 注入sdk

分享我的华为面经,华为OD岗笔试+面试心得,本人已成功入职!

编程菌

Java 华为 程序员 面试 计算机

上线直接霸占GitHub榜一!腾讯内部spring全家桶笔记细节拉满!

Java 编程 架构 腾讯 面试

阿里技术3面+HR面,奋战两个月,终斩获offer定级阿里P6+

编程菌

Java 编程 程序员 面试 计算机

带你破解DDOS攻击的原理

网络安全学海

黑客 网络安全 信息安全 渗透测试 漏洞挖掘

备战92天终入阿里,这份Java后端开发者面试技能笔记功不可没,共勉

Java~~~

Java spring 架构 面试 微服务

百度世界大会2021: 与时代共振,AI让生活更好

百度大脑

人工智能

Web JS SDK 架构解析

神策技术社区

技术 源码分析 神策数据

你真的懂Redis与MySQL双写一致性如何保证吗?

Linux服务器开发

MySQL redis 中间件 架构师 Linux服务器开发

智能CRM销氪强势崛起, CRM赛道变数几何?

ToB行业头条

CRM

智能量化交易系统搭建|量化交易APP系统源码开发

量化系统19942438797

量化交易 智能量化

Web端实现RTC视频特效的解决方案

网易云信

裸辞闭关62天,啃下这些分布式技术笔记,有幸通过阿里Java岗P6面试

Java~~~

Java 架构 面试 分布式 高可用

面试侃集合 | ArrayBlockingQueue篇

码农参上

队列 8月日更

终于学完了阿里P8架构师7年心血整理总结的微服务实战文档

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

Reality Capture 初探

空城机

3D渲染 3D模型 8月日更 Reality Capture

大二上半学期还挂科两门,大三上半学期就找到了外企实习工作,半年时间,我是怎么逆袭的?

编程菌

Java 编程 程序员 面试 计算机

实时数据引擎系列(一): 新鲜的数据流

tapdata

数据库 hadoop Tapdata 实时数据引擎 OLTP

【Vue2.x 源码学习】第四十篇 - 组件部分 - 组件的生命周期

Brave

源码 vue2 8月日更

斯图飞腾发布《如何将客户反馈转化为有价值的商业洞察》白皮书

Swift 与 Objective-C:您应该为下一个 iOS 移动应用选择哪个语言?

iOSer

ios objective-c swift ios开发

数字货币量化交易平台源码搭建|量化交易所自动交易软件开发

Geek_23f0c3

去中心化交易所系统开发 量化跟单 合约量化

网络安全产品之堡垒机介绍以及应用案例

行云管家

网络安全 数据安全 堡垒机 成功案例

阿里技术大牛终于分享出了解决我多年困扰的微服务开发架构文档

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

腾讯T8面试官纯手打总结Java888道高频面试真题笔记+Java面试金典

Java~~~

Java 架构 面试 算法 JVM

85W美团架构师分享深入解析Java虚拟机HotSpot文档

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

这份Github神仙笔记覆盖了90%以上的Java面试题,带你所向披靡

Java~~~

Java spring 架构 面试 微服务

金九银十你打算用什么硬核技能噎死面试官呢?附Java面试核心笔记

Java~~~

Java spring 架构 面试 微服务

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