NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

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

评论

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

模块8作业

忘记喝水的猫

架构训练营

02 Prometheus之监控方法论及指标

穿过生命散发芬芳

Prometheus 1月月更

040022-week1-algorithm

InfoQ_70156470130f

Linux之find xargs

入门小站

【架构实战营】模块八作业

liu🍊

【LeetCode】一手顺子Java题解

Albert

算法 LeetCode 1月月更

模块八 设计消息队列存储消息数据的 MySQL 表格

小朱

架构实战营

看金沙遗址-理科生博物馆的正确打开方式

wood

成都 300天创作 博物馆 金沙遗址

一、什么是计算机

喵叔

28天写作 1月月更

莫让虚线管理形同虚设,再论研发组织的设计逻辑

菜根老谭

企业管理 研发组织 组织设计 虚线管理

设计原则与思想:单一职责原则

努力努力再努力

架构实战营模块八作业

spark99

架构实战营

设计消息队列存储消息数据的 MySQL 表格

渐行渐远

架构实战营

保姆级教程,终于搞懂脏读、幻读和不可重复读了!

王磊

[架构实战营] 模块四作业

Geek_0ed632

「架构实战营」

架构训练营 - 模块八作业

VegetableBird

架构训练营

架构训练营 - 模块 8 作业

焦龙

架构训练营

模块八作业

Geek_1d37ea

架构实战营

复盘2021,像做产品一样来做自媒体

菜根老谭

自媒体 菜根老谭

Kubernetes集群监控

Rayzh

Kubernetes 云原生 Prometheus

是分是合?探讨影响研发组织设计的主要因素

菜根老谭

企业管理 研发组织 组织设计

在线JSON转CSV,TSV工具

入门小站

工具

架构实战营 - 模块八作业

随风King

「架构实战营」

架构训练营 模块八

dog_brother

「架构实战营」

为什么每次加入一个新的团队,都会觉得遗留系统是一坨“屎”?

蔡超

重构 架构设计 团队文化

Excelize 2.5.0 正式发布,这些新增功能值得关注

xuri

Java golang Excel go语言 Excelize

模块八总结

Geek_1d37ea

架构训练营

Kubernetes集群日志搜集

Rayzh

Kubernetes 云原生 ELK Stack

架构训练营 模块八作业

吴霏

#架构训练营

设计消息队列存储消息数据的 MySQL 表

Beyond Ryan

Rust 入门 快速配置 Rust 开发环境并编写一个小应用!

贾献华

rust

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