当前位置: 首页 > news >正文

ESLint 深度解析:原理、规则与插件开发实践

在前端开发的复杂生态中,保障代码质量与规范性是构建稳健、可维护项目的基石。ESLint 作为一款强大的代码检查工具,其默认规则与插件能满足多数常见需求,但面对特定团队规范或项目独特要求,自定义 ESLint 插件便成为有力的扩展手段。本文将深入探讨如何打造自定义 ESLint 插件,并结合实际案例,详细阐述从创建到应用的全过程。

一、ESLint 基础回顾

ESLint 通过静态分析代码,将其转换为抽象语法树(AST),进而依据规则对代码进行细致检查。这一过程始于对代码的解析,默认使用 Espree 解析器,它将代码转化为树形结构,每个节点代表一种语法结构。例如,对于简单代码let num = 10;,在 AST 中会呈现为VariableDeclaration节点。

  • VariableDeclaration节点 :用于表示变量声明。它包含以下重要属性:

    • declarations :是一个数组,存放变量声明符。在let num = 10;中,这个数组只有一个元素,即表示num变量的声明符。
    • kind :表示声明的类型,如let、const或var。在上述例子中,kind的值为let。

ESLint 利用这些 AST 信息,对照规则库,找出代码中的潜在问题,如未使用的变量、错误的语法等。

二、自定义插件的需求场景


在团队协作项目中,统一的代码风格和规范至关重要。除了常规的代码格式与最佳实践,还可能存在一些特殊要求。例如,为了维护代码的文明性与专业性,我们要求代码中不得出现诸如 “sb250”“fuck” 等不文明、不专业的词汇。这类需求无法通过 ESLint 的默认规则实现,因此需要开发自定义插件来满足。

三、自定义 ESLint 插件开发流程

(一)工程搭建

  • 初始化项目

    • 首先确保全局安装了yo和generator - eslint。若未安装,可通过以下命令进行安装:
npm i -g yo
npm i -g generator-eslint
  • 然后创建一个新目录用于插件项目,例如eslint - plugin - yinzhixiaxue,并进入该目录:
mkdir eslint-plugin-yinzhixiaxue
cd eslint-plugin-yinzhixiaxue
  • 执行yo eslint:plugin命令,这是一个交互式命令,需要填写相关信息:

    • 插件名称:例如eslint-plugin-yinzhixiaxue。
    • 插件描述:描述插件的功能,如 “用于检查代码中是否存在不文明词汇的 ESLint 插件”。
    • 是否包含自定义规则:选择Yes。
    • 是否需要处理器:根据实际需求选择,通常对于简单的规则检查选择No。
  • 安装依赖

    • 插件开发依赖eslint和eslint-utils库,通过以下命令安装:
npm install eslint eslint-utils --save - dev

(二)创建规则

  • 生成规则文件

    • 在项目目录下执行npx yo eslint:rule命令,同样是交互式操作:

      • 规则名称:例如no-offensive-words。
      • 规则描述:如 “禁止在代码中使用不文明词汇”。
      • 不通过的案例代码:可输入包含不文明词汇的代码示例,如let message = “fuck you”;。
    • 完成后,项目目录结构中会生成lib/rules/no-offensive-words.js文件,该文件用于编写具体的规则逻辑。

(三)规则配置与编写

  • 规则配置(meta对象)

在lib/rules/no-offensive-words.js文件中,首先定义meta对象,用于描述规则的元信息:\

module.exports = {meta: {type: 'problem', // 表示该规则识别的代码可能会导致问题,需要优先解决,取值还可以是'suggestion'(建议优化代码)或'layout'(关注代码布局,如空格、分号等)docs: {description: '禁止在代码中使用不文明词汇', // 规则的详细描述category: 'Custom Rules', // 规则的分类,便于在规则列表中进行归类展示recommended: true, // 表示该规则是否推荐使用,若为true,在继承相关配置时可能会默认启用该规则url: null // 规则文档的链接,可指向详细介绍该规则的页面,这里暂设为null},messages: {noOffensiveWords: '代码中不允许使用不文明词汇' // 定义规则触发时的错误提示信息,这里的'noOffensiveWords'是一个自定义的标识符,可在后续代码中引用},fixable: null, // 表示该规则是否支持自动修复,null表示不支持,'code'表示可修复代码问题,'whitespace'表示可修复空格相关问题schema: [] // 用于定义规则的配置选项,这里为空表示该规则没有额外的配置参数},// 规则具体实现将在create函数中编写
};
  • AST结构分析与规则编写(create函数)

ESLint 通过遍历 AST 来应用规则,因此需要了解代码对应的 AST 结构。对于代码let message = “fuck you”;,在 AST Explorer(https://astexplorer.net/)中解析后,VariableDeclaration节点包含message变量的声明信息,而变量的初始值"fuck you"则存储在init属性指向的Literal节点中。

我们使用Literal节点是因为在这个规则中,我们关注的是字符串字面量中是否包含不文明词汇。Literal节点专门用于表示各种字面量,如字符串、数字、布尔值等。在检查不文明词汇时,我们只需要关心字符串类型的字面量,所以使用Literal节点来获取并检查变量值。

基于此,编写create函数来实现规则:\

module.exports = {meta: {// 省略meta部分已有的内容},create: function (context) {const offensiveWords = ['sb250', 'fuck'];return {Literal(node) {if (typeof node.value ==='string') {offensiveWords.forEach((word) => {if (node.value.includes(word)) {context.report({node,messageId: 'noOffensiveWords'});}});}}};}
};


在上述代码中:

  • 定义了一个包含不文明词汇的数组offensiveWords。
  • 在create函数返回的对象中,使用Literal节点访问方法。当 ESLint 遍历 AST 遇到Literal节点(通常用于表示字符串、数字等字面量)时,若其值为字符串类型,则检查该字符串是否包含offensiveWords中的词汇。若包含,则使用context.report方法报告错误,错误信息使用meta.messages中定义的noOffensiveWords。

(四)配置规则组

在lib/rules/index.js文件中,将新创建的规则集成到插件中:

const requireIndex = require('requireindex');
const rules = requireIndex(__dirname + '/rules');
module.exports = {rules,configs: {recommended: {plugins: ['yinzhixiaxue'],rules: {'yinzhixiaxue/no-offensive-words': 'error'}}}
};


这里通过requireIndex引入自定义规则,在configs中定义了recommended配置组,将no-offensive-words规则设置为error级别,即一旦违反该规则,ESLint 将抛出错误。

(五)补充测试用例

在tests/lib/rules/no-offensive-words.js文件中编写测试用例,以验证规则的正确性:

const rule = require('../../../lib/rules/no-offensive-words');
const RuleTester = require('eslint').RuleTester;const ruleTester = new RuleTester();
ruleTester.run('no-offensive-words', rule, {valid: ['let message = "Hello world";','const num = 10;'],invalid: [{code: 'let message = "sb250 is not allowed";',errors: [{ messageId: 'noOffensiveWords' }]},{code: 'const greeting = "fuck this";',errors: [{ messageId: 'noOffensiveWords' }]}]
});


测试用例分为valid和invalid两组:

  • valid组包含符合规则的代码示例,这些代码应通过规则检查。
  • invalid组包含违反规则的代码示例,每个示例都指定了预期的错误信息messageId,用于验证规则是否按预期触发错误。

四、自定义插件的使用

(一)插件安装

  • 本地调试

在插件项目目录下执行npm link,然后在需要使用该插件的项目目录下执行npm link eslint-plugin-yinzhixiaxue。

  • 发布安装

将插件发布到 npm 仓库后,在项目中通过npm install eslint-plugin-yinzhixiaxue --save - dev进行安装。

(二)项目配置

在项目的.eslintrc文件中,添加插件配置:

{"extends": ["plugin:yinzhixiaxue/recommended"],"parserOptions": {"ecmaVersion": 6,"sourceType": "module"}
}


这里通过extends继承了eslint-plugin-yinzhixiaxue插件的recommended配置组,同时根据项目需求配置了parserOptions,例如支持 ES6 语法和模块语法。

(三)关于 extends 和 plugins 的深入理解

在 ESLint 的配置体系中,extends和plugins扮演着不同但又紧密关联的角色。

extends主要用于继承已有的配置集合 ,它可以是一个配置文件的路径、可共享配置的名称,或是plugin:插件名/配置组名的形式。以"extends": [“plugin:react/recommended”]为例,它会一次性启用react插件中recommended配置组里预先定义好的多个规则 ,这些规则涵盖了插件作者认为在大多数情况下适合项目使用的代码检查规范,比如react/jsx-uses-react、react/jsx-uses-vars等规则会同时生效,无需开发者逐个配置。这大大简化了配置流程,确保项目遵循特定插件推荐的整体规则集。

plugins则是用于引入第三方插件 ,扩展 ESLint 的功能边界。在使用插件前,需要先通过npm安装插件,然后在.eslintrc文件的plugins数组中添加插件名,如"plugins": [“eslint-plugin-demo”] 。引入插件后,若想启用插件中的规则,有两种常见方式。一是在rules中单独配置,例如想启用eslint-plugin-demo插件中的rule1规则,可以设置"eslint-plugin-demo/rule1": “error” ,这种方式适用于对插件规则有精细化控制,只启用部分规则的场景;二是结合extends,通过继承插件提供的配置组来批量启用规则,就像前面提到的"extends": [“plugin:react/recommended”] 。

extends会默认开启当前的所有,plugin需要自己手动开启

extends侧重于对已有配置的复用,让开发者能够快速应用一套成熟的规则体系;而plugins更专注于引入新的功能,无论是自定义规则还是特殊文件处理器。在实际项目中,二者通常相互配合,开发者可以根据项目的具体需求,先用plugins引入插件,再巧妙运用extends来启用插件中合适的配置组,从而精准定制出符合项目特点的代码检查方案。

通过以上步骤,我们成功创建并应用了一个自定义 ESLint 插件,能够有效检查代码中是否存在不文明词汇,进一步提升了代码的规范性与专业性,为团队协作和项目维护提供了有力保障。在实际开发中,可根据更多具体需求,灵活扩展和调整自定义插件的规则,以满足不断变化的项目要求。

技术交流沟通➕V:yinzhixiaxue

相关文章:

ESLint 深度解析:原理、规则与插件开发实践

在前端开发的复杂生态中,保障代码质量与规范性是构建稳健、可维护项目的基石。ESLint 作为一款强大的代码检查工具,其默认规则与插件能满足多数常见需求,但面对特定团队规范或项目独特要求,自定义 ESLint 插件便成为有力的扩展手段…...

洛谷P1091

题目如下 思路 谢谢观看...

随机树算法 自动驾驶汽车的路径规划 静态障碍物(Matlab)

随着自动驾驶技术的蓬勃发展,安全、高效的路径规划成为核心挑战之一。快速探索随机树(RRT)算法作为一种强大的路径搜索策略,为自动驾驶汽车在复杂环境下绕过静态障碍物规划合理路径提供了有效解决方案。 RRT 算法基于随机采样思想…...

江科大51单片机笔记【9】DS1302时钟可调时钟(下)

在写代码前,记得把上一节的跳线帽给插回去,不然LCD无法显示 一.DS1302时钟 1.编写DS1302.c文件 (1)重新对端口定义名字 sbit DS1302_SCLKP3^6; sbit DS1302_IOP3^4; sbit DS1302_CEP3^5;(2)初始化 因为…...

ssm_mysql_暖心家装平台

收藏关注不迷路!! 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,还有大家在毕设选题(免费咨询指导选题),项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多…...

一周学会Flask3 Python Web开发-SQLAlchemy简介及安装

锋哥原创的Flask3 Python Web开发 Flask3视频教程: 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili SQLAlchemy是Python编程语言下的一款开源软件。提供了SQL工具包及对象关系映射(ORM)工具,…...

< 自用文儿 > DELETED 设置速读 in Ubuntu24

systemctl 和 DELETED: 配置文件: vi /etc/systemd/system/ DELETED.service [Unit] DescriptionV2Ray Service Documentation DELETED Afternetwork.target nss-lookup.target[Service] #Usernobody CapabilityBoundingSetCAP_NET_ADMIN CAP_NET_BIN…...

自动化同步多服务器数据库表结构

当项目每次进行版本升级的时候,如果在这次迭代中涉及表结构变更,需要将不同的生产环境下,都需要同步表结构的DDL语句,比较麻烦,而且还有可能忘记同步脚本,导致生产环境报错.... 该方案采用SpringBootMybat…...

深入理解 HTML 元素:构建网页的基础

在网页开发的领域中,HTML(超文本标记语言)犹如一座大厦的基石,支撑起整个网页的结构与内容呈现。而 HTML 元素,则是构成这座基石的基本单位。今天,就让我们一同深入探索 HTML 元素的奥秘。 HTML 元素的构成…...

黄昏时间户外街拍人像Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色介绍 黄昏时分有着独特而迷人的光线,使此时拍摄的人像自带一种浪漫、朦胧的氛围 。通过 Lr 调色,可以进一步强化这种特质并根据不同的风格需求进行创作。Lr(Lightroom)作为专业的图像后期处理软件,提供了丰富的调色…...

OCPP扩展机制与自定义功能开发:协议灵活性设计与实践 - 慧知开源充电桩平台

OCPP扩展机制与自定义功能开发:协议灵活性设计与实践 引言 OCPP作为开放协议,其核心价值在于平衡标准化与可扩展性。面对不同充电桩厂商的硬件差异、区域能源政策及定制化业务需求,OCPP通过**扩展点(Extension Points&#xff09…...

哈希查找与深度优先遍历深度解析

一、算法基础概念对比 1.1 哈希查找的本质特征 哈希查找是一种基于哈希函数直接访问数据结构的查找技术,其核心在于通过数学映射建立键值与存储位置的直接关联。理想情况下时间复杂度可达O(1),实际应用中通过冲突处理机制实现近似常数时间的查找效率。…...

【powerjob】 powerjobserver注册服务IP错误

1、问题:powerjobserver 4.3.6 的服务器上有多个网卡对应多个ip,示例 eth0 :IP1 ,docker0:IP2 和worker 进行通信时 正确的应该时IP1 但是注册显示获取的确实IP2,导致 worker 通过ip2和server通信,网络不通,注册不上 2、解决方案 …...

Flutter底层实现

1. Dart 语言 Dart 是 Flutter 的主要编程语言。Dart 设计之初就是为了与 JavaScript 兼容,并且可以编译为机器代码运行。Dart 提供了一些特性,如异步支持(通过 async 和 await),这使得编写高效的网络请求和复杂动画变…...

亚信安全发布2024威胁年报和2025威胁预测

在当今数字化时代,网络空间已成为全球经济、社会和国家安全的核心基础设施。随着信息技术的飞速发展,网络连接了全球数十亿用户,推动了数字经济的蓬勃发展,同时也带来了前所未有的安全挑战。2024年,网络安全形势愈发复…...

【YOLOv12改进trick】StarBlock引入YOLOv12,创新涨点优化,含创新点Python代码,方便发论文

🍋改进模块🍋:StarBlock 🍋解决问题🍋:采用StarBlock将输入数据映射到一个极高维的非线性特征空间,生成丰富的特征表示,使得模型在处理复杂数据时更加有效。 🍋改进优势🍋:简单粗暴的星型乘法涨点却很明显 🍋适用场景🍋:目标检测、语义分割、自然语言处理…...

Android MVI架构模式详解

MVI概念 MVI(Model-View-Intent)是一种Android应用架构模式,旨在通过单向数据流和不可变性来简化应用的状态管理。MVI的核心思想是将用户操作、状态更新和界面渲染分离,确保应用的状态可预测且易于调试。 MVI的核心组件 Model&a…...

Spring AI Alibaba + Ollama:国产大模型DeepSeek LLM的低成本AI应用开发认知

写在前面 官方文档很详细,有开发需求可以直接看文档https://java2ai.com/docs/1.0.0-M5.1/get-started/博文内容为一个开发Demo,以及API简单认知理解不足小伙伴帮忙指正 😃,生活加油 我看远山,远山悲悯 持续分享技术干货&#xf…...

《2025软件测试工程师面试》功能测试篇

什么是功能测试? 功能测试是通过验证产品功能是否满足用户需求的过程,主要关注软件的功能是否符合需求规格说明,包括软件的各种功能、特性、性能、安全性和易用性等。 功能测试的流程包括哪些步骤? 需求分析:明确软件需求,确定测试范围。测试计划:制定详细的测试计划,…...

蓝桥杯2024年第十五届省赛真题-传送阵

题目描述 小蓝在环球旅行时来到了一座古代遗迹,里面并排放置了 n 个传送阵,进入第 i 个传送阵会被传送到第 ai 个传送阵前,并且可以随时选择退出或者继续进入当前传送阵。小蓝为了探寻传送阵中的宝物,需要选择一个传送阵进入&…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

【JVM】- 内存结构

引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...