首页/新闻资讯/正文详情

GitHub Desktop 自定义 ESLint 规则全解析:从规则目录到源码与测试实践

发布时间:2026/9/27 7:11:31 来源:云帆数科 栏目:资讯中心
GitHub Desktop 自定义 ESLint 规则全解析:从规则目录到源码与测试实践
开发工具桌面应用【免费下载链接】desktopFork of GitHub Desktop to support various Linux distributions项目地址https://gitcode.com/gh_mirrors/des/desktop点击查看免费下载本篇技术指南围绕 GitHub Desktopdesktop/desktop仓库中 eslint-rules/README.md 展开系统讲解该项目自研 ESLint 规则的设计动机、目录结构、两类型规则体系、本地校验与测试方法并逐一剖析五个内置自定义规则insecure-random、react-proper-lifecycle-methods、react-no-unbound-dispatcher-props、react-readonly-props-and-state、no-loosely-typed-webcontents-ipc的源码实现与测试用例帮助你在自己的 TypeScript React Electron 项目中复刻这套「编译期拦截错误」的工程实践。为什么 GitHub Desktop 需要自定义 ESLint 规则GitHub Desktop 是一个以 TypeScript 为主、基于 React Electron 的桌面应用代码规模横跨 app/src渲染进程 UI与 app/src/main-process主进程。项目在 .eslintrc.yml 中同时启用了大量来自社区插件的规则但仍有几类问题「没有现成规则可覆盖」项目特有的架构约定例如 dispatcher 方法必须绑定this才能作为回调传递安全类问题例如使用Math.random()生成随机字节类型系统的语义约束例如 props/state 接口成员必须readonly、React 生命周期方法签名必须与类型参数一致Electron IPC 的强类型封装要求禁止直接调用松散类型的webContents.send。因此项目在根目录的eslint-rules/目录下自行编写规则并通过.eslintrc.yml在项目根部统一配置。所有自定义规则在 .eslintrc.yml 的CUSTOM区块中声明且全部以error级别启用意味着任何一处违规都会直接导致 lint 失败。仓库目录结构速览eslint-rules/ ├── README.md # 规则设计文档本文主题 ├── tsconfig.json # 规则自身的类型检查配置 ├── insecure-random.js # 规则 1禁止不安全的随机数来源 ├── no-loosely-typed-webcontents-ipc.js # 规则 2禁止松散类型的 webContents IPC ├── react-no-unbound-dispatcher-props.js # 规则 3禁止未绑定的 dispatcher 回调 ├── react-proper-lifecycle-methods.js # 规则 4React 生命周期方法签名校验 ├── react-readonly-props-and-state.js # 规则 5props/state 必须只读 └── tests/ ├── insecure-random.test.js ├── react-no-unbound-dispatcher-props.test.js ├── react-proper-lifecycle-methods.test.js └── react-readonly-props-and-state.test.js规则实现文件与对应测试文件一一对应除no-loosely-typed-webcontents-ipc外均有独立测试测试统一放在 eslint-rules/tests 目录下。新增一条规则前先查现有插件README 明确给出项目已在使用的插件清单新增规则前必须确认没有现成替代typescript-eslint/eslint-pluginpackage.json 中为^6.13.2eslint-plugin-babeleslint-plugin-jsdoc^43.0.1eslint-plugin-json^2.1.1eslint-plugin-prettier^3.1.4eslint-plugin-react^7.33.2以及 devDependencies 中的eslint-plugin-github^4.10.1。只有当这些插件无法覆盖需求时才把规则加入eslint-rules/并在 .eslintrc.yml 中注册。两种规则形态TS-aware 与纯 AST 规则README 将自定义规则划分为两类形态能力依赖项目示例TypeScript-aware 规则可检查 AST 及类型相关信息typescript-eslint解析器与typescript-estreereact-proper-lifecycle-methods常规 ESLint 规则仅需语法层面的 AST 检查标准 ESLint 规则 APIreact-no-unbound-dispatcher-props、insecure-random、react-readonly-props-and-state、no-loosely-typed-webcontents-ipc以react-proper-lifecycle-methods为例它通过typescript-eslint/typescript-estree提供的TSESTree类型定义如ClassDeclaration、MethodDefinition、Parameter来定位类的类型参数进而校验生命周期方法而react-no-unbound-dispatcher-props只对JSXExpressionContainer节点做正则匹配完全不需要类型信息。本地校验yarn check:eslint自定义规则代码带有// ts-check指令并尽可能添加 JSDoctype注解通过项目根目录的yarn check:eslint进行类型检查$ yarn check:eslint该脚本在 package.json 中定义为check:eslint: tsc -P eslint-rules/即用tsc按 eslint-rules/tsconfig.json 编译规则目录。该 tsconfig 的关键配置如下{ compilerOptions: { allowJs: true, checkJs: true, noEmit: true, target: ES2021, skipLibCheck: true, moduleResolution: node }, include: [*.js, test/*.js] }allowJscheckJs让tsc对纯 JS 规则文件做类型检查noEmit保证只检查不产出文件include覆盖规则本体与tests/下的测试文件。所有规则文件的头部都带有// ts-check并通过typedef {import(eslint).Rule.RuleModule} RuleModule之类的注解声明模块类型确保类型检查器能理解 ESLint 规则模块结构。本地测试yarn test:eslint测试文件与规则同放在eslint-rules/tests/从项目根目录执行$ yarn test:eslint对应脚本定义package.jsontest:eslint: jest eslint-rules/tests/*.test.js它直接调用 jest 运行eslint-rules/tests/*.test.js下的所有测试。每个测试套件通过RuleTester对规则注入「合法」与「非法」代码片段并断言非法片段应报出哪些消息 ID。用 VSCode 调试自定义规则README 提供了把调试任务加入.vscode/launch.json的配置{ command: yarn test:eslint, name: Test ESLint scripts, request: launch, type: node-terminal }将该对象追加到configurations数组后即可在 VSCode 中直接运行该任务调试器会附着到 jest 进程配合测试用例逐步单步执行规则代码。五个内置自定义规则逐一剖析1.insecure-random拦截不安全的随机数来源实现文件eslint-rules/insecure-random.js该规则基于 tslint-microsoft-contrib 的insecureRandomRule改编目的是杜绝使用非加密安全的随机数 API。它监听CallExpression命中以下两种情况即报错Math.random()—— 报mathRandomInsecure提示改用crypto.randomBytes()或window.crypto.getRandomValues()crypto.pseudoRandomBytes()或解构出的pseudoRandomBytes()—— 报pseudoRandomBytesInsecure提示改用crypto.randomBytes()。关键实现片段CallExpression(node) { const { callee } node if ( callee.type MemberExpression callee.object.type Identifier callee.object.name Math callee.property.type Identifier callee.property.name random ) { context.report({ node, messageId: mathRandomInsecure }) } // ...pseudoRandomBytes 分支同理 }测试 eslint-rules/tests/insecure-random.test.js 覆盖合法crypto.randomBytes()、window.crypto.getRandomValues()非法Math.random()、crypto.pseudoRandomBytes()、解构的pseudoRandomBytes()调用。2.react-no-unbound-dispatcher-props杜绝未绑定的 dispatcher 回调实现文件eslint-rules/react-no-unbound-dispatcher-props.js这是高度 GitHub Desktop 定制化的规则针对项目里「把 dispatcher 方法直接当回调传给组件」这一常见运行时错误。规则头注释给出了反例与正解// 反例resetSidebarWidth 被调用时 this 不是 dispatcher 实例运行时报错 Resizable onReset{this.props.dispatcher.resetSidebarWidth} / // 正解提取为绑定实例方法后再传入 private handleReset () { this.props.dispatcher.resetSidebarWidth } // ... Resizable onReset{this.handleReset} /实现上规则在JSXExpressionContainer节点中用正则^\{this\.props\.dispatcher\.检测 JSX 表达式是否直接引用 dispatcher 方法命中即报unboundMethodJSXExpressionContainer(node) { const text sourceCode.getText(node) if (/^\{this\.props\.dispatcher\./.test(text)) { const textWithoutContainer text.slice(1, text.length - 1) context.report({ node, messageId: unboundMethod, data: { text: textWithoutContainer } }) } }测试 eslint-rules/tests/react-no-unbound-dispatcher-props.test.js 中合法样本是箭头函数包裹的() { this.props.dispatcher.resetSidebarWidth }非法样本正是文档中的Resizable onReset{this.props.dispatcher.resetSidebarWidth} /并断言报出unboundMethod且text为this.props.dispatcher.resetSidebarWidth。3.react-readonly-props-and-state强制 props/state 接口只读实现文件eslint-rules/react-readonly-props-and-state.js该规则针对项目中「技术上可以改this.props但永远不该改」的事实强制所有以Props或State结尾的 TypeScript 接口成员声明为readonly。它监听TSInterfaceDeclarationTSInterfaceDeclaration(node) { if (node.id.name.endsWith(Props)) { ensureReadOnly(node.body) } if (node.id.name.endsWith(State)) { ensureReadOnly(node.body) } }ensureReadOnly对每个TSPropertySignature成员做两项检查未标记readonly时报signaturesShouldBeReadonly类型为Array...或...[]时报arraySignaturesShouldBeReadonly要求改用ReadonlyArray。注意该规则在create入口处对.ts文件直接返回空对象仅.tsx参与检查react-proper-lifecycle-methods也有同样的.ts跳过逻辑——这两个规则只面向 UI 组件文件。测试 eslint-rules/tests/react-readonly-props-and-state.test.js 验证readonly name: string合法name: string报signaturesShouldBeReadonlyArraystring与string[]均报arraySignaturesShouldBeReadonly不以 Props/State 结尾的接口如ISomeOtherThing不受影响。4.react-proper-lifecycle-methods校验 React 生命周期方法签名实现文件eslint-rules/react-proper-lifecycle-methods.js这是五个规则中最复杂的一个也是 README 明确列举的「TypeScript-aware 规则」代表。它针对 React 类组件的生命周期方法保证方法名、参数名、参数类型与组件声明的泛型类型参数一致。整体流程如下识别 React 组件extendsReactComponent(node)判断类的父类是React.Component或React.PureComponent提取类型参数getPropsType/getStateType从React.ComponentProps, State的superTypeParameters中解析出 props 与 state 类型名支持TSTypeReference如ICloningRepositoryProps空类型字面量{}亦被处理校验方法签名对以component或shouldComponent开头的方法逐一校验。各生命周期方法的期望参数如下表方法期望参数名称 类型componentWillMount/componentDidMount/componentWillUnmount无参数componentWillReceivePropsnextProps: PropscomponentWillUpdatenextProps: Props、nextState: StatecomponentDidUpdateprevProps: Props、prevState: StateshouldComponentUpdatenextProps: Props、nextState: State其他component*/shouldComponent*命名报reservedMethodName易与生命周期方法混淆禁止使用verifyParameters还允许「省略参数」——即少写参数不报错但多出的参数会报unknownParameter每个已声明参数依次通过verifyParameter做名称nameMismatch与类型typeMismatch双重校验。规则在 meta 中声明为fixable: code且schema: []不接收任何选项。测试 eslint-rules/tests/react-proper-lifecycle-methods.test.js 覆盖了完整的合法/非法矩阵例如shouldComponentUpdate(foo: string)报nameMismatch应为nextProps与typeMismatch应为ICloningRepositoryPropsshouldComponentUpdate(nextProps, foo)报第二个参数nameMismatch应为nextState多余参数additionalParam报unknownParametercomponentWillDoSomething、shouldComponentFoo这类以保留前缀命名的方法报reservedMethodName普通类非 React 组件中出现同名方法不报错。5.no-loosely-typed-webcontents-ipc强制使用强类型 IPC 封装实现文件eslint-rules/no-loosely-typed-webcontents-ipc.js该规则与 .eslintrc.yml 中针对electron的no-restricted-imports配置形成互补——后者禁止直接导入ipcRenderer/ipcMain要求改用项目自建的强类型封装前者则拦截渲染进程侧直接调用webContents相关方法。核心逻辑isLooselyTypesWebContentsCall监听CallExpression与OptionalCallExpression命中以下任意形态即报useStronglyTypedWebContentsIPCwc.send(...)标识符直接名为wcxxx.webContents?.send(...)或xxx.webContents.send(...)裸的webContents.send(...)。报错消息明确提示「请改用ipc-webcontents提供的强类型 IPC 辅助方法」与仓库中 app/src/main-process/ipc-webcontents.ts 的定位一致该规则无独立测试文件可参照其余四个规则的RuleTester模式补写。规则如何接入主 lint 流程自定义规则通过--rulesdir参数接入项目主 lint 命令package.json 中的定义eslint: eslint --cache --rulesdir ./eslint-rules \./eslint-rules/**/*.js\ \./script/**/*.ts{,x}\ \./app/{src,typings,test}/**/*.{j,t}s{,x}\ \./changelog.json\即eslint 以./eslint-rules为规则目录对规则自身、script/、app/源码与测试等路径执行检查。而 .eslintrc.yml 中的CUSTOM区块将这些规则统一配置为error配合root: true、typescript-eslint/parser与 prettier、github/react 等扩展构成完整约束体系。日常可通过yarn lint先跑 prettier 再跑lint:src或yarn lint:src直接触发检查。把这套实践移植到你的项目规则选择标准优先复用社区插件typescript-eslint、react、jsdoc、json、prettier、babel只有项目特有架构约定才自写规则两类规则按需选用需要类型信息如生命周期签名校验时使用typescript-eslint解析器与typescript-estree纯语法检查如 dispatcher 正则匹配用标准规则 API 即可类型检查保护规则本身给规则文件加// ts-check与 JSDoc 类型注解并配置独立的tsconfig.jsonallowJscheckJsnoEmit用tsc校验规则代码质量测试先行为每条规则配套RuleTester测试用「合法 非法」代码片段锁定行为再接入jest统一跑yarn test:eslint安全与强类型并重insecure-random与no-loosely-typed-webcontents-ipc提醒我们lint 规则不仅能管风格还能在编译期拦截安全风险和架构性误用是 Electron 这类长生命周期桌面应用值得借鉴的工程实践。赞分享开发工具桌面应用【免费下载链接】desktopFork of GitHub Desktop to support various Linux distributions项目地址https://gitcode.com/gh_mirrors/des/desktop点击查看免费下载相关推荐自定义 ESLint 规则GitHub Desktop 项目内规则开发实战指南自定义 ESLint 规则GitHub Desktop 项目内规则开发实战指南 GitHub Desktop仓库路径 desktop 是一个依赖大量插件规桌面应用版本控制开发工具CANN/ge ES接口普通输入样例使用指导样例使用指导 1、功能描述 本样例使用Relu算子普通输入进行构图旨在帮助构图开发者快速理解普通输入的定义和使用该类型算子进行构图 2、目录结构 angula人工智能深度学习模型编译模型优化编译器AscendGitHub Desktop 代码质量管控指南ESLint、Prettier 与自定义规则深度解析GitHub Desktop 代码质量管控指南ESLint、Prettier 与自定义规则深度解析 本文以 GitHub Desktopdesktop开源桌面应用版本控制开发工具上一篇推荐使用deoplete-jedi —— 快速、智能的Python代码补全神器下一篇32GB显存也能跑Qwen3-VL-32BComfyUI量化部署保姆级指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

制作php网站必看5大安全注意事项防被黑
制作php网站必看5大安全注意事项防被黑

制作php网站必看5大安全注意事项防被黑 不会写代码却想独立做网站,最怕的就是上线后半夜收到报警,发现后台被篡改、数据库被拖库。很多老板觉得PHP网站便宜、开发快,但正因为门槛低,攻击者最爱盯着这类站点下手。做PHP网站不是写完代码就完事,… · 2026/9/27 7:11:25

滨州装修开工前必做的 7 件事,少一件都容易耽误工期
滨州装修开工前必做的 7 件事,少一件都容易耽误工期

很多滨州的朋友拿到新房钥匙,急着赶紧开工装修,恨不能当天就砸墙,结果开工没两天就因为手续不全被叫停,要么就是没准备好耽误工期。其实装修开工前的准备工作特别重要,准备做足了,后面才能顺顺利利&#xf… · 2026/9/27 7:11:25

肥西上派网站开发避坑指南:代码漏了?选哪家看这5点
肥西上派网站开发避坑指南:代码漏了?选哪家看这5点

肥西上派网站开发避坑指南:代码漏了?选哪家看这5点 网站做好了没人访问?别急着换SEO,先查查是不是被黑了。很多老板在找 肥西上派网站开发 团队时,只盯着价格和设计图,问一句 哪家好… · 2026/9/27 7:11:12

解读 MacVim 仓库中的 Vim 9.2 上游指南:Vi IMproved 的能力全景、编译安装与 Vi 兼容性
解读 MacVim 仓库中的 Vim 9.2 上游指南:Vi IMproved 的能力全景、编译安装与 Vi 兼容性

开发工具桌面应用 【免费下载链接】macvim Vim - the text editor - for macOS 项目地址: https://gitcode.com/gh_mirrors/ma/macvim 点击查看 免费下载 Vim(Vi IMproved)是 UNIX 经典编辑器 Vi 的全面改进版本,本仓库根目录下的… · 2026/9/27 7:58:28

行业网站怎么建设才不踩坑?3类方案报价与真实成本拆解
行业网站怎么建设才不踩坑?3类方案报价与真实成本拆解

行业网站怎么建设才不踩坑?3类方案报价与真实成本拆解 别再问模板网站多少钱了,那些几百块的成品站,上线三天就让你想砸锅。客户看页面卡顿、手机适配错位,业务员嫌后台难用,老板看着像PPT做出来的“假官网”,心里直打鼓。… · 2026/9/27 7:58:28

NodeMCU PWM2 模块实战指南:基于 TIMER1 软中断的高频、多引脚软件 PWM
NodeMCU PWM2 模块实战指南:基于 TIMER1 软中断的高频、多引脚软件 PWM

物联网嵌入式 【免费下载链接】nodemcu-firmware Lua based interactive firmware for ESP8266, ESP8285 and ESP32 项目地址: https://gitcode.com/gh_mirrors/no/nodemcu-firmware 点击查看 免费下载 PWM2 是 NodeMCU 固件中一个独立的软件 PWM 模块(… · 2026/9/27 7:58:22

F2 环形图(Donut Chart)实战指南:极坐标、中心文本与嵌套环图实现
F2 环形图(Donut Chart)实战指南:极坐标、中心文本与嵌套环图实现

数据可视化前端 【免费下载链接】F2 📱📈An elegant, interactive and flexible charting library for mobile. 项目地址: https://gitcode.com/gh_mirrors/f2/F2 点击查看 免费下载 F2 是一个面向移动端的优雅、交互式且灵活的图表库。本篇… · 2026/9/27 7:58:22

国内本地操作型 Agent 测评对比:用 TaoToken 统一 Key 跑通 OpenClaw 配置链路
国内本地操作型 Agent 测评对比:用 TaoToken 统一 Key 跑通 OpenClaw 配置链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 7:58:16

如何在 VS Code 中配置 Claude Code 扩展并接入 TaoToken 统一 API 通道
如何在 VS Code 中配置 Claude Code 扩展并接入 TaoToken 统一 API 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 7:58:10

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码