写点什么

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

评论

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

Android C++系列:C++最佳实践3继承与访问控制

轻口味

c++ android ndk 4月月更

大咖实战|Kubernetes自动伸缩实现指南分享

云智慧AIOps社区

Docker 云计算 Kubernetes 容器 云原生

TiUP:TiDBAer 必备利器

PingCAP

TiDB

我,机器学习工程师,决定跑路了

OneFlow

机器学习 深度学习 AI 程序人生 MLOps

最受欢迎的5种编程语言各有什么特点或优点?

源字节1号

软件开发 后端开发 编程语言、

找工作,你被“卷”到了吗?

InfoQ写作社区官方

招聘 就业 热门活动 拉勾招聘

jackson学习之九:springboot整合(配置文件)

爱好编程进阶

Java 面试 后端开发

GPU底层技术、全球市场格局分析

Finovy Cloud

人工智能 云计算 云服务器 GPU服务器 GPU算力

大型IM系统有多难?万字长文,搞懂异地多活!

BeeWorks

jackson学习之三:常用API操作

爱好编程进阶

Java 面试 后端开发

web前端培训如何使用CSS连接数据库

@零度

CSS 前端开发

源码级别的广播与监听实现

阿Q说代码

spring源码 实战 监听 4月月更 广播

大数据培训经典SQL面试题解析

@零度

sql 大数据开发

Apache ShardingSphere 5.1.1 正式发布

SphereEx

Apache 数据库 开源 ShardingSphere SphereEx

Pipy 性能基准测试的思考与实践

Flomesh

代理 benchmark Pipy

【直播回顾】OpenHarmony 3.1 Release版本南北向关键能力解读

OpenHarmony开发者

OpenHarmony 直播回放

JAVA 最常用实用的正则表达式校验

爱好编程进阶

Java 面试 后端开发

如何撰写出有效的帮助文档内容?

小炮

帮助文档

java培训:java流中的异常处理方法分享

@零度

JAVA开发 java流

ZEGO 最后一公里网络传输的容灾及优化方案

ZEGO即构

后台开发 容灾 最后一公里

CentOS 停止维护,一文看懂升级迁移路径

亚马逊云科技 (Amazon Web Services)

Tech 专栏

client-go实战之五:DiscoveryClient

爱好编程进阶

Java 面试 后端开发

client-go实战之四:dynamicClient

爱好编程进阶

Java 面试 后端开发

Elasticsearch文档读写模型实现原理

爱好编程进阶

Java 面试 后端开发

自己动手写Docker系列 -- 6.1 ip分配管理

Go Docker 4月月更

Linux驱动开发-编写按键驱动

DS小龙哥

4月月更 Linux驱动

助力 60+ 市区管理建设,TDengine 联手数字政通打造智慧城市平台

TDengine

数据库 tdengine 时序数据库

视频画质增强最优解:微帧科技视频超高清引擎

微帧Visionular

计算机视觉 视频增强 电影修复

OpenHarmony 3.1 Release正式发布,标准系统全方位升级!

叶落便知秋

API 分页探讨:offset 来分页真的有效率吗?

爱好编程进阶

Java 面试 后端开发

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