eslint-rule-development について
`@sap-ux/eslint-plugin-fiori-tools` を拡張する開発者向けに、ESLint ルールの追加手順をまとめたスキルです。ルール種別ごとの実装、登録、テスト、ドキュメント作成からリリース確認までを案内します。
主な機能
- 01ルール種別と参照資料の選択
- 02実装・登録チェックリスト
- 03新規ルールのテスト手順
- 04ドキュメントと README の更新
- 05Lint・テスト・changeset の手順
活用シーン
- 01アノテーションまたは manifest ルールの追加
- 02JavaScript または TypeScript ルールの作成
- 03ルールのリリース準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sap/ open-ux-tools --skill eslint-rule-developmentインストール後、Claude Code で/eslint-rule-developmentを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/annotation.mdflex-change.mdjs-ts-rule.mdmanifest-json.md詳細
Fiori ESLint ルール開発者
モノレポで確立されているパターンに従って、@sap-ux/eslint-plugin-fiori-tools に新しい ESLint ルールを追加します。
⚡ 効率化のルール — 作業を始める前にお読みください
Readツールを直接使用してください — ファイルの読み込みにBash catを使ったり、Explore サブエージェントを起動したりしないでください- すべてを1回の並列バッチで読み込んでください — 各ファストパスで指定されているファイルを、1ターンですべて一度に読み込んでください
- 開発中は新しいテストファイルのみを実行してください — パッケージ全体のテストスイートは実行しないでください:
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 のみ、または両方
- ページの対象範囲 — チェックするページの種類。デフォルト:すべてのページタイプ(リストレポート、オブジェクトページなど)。仕様で明示的に対象が制限されていない限り、すべてを対象にします。仕様の例をもとに、対象を1つのページタイプに限定しないでください。
- 自動修正 — あり/なし
- 重大度 —
errorまたはwarn。recommended-for-s4hanaに含めるルールは、必ずwarnにしてください。
OData バージョンに応じてリンカーファイルが決まります — 必ず指定されたバージョンに従ってください。
| OData バージョン | リンカーファイル | Manifest のルート |
|---|---|---|
| V2 のみ | src/project-context/linker/fe-v2.ts | sap.ui.generic.app.pages.* |
| V4 のみ | src/project-context/linker/fe-v4.ts | sap.ui5.routing.targets.* |
| 両方 | 両方のリンカーファイル | 両方のルート |
該当する参照ファイルをすぐに読み、そのファイルに記載されているすべてのファイルを、1回の並列バッチで読み込んでください。ルールが複数の種類にまたがる場合(例:アノテーションと 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を超える場合は、分岐やループを適切な名前を付けたヘルパー関数に切り出し、制限内に収まるようにしてください。これを避けるために、複雑なロジックを1つの関数に詰め込まないでください。 - メッセージ内のバッククォートによるコード表記 — ルールの警告メッセージでは、コードのような値をすべてバッククォートで囲んでください。これには、プロパティ名、アノテーション名、プロパティ値、エンティティ名、およびソースにそのまま記載されるその他の識別子が含まれます。通常の説明文は引用符で囲まないでください。
// ✅ 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',
Step 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 errors の場合は、リファレンスファイルの末尾にあるデバッグチェックリストを確認してください。
Step 6 — ドキュメントを作成する
packages/eslint-plugin-fiori-tools/docs/rules/sap-[rule-name].md を作成します。
構成については packages/eslint-plugin-fiori-tools/docs/rules/TEMPLATE.md を参照してください。主なセクションは次のとおりです。
- H1 タイトル — ルールの説明を1文で記述し、括弧内にルール ID を含めます
- 導入段落 — 2〜3文で、検出対象、ルールが導入された理由(動機は独立した H2 ではなく、ここに記載)、代わりに行うべきことを説明します
- ## Rule Details — ルールの動作と警告メッセージを説明し、「次のパターンは警告と見なされます:」および「次のパターンは警告と見なされません」のコード例を含めます
- ### 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 がある場合にのみ記載します
Step 7 — README を更新する
packages/eslint-plugin-fiori-tools/README.md で、次の2つを行います。
-
ルール一覧表の先頭に、新しいルールをバージョン列に
newを付けて追加します。| new | [sap-my-new-rule](docs/rules/sap-my-new-rule.md) | Short description | | ✅ | -
保留中の
newバージョンを遡って更新する:以前のルール追加時からnewのままになっていて、その後リリースされた行があれば、packages/eslint-plugin-fiori-tools/CHANGELOG.mdで各ルールのリリースバージョンを確認し、newをそのバージョンに置き換えます。この整理後、newと表示される行は追加した新しいルールだけになります。
Step 8 — 品質ゲートをすべて実行する(1回)
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:fix の後に lint がエラーを報告する場合:
sonarjs/cognitive-complexity— Step 3 の認知的複雑度に関するガイダンスに従って解決します。prettier/prettier— フォーマットの問題を自動修正できませんでした。提案された変更を手動で適用します(通常、長すぎる行や、構造の変更が必要な複数行の式です)。@typescript-eslint/no-unsafe-*—anyキャストや型指定のない値を、適切なインターフェース、または型ガードと組み合わせたunknownに置き換えます。
pnpm lint が終了コード 0 で終了するまで、Step 9 に進まないでください。
続いて、すべてのテストが引き続き合格することを確認します。
pnpm --filter @sap-ux/eslint-plugin-fiori-tools test
Step 9 — 変更セットを作成する
pnpm cset
@sap-ux/eslint-plugin-fiori-tools を選択し、新しいルールには minor を選択します。
FEAT: add sap-my-new-rule rule for [short description]
Step 10 — 報告する
実施内容を要約します。
- ルール名と種類 — ルール ID と種類(アノテーション/マニフェスト JSON/フレックス変更/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、getIndexedServiceForMainService には index.apps[appKey] を使用します | ページから参照されるアノテーションのみを確認し、すべてのエンティティアノテーションをスキャンしないでください。pageNames には、特定のアノテーションを参照するページのみを列挙する必要があります。アクセスパターンとページ・アノテーションマップのテンプレートについては、annotation.md を参照してください。テキストが i18n バインディングの場合は、annotation.md#when-the-text-field-can-be-an-i18n-binding の 2 パス設計を使用してください。 |
| Manifest JSON | ページの反復処理には linkedModel.apps、parsedApp(manifest URI、manifestObject)には index.apps[appKey] を使用します | manifest の設定パスを見つけるには、リンク済みのページが必要です |
| Flex 変更 | context.sourceCode.projectContext.linkedModel.apps | 最初に FioriChangeSourceCode かどうかを確認してください。リンク済みモデルは、page.lookup['table'] を通じて変更ファイルの設定を提供します |
| JavaScript / TypeScript | 標準の ESLint context。projectContext は使用しません | JS/TS ルールは Fiori プロジェクトモデルを使用しません。createFioriRule ではなく Rule.RuleModule を使用してください |