Cypress 内部共享 ESLint 规范:@cypress/eslint-plugin-dev 的预设体系、自定义规则与 Git 钩子实战

发布时间:2026/9/8 16:04:43
Cypress 内部共享 ESLint 规范:@cypress/eslint-plugin-dev 的预设体系、自定义规则与 Git 钩子实战 Cypress 内部共享 ESLint 规范cypress/eslint-plugin-dev 的预设体系、自定义规则与 Git 钩子实战【免费下载链接】cypressFast, easy and reliable testing for anything that runs in a browser.项目地址: https://gitcode.com/GitHub_Trending/cy/cypresscypress/eslint-plugin-dev 是 Cypress 仓库内部开发专用的 ESLint 插件它为 monorepo 中数十个包提供统一、可自动修复的代码风格与质量规则。本文以该插件的官方 README位于 npm/eslint-plugin-dev/README.md为核心骨架完整讲解安装、预设general / tests / react、自定义规则与 Git 钩子集成并结合仓库源码剖析每个预设与规则的底层实现帮助你在一套规则之上获得可复制的工程实践方案。插件定位专为 Cypress 内部开发而生该插件在 README 中明确标注为[Internal] Cypress Developer ESLint Plugin其定位描述为 Common ESLint rules shared by Cypress packages——即供 Cypress 各 npm 包共享的通用 ESLint 规则集合而非给使用 Cypress 做测试的用户使用。仓库 npm/eslint-plugin-dev/package.json 中的描述 Common ESLint rules shared by Cypress development-only packages 也印证了这一点。需要注意区分面向 Cypress 使用者的官方插件是独立的eslint-plugin-cypress两者命名相似但用途完全不同阅读本文时不要混淆。Cypress 自己的实际用户插件并不在这个包内。在 Cypress 仓库中该包位于 npm/eslint-plugin-dev 目录入口main指向./lib即 lib/index.js并对外提供两个命令行 binlint-changed与lint-pre-commit见 package.json 的bin字段。版本兼容性与安装前置条件ESLint 版本对应关系README 明确指出当前不支持 ESLint 9版本对应规则如下使用的 ESLint 版本应安装的 cypress/eslint-plugin-dev 版本ESLint 86.x.xESLint 7 及以下5.x.x该声明与 package.json 中的peerDependencies一致插件声明eslint: ^ 8.0.0且 devDependencies 使用eslint: ^8.56.0说明插件按经典.eslintrc配置格式设计与验证尚未适配 ESLint 9 的 flat config 体系。安装插件npm install --save-dev cypress/eslint-plugin-dev必须配套安装的 devDependencies该插件是组合式规则集依赖多个 ESLint 生态包提供 parser 与规则请一次性安装cypress/eslint-plugin-dev eslint-plugin-json-format typescript-eslint/parser typescript-eslint/eslint-plugin eslint-plugin-mocha eslint-plugin-import # 如果工程中有 react/jsx 文件还需要 eslint-plugin-react babel/eslint-parser这些依赖与 package.json 的peerDependencies列表对应typescript-eslint/* 7.0.0、eslint-plugin-react 7.22.0、eslint-plugin-mocha 8.0.0等安装时建议使用满足上述最低版本的包。最小可用配置4 步接入一个包1) 在包根目录创建.eslintrc.json{ plugins: [ cypress/dev ], extends: [ plugin:cypress/dev/general ] }如果使用 React再追加plugin:cypress/dev/react。2) 在test/目录内单独配置如果包内有test/目录应在其中再放一个.eslintrc.json让测试代码套用测试专用规则例如禁止.only、强制为.skip写解释注释等{ extends: [ plugin:cypress/dev/tests ] }3) 在.eslintignore中放行隐藏文件# dont ignore hidden files, useful for formatting json config files !.*这样可以让 ESLint 处理.eslintrc等点开头文件便于对 JSON 配置文件做格式化与校验。4)可选配置编辑器插件与 pre-commit 钩子详见下文Git 钩子与编辑器集成两节。三大预设Presets源码级剖析插件在 lib/index.js 中导出了三个预设分别用于不同场景。每个预设的extends名称对应源码中的configs.general、configs.tests、configs.react。general包根目录的标准规则集README 建议通常用于包根目录其包含绝大多数规则并通过eslint-plugin-json-format对 JSON 文件自动修复并排序 package.json。从 lib/index.js 源码看general预设由三部分组成基础解析环境与插件ecmaVersion: 2018、sourceType: module启用env.node与env.es6注册json-format插件并在 settings 中默认开启json[sort-package-json]: pro这正是 README 中自动排序 package.json的底层开关若想关闭见下文配置示例。baseRules 基础规则表约百条 ESLint 内置核心规则全部置为error可视为 Cypress 的编码风格规范。几条值得注意的默认值均为源码直接给出semi: [error, never]、quotes: [error, single, { allowTemplateLiterals: true }]——不加分号、强制单引号indent: [error, 2, {...}]——2 空格缩进TS 文件改用typescript-eslint/indentcomma-dangle: [error, always-multiline]、object-curly-spacing: [error, always]arrow-parens: [error, always]、brace-style: 1tbsno-console: error、no-debugger: error——生产源码禁止console与debugger源码中多处刻意写了// eslint-disable-next-line no-console来放行 CLI 日志no-var: error、eqeqeq: [error, allow-null]、prefer-template: error自带规则cypress/dev/arrow-body-multiline-braces: [error, always]默认开启。overrides 覆盖规则针对不同文件类型*.jsx/*.tsx关闭arrow-body-multiline-bracesJSX 多行箭头函数允许省略花括号*.ts/*.tsx/*.vue换用typescript-eslint/parser注册typescript-eslint与import插件关闭与 TS 冲突的内置规则no-undef、no-unused-vars、indent等改启用typescript-eslint/no-unused-vars支持argsIgnorePattern: ^_下划线参数豁免、typescript-eslint/type-annotation-spacing、typescript-eslint/member-delimiter-style多行接口成员不写分号等并用import/no-duplicates替代关闭掉的no-duplicate-imports。general预设要求安装eslint-plugin-import、eslint-plugin-json-format、typescript-eslint/parser、typescript-eslint/eslint-plugin。tests测试目录专用配置tests预设用于test/目录针对 Mocha 风格的测试代码{ extends: [ plugin:cypress/dev/tests ] }其源码配置lib/index.js核心内容env.mocha: true并声明全局expect: true注册mocha插件启用mocha/handle-done-callback、mocha/no-exclusive-tests禁止.only、mocha/no-global-tests启用自定义规则cypress/dev/skip-comment: error详见下文自定义规则对*.spec.tsx额外使用typescript-eslint/parser并关闭no-unused-vars源码注释避免对仅用于类型导入的接口报未使用警告。注意tests预设不会把general的规则带进来两者是并列的 configREADME 建议的做法是在包根用general、在test/下用tests。tests预设要求安装eslint-plugin-mocha。reactReact/JSX 文件专用配置{ extends: [ plugin:cypress/dev/general, plugin:cypress/dev/react ] }源码中configs.react使用babel/eslint-parserrequireConfigFile: false无需 babel 配置文件即可解析 JSXecmaFeatures.jsx: true并开启legacyDecoratorsenv.browser: true注册react插件后启用一组 JSX 规则react/jsx-curly-spacing、react/jsx-pascal-case、react/jsx-wrap-multilines、react/no-unknown-property、react/react-in-jsx-scope、react/jsx-filename-extension等全部为error。react预设要求安装babel/eslint-parser、eslint-plugin-react。常见配置改写示例调整某条规则继承预设后可在.eslintrc.json中按常规方式覆盖规则// .eslintrc.json { extends: [ plugin:cypress/dev/general ], rules: { comma-dangle: off, no-debugger: warn } }关闭 package.json 自动排序general预设默认会通过eslint-plugin-json-format在 autofix 时排序 package.json源码对应 lib/index.js 中settings.json[sort-package-json]: pro。若不希望 package.json 被格式化在配置中加入{ settings: { json/sort-package-json: false } }Cypress 特有自定义规则详解README 用一张表列出了三条随插件分发的自定义规则注册于 lib/custom-rules/index.js自动加载custom-rules/下除index.js外的所有规则文件。下表完整保留 README 的说明并补充配置要点| name | description | options | example | |-|-|-|-| |cypress/dev/arrow-body-multiline-braces| 仅要求多行箭头函数必须写花括号 |[always\|never]应设为always |cypress/dev/arrow-body-multiline-braces: [error, always]| |cypress/dev/skip-comment| 强制it/describe/context上的.skip前必须有解释注释如// NOTE: |{ commentTokens: [array] }标识.skip原因的注释令牌默认[NOTE:, TODO:, FIXME:]|cypress/dev/skip-comment: [error, { commentTokens: [TODO:] }]| |cypress/dev/no-return-before| 禁止在某些可配置 token 前写return|{ tokens: [array] }不能被return前置的 token默认[it, describe, context, expect]|cypress/dev/no-return-before: [error, { tokens: [myfn] }]|arrow-body-multiline-braces基于官方规则作曲该规则源码见 lib/custom-rules/arrow-body-multiline-braces.js。它并非从零实现而是使用eslint-rule-composer的filterReports对 ESLint 内置规则arrow-body-style做过滤报告取出内置arrow-body-style规则实例对每个 report 判断若问题所在的箭头函数是单行node.loc.start.line node.loc.end.line则直接放行再通过 token 分析跳过块注释边界场景。因此最终效果是 README 所述——仅在多行函数定义中强制箭头函数使用花括号单行箭头如const f () 1不受影响。对应测试见 test/arrow-body-multiline-braces.spec.tsfixtures 位于 test/fixtures/multiline.js 与 test/fixtures/oneline.js。skip-comment杜绝无解释的跳过用例测试代码里残留.skip是最常见的悄悄溜走的用例。该规则源码 lib/custom-rules/skip-comment.js在CallExpression:exit时检查 callee当命中it.skip、describe.skip、context.skip即 MemberExpression 的property.name skip且对象名属于这三个测试作用域之一时检查该节点前面的注释是否以默认令牌NOTE:/TODO:/FIXME:或自定义令牌开头若没有则报错错误消息会提示补上形如// NOTE: reason test was skipped的注释。自定义令牌通过 option 传入cypress/dev/skip-comment: [error, { commentTokens: [FOOBAR:] }]。测试用例 test/skip-comment.spec.ts 验证带注释的 fixture 报 0 个错误不带注释的 fixturetest/fixtures/skip-comment-fail.js对it/describe/context三个场景各报 1 个错误共 3且错误消息必须包含NOTE:、TODO:当自定义commentTokens: [FOOBAR:]时则要求注释以FOOBAR:开头。no-return-before禁止在测试块前 return源码 lib/custom-rules/no-return-before.js 会在CallExpression:exit时取出 callee 前一个 token若它是return关键字且 callee 命中默认令牌[it, describe, context, expect]或自定义 tokens则报告错误并附带autofix删除多余的return关键字对应fix中replaceTextRange的实现。之所以要防return it(...)是因为测试代码中return是多余且易误导的写法如return it(..., () {...})。附带规则no-only默认关闭保留实现除 README 表格外源码中还包含第四条约束质量的自定义规则 lib/custom-rules/no-only.js用于阻止 spec 文件中出现it.only/describe.only/context.only消息为Found only: \{{callee}}。在 [lib/index.js](https://link.gitcode.com/i/ade61863bec9a972dd71cf3293fb8599) 中该规则以注释形式存在// cypress/dev/no-only: error即**当前未在预设中默认开启**——其职责主要由 tests 预设里的mocha/no-exclusive-tests承担规则本体保留可在需要的包内显式启用cypress/dev/no-only: error。对应测试见 test/no-only.spec.tsfixture test/fixtures/with-only.js。一键修复Git 钩子与 lint-changed为让团队成员在 commit 前自动获得 lint 与格式修复README 推荐配合husky使用插件自带的 pre-commit 脚本。启用 pre-commit 钩子在package.json中husky: { hooks: { pre-commit: lint-pre-commit } }其中lint-pre-commit由 package.json 的bin字段注册./lib/scripts/lint-pre-commit.js安装后即生成可直接调用的命令。钩子的安全行为与手动全量修复lint-pre-commit钩子只对已暂存staged文件执行 lint 与--fix并自动git add回暂存区它特意保护部分暂存的文件对既有暂存又有未暂存改动的文件partially staged改为用git show :file取出暂存区版本内容进行 lint只检查不写回从而避免钩子误把开发者未暂存的改动一并 add 进暂存区——这正是 README 强调的保护被部分暂存的文件如需对所有暂存与未暂存文件做一次全量自动修复手动执行./node_modules/.bin/lint-changed --fixlint-changed源码 lib/scripts/lint-changed.js会取git diff --name-only --diff-filterM已修改与git diff --name-only --diff-filterMA --staged新增/修改且已暂存的并集进行 lint带--fix时自动修复失败时以非零码退出。底层实现见 lib/scripts/utils.jslintFilesByName用npx eslint --colortrue [--fix] files处理工作区文件lintFilesByText则用eslint --stdin --stdin-filename file处理文本用于部分暂存文件两者都只筛选.js|.jsx|.ts|.tsx|.json|.eslintrc后缀文件且统一在 monorepo 根目录cwd指向../../../../执行命令以保证解析到正确的.eslintrc与依赖。scripts目录下还有配套的 lint-staged.js、lint-pre-push.js 可参考。编辑器集成保存即修复VSCode安装 ESLint 扩展Dirk Baeumer 的 vscode-eslint后在 User 或 Workspace 的.vscode/settings.json中声明校验语言并开启保存时自动修复{ eslint.validate: [ { language: javascript, autoFix: true }, { language: javascriptreact, autoFix: true }, { language: typescript, autoFix: true }, { language: typescriptreact, autoFix: true }, { language: json, autoFix: true } ], }Atom安装linter-eslint包及其依赖后在其设置中开启 Fix on save即可在保存时自动修复空格等格式问题。Sublime Text安装ESLint-Formatter后配置{ format_on_save: true, debug: true }在 Cypress 仓库中的应用位置与拓展阅读作为 Cypress 仓库内部约定的一部分该插件的实际使用效果可参考仓库内大量包的规则与源码组织方式Cypress 根目录的 ESLint 配置见 eslint.config.ts其为 monorepo 自身的 lint 入口。对于希望独立接入本文所述规则的第三方包接入流程即安装上文依赖 → 根目录extends plugin:cypress/dev/general→test/目录内extends plugin:cypress/dev/tests→ 配.eslintignore的!.*→ 接 Git 钩子整个链路可在不写一行规则的前提下获得与 Cypress 各包一致的代码风格与测试卫生约束。该包遵循 MIT 协议见 npm/eslint-plugin-dev/LICENSE.md版本变更记录可查阅 npm/eslint-plugin-dev/CHANGELOG.md插件测试基于 vitest 运行vitest.config.ts执行npm test即可跑通 test 下的全部规则用例。【免费下载链接】cypressFast, easy and reliable testing for anything that runs in a browser.项目地址: https://gitcode.com/GitHub_Trending/cy/cypress创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询