mcpField
E
eslint-rule-development

eslint-rule-development

github.com/sap开发160271 次安装今天更新
代码仓库

关于 eslint-rule-development

面向扩展 `@sap-ux/eslint-plugin-fiori-tools` 的开发者,提供新增 ESLint 规则的流程指南。内容涵盖规则分类、实现注册、测试文档及发布检查。

主要功能

  1. 01按规则类型选择参考指南
  2. 02实现与注册检查清单
  3. 03指定新规则测试方式
  4. 04文档与 README 更新步骤
  5. 05Lint、测试和 changeset 流程

适用场景

  1. 01新增注解或 manifest 规则
  2. 02编写 JavaScript 或 TypeScript 规则
  3. 03准备规则发布

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sap/open-ux-tools --skill eslint-rule-development

安装后在 Claude Code 中输入/eslint-rule-development确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
annotation.md
flex-change.md
js-ts-rule.md
manifest-json.md

详细介绍

Fiori ESLint 规则开发者

按照单体仓库中既定的模式,向 @sap-ux/eslint-plugin-fiori-tools 添加一条新的 ESLint 规则。

⚡ 效率规则——开始前请阅读

  1. 直接使用 Read 工具——不要使用 Bash cat,也不要启动 Explore 子 Agent 来读取文件
  2. 在一个并行批次中读取所有文件——每条快速路径都会列出确切的文件;一次性在同一轮中读取这些文件
  3. 开发期间只运行新的测试文件——不要运行整个包的测试套件:
    NODE_OPTIONS="--experimental-vm-modules" npx jest --testPathPatterns="sap-[rule-name]" --no-coverage
    

步骤 1——确定规则类型,然后读取参考文件

类型适用场景参考文件
注解规则验证 .xml / .cds 文件中的 UI.* OData 注解。此外,还适用于文本(即标签、标题或描述)可以是 i18n 绑定的规则references/annotation.md
Manifest JSON 规则验证 manifest.json 属性references/manifest-json.md
Flex 更改文件规则验证 webapp/changes/*.change(仅适用于 OData V2 flex 更改属性)references/flex-change.md
JavaScript / TypeScript 规则验证 JS/TS 应用程序源代码(UI5 模式、全局变量、已弃用的 API)references/js-ts-rule.md

根据请求推断:

  • 规则名称——遵循 sap-[kebab-case-name] 模式
  • OData 版本——仅 V2、仅 V4 或两者
  • 页面范围——要检查的页面类型。默认:所有页面类型(列表报表、对象页面等),除非规范明确限制范围。不要仅根据规范中的示例将范围限制为一种页面类型。
  • 自动修复——是/否
  • 严重级别——error 或 warn。recommended-for-s4hana 中的规则必须为 warn。

OData 版本决定链接器文件——始终遵循指定的版本:

OData 版本链接器文件Manifest 根节点
仅 V2src/project-context/linker/fe-v2.tssap.ui.generic.app.pages.*
仅 V4src/project-context/linker/fe-v4.tssap.ui5.routing.targets.*
两者两个链接器文件两个根节点

立即读取匹配的参考文件,然后在一个并行批次中读取其中列出的所有文件。如果规则涉及多种类型(例如注解 + Manifest,或 Manifest + Flex 更改),请读取所有匹配的参考文件,并结合其中的模板和访问模式。


步骤 2–10:实现检查清单

步骤 2——添加诊断常量(仅适用于注解、Manifest JSON 和 Flex 更改规则;JS/TS 规则跳过)

在 packages/eslint-plugin-fiori-tools/src/language/diagnostics.ts 中:

export const MY_RULE = 'sap-my-new-rule';

export interface MyRuleDiagnostic {
    type: typeof MY_RULE;
    // ... fields from the reference file's "Required diagnostic fields" table
}

// Add MyRuleDiagnostic to the Diagnostic union at the bottom
步骤 3——实现规则

使用适用于规则类型的参考文件中的模板。

每个新增或修改函数的代码质量要求:

  • JSDoc——为每个新函数添加 JSDoc 块(@param、@returns)。修改现有函数时,更新其 JSDoc,以反映签名或行为变化。
  • 认知复杂度 ≤ 15——由 sonarjs/cognitive-complexity 强制执行。如果函数超过 15,则将分支或循环提取到命名清晰的辅助函数中,直到复杂度符合要求。不要为了避免这种做法而将复杂逻辑内联到单个函数中。
  • 消息中的反引号代码标识——在规则警告消息中,用反引号括起所有类似代码的值:属性名称、注解名称、属性值、实体名称,以及源代码中原样出现的其他标识符。普通描述性词语无需加引号。
    // ✅ Correct — code values in backticks
    message: "The `UI.LineItem` annotation is missing the required `Criticality` property."
    
步骤 4——注册规则

src/rules/index.ts——添加导入和条目(按字母顺序排列):

import sapMyNewRule from './sap-my-new-rule.js';
// ...
[MY_RULE]: sapMyNewRule,

src/index.ts——将规则添加到 fioriLanguageConfig 规则(Fiori 语言规则)或 baseFioriToolsRules(JS/TS 规则)中:

'@sap-ux/fiori-tools/sap-my-new-rule': 'warn',

如果规则也应适用于 S/4HANA 项目,请同时将其添加到 src/index.ts 中的 recommended-for-s4hana 配置。此配置中的规则必须使用 'warn' 严重级别:

// In the recommended-for-s4hana config rules object:
'@sap-ux/fiori-tools/sap-my-new-rule': 'warn',
步骤 5 — 编写测试

使用参考文件中的测试模板;仅运行新的测试文件(请参阅顶部的效率规则)。

在 errors 数组中始终检查 message,不要检查 messageId。 如果规则消息包含插值数据(例如 {{tableType}}),仅检查 messageId 会接受该占位符的任意值,无法发现回归问题。请使用完全解析后的字符串:

// ✅ Correct — verifies the interpolated value
errors: [
    {
        message:
            '"TreeTable" is not supported in the flexible column layout with a draft-enabled service.'
    }
]

// ❌ Wrong — does not verify the data interpolated into the message
errors: [{ messageId: 'sap-my-new-rule' }]

如果测试显示预期存在违规时错误数为 0,请检查参考文件底部的调试清单。

步骤 6 — 编写文档

创建 packages/eslint-plugin-fiori-tools/docs/rules/sap-[rule-name].md。 阅读 packages/eslint-plugin-fiori-tools/docs/rules/TEMPLATE.md 了解文档结构。主要部分:

  • H1 标题 — 用一句话描述规则,并在括号中注明规则 ID
  • 引言段落 — 2–3 句话:说明规则检测什么、引入原因(动机应放在这里,而非单独的 H2 中),以及应采取什么替代做法
  • ## Rule Details — 说明规则的工作方式和警告消息;包含“The following patterns are considered warnings:”以及“The following patterns are not considered warnings”代码示例
  • ### How to Fix — 提供修复步骤(如果示例已清楚说明,则省略)
  • ## False Positives — 可选;仅当规则可能产生误报时添加
  • ## Bug Report — 使用以下确切文本:
    ## Bug Report
    
    If you detect an issue with the check, open a [GitHub issue](https://github.com/SAP/open-ux-tools/issues).
    
  • ## Further Reading — 可选;仅在有真实且可验证的 URL 时添加
步骤 7 — 更新 README

在 packages/eslint-plugin-fiori-tools/README.md 中完成两项工作:

  1. 使用版本列中的 new,将新规则添加到规则表的顶部:

    |  new  | [sap-my-new-rule](docs/rules/sap-my-new-rule.md) | Short description | | ✅ |
    
  2. 补全所有待定的 new 版本:如果之前添加且已发布的规则行仍显示 new,请在 packages/eslint-plugin-fiori-tools/CHANGELOG.md 中查找每条规则的发布版本,并将 new 替换为该版本。完成清理后,只有新添加的规则应显示 new。

步骤 8 — 运行完整质量检查(一次)

运行 lint:fix,自动修复 ESLint 错误,并对所有修改过的文件应用 Prettier 格式化,然后确认没有剩余问题:

# Fix lint errors and apply Prettier formatting
pnpm --filter @sap-ux/eslint-plugin-fiori-tools lint:fix

# Verify no remaining issues
pnpm --filter @sap-ux/eslint-plugin-fiori-tools lint

如果 lint 在运行 lint:fix 后仍报告错误:

  • sonarjs/cognitive-complexity — 按照步骤 3 中关于认知复杂度的指导进行处理。
  • prettier/prettier — 格式问题无法自动修复。手动应用建议的更改(通常是行太长,或多行表达式需要重新组织)。
  • @typescript-eslint/no-unsafe-* — 将 any 类型断言或未类型化的值替换为适当的接口,或使用 unknown + 类型守卫。

在 pnpm lint 以代码 0 退出之前,不要继续步骤 9。

然后确认所有测试仍然通过:

pnpm --filter @sap-ux/eslint-plugin-fiori-tools test
步骤 9 — 创建变更集
pnpm cset

选择 @sap-ux/eslint-plugin-fiori-tools,为新规则选择 minor:

FEAT: add sap-my-new-rule rule for [short description]
步骤 10 — 汇报

总结完成的工作:

  • 规则名称和类型 — 规则 ID 及其类型(annotation / manifest JSON / flex change / JS/TS)
  • 创建的文件 — 规则实现文件、测试文件、文档文件
  • 修改的文件 — diagnostics.ts、rules/index.ts、src/index.ts、README.md
  • 测试结果 — 有效和无效用例的数量,且全部通过
  • 变更集 — 软件包、升级类型(minor)、摘要行

快速参考:关键文件

用途路径
规则实现packages/eslint-plugin-fiori-tools/src/rules/sap-[name].ts
规则注册表packages/eslint-plugin-fiori-tools/src/rules/index.ts
插件配置和导出packages/eslint-plugin-fiori-tools/src/index.ts
诊断常量packages/eslint-plugin-fiori-tools/src/language/diagnostics.ts
注解辅助工具packages/eslint-plugin-fiori-tools/src/project-context/linker/annotations.ts
i18n 辅助工具(例如 extractI18nKey、getAttrOrChildText、collectSectionLabelKeys)packages/eslint-plugin-fiori-tools/src/project-context/linker/i18n.ts
注解索引键格式packages/eslint-plugin-fiori-tools/src/project-context/parser/service.ts(第 50-57 行)
链接器类型packages/eslint-plugin-fiori-tools/src/project-context/linker/types.ts
V2 链接器packages/eslint-plugin-fiori-tools/src/project-context/linker/fe-v2.ts
V4 链接器packages/eslint-plugin-fiori-tools/src/project-context/linker/fe-v4.ts
规则工厂packages/eslint-plugin-fiori-tools/src/language/rule-factory.ts
规则修复器packages/eslint-plugin-fiori-tools/src/language/rule-fixer.ts
测试辅助工具packages/eslint-plugin-fiori-tools/test/test-helper.ts
规则文档模板packages/eslint-plugin-fiori-tools/docs/rules/TEMPLATE.md
README 规则表packages/eslint-plugin-fiori-tools/README.md

按规则类型访问 check() 上下文

规则类型在 check() 中使用原因
注解使用 linkedModel.apps 遍历页面;使用 index.apps[appKey] 调用 getIndexedServiceForMainService仅检查被页面引用的注解,切勿扫描所有实体注解。pageNames 必须只列出引用了特定注解的页面。访问模式和页面注解映射模板请参阅 annotation.md。当文本可能是 i18n 绑定时,请使用 annotation.md#when-the-text-field-can-be-an-i18n-binding 中的两遍设计。
Manifest JSON使用 linkedModel.apps 遍历页面;使用 index.apps[appKey] 获取 parsedApp(manifest URI、manifestObject)需要已链接的页面来查找 manifest 配置路径
Flex 更改context.sourceCode.projectContext.linkedModel.apps先对 FioriChangeSourceCode 进行守卫检查;链接模型通过 page.lookup['table'] 提供更改文件配置
JavaScript / TypeScript标准 ESLint context,不使用 projectContextJS/TS 规则不使用 Fiori 项目模型;使用 Rule.RuleModule,而非 createFioriRule

评论

支持 Markdown