n8n:create-community-node-lint-rule について
n8n の community-nodes ESLint プラグインにルールを追加するためのスキルです。設計、実装、テスト、登録、ドキュメント作成、検証を案内します。
主な機能
- 01ルールの動作と適用範囲を明確化
- 02AST ヘルパーを使ってルールを実装
- 03診断内容と自動修正をテスト
- 04ルールと推奨設定に登録
- 05ルールのドキュメントを作成
- 06テスト、ビルド、Lint を実行
活用シーン
- 01ノードファイル向けの Lint ルールを追加
- 02認証情報クラスのパターンを適用
- 03テスト付きの自動修正可能なルールを作成
- 04プラグインルールの文書化と登録
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ n8n-io/ n8n --skill n8n:create-community-node-lint-ruleインストール後、Claude Code で/n8n:create-community-node-lint-ruleを入力して読み込まれたか確認します。
同梱ファイルreference.md
詳細
コミュニティノードの Lint ルールを作成する
packages/@n8n/eslint-plugin-community-nodes/ に新しい ESLint ルールを追加するためのガイドです。
以下のパスはすべて packages/@n8n/eslint-plugin-community-nodes/ を基準とします。
ステップ 1:ルールを理解する
コードを書く前に、以下を明確にします。
- 何を検出するルールですか?(プロパティの欠落、誤ったパターン、不正な値)
- どこに適用されますか?(
.node.tsファイル、認証情報クラス、またはその両方) - 重要度:
error(修正必須)ですか、それともwarn(修正推奨)ですか? - 自動修正可能ですか? 安全に自動修正できますか、それとも提案のみですか?
- 適用範囲:両方の
recommended設定ですか、それともrecommendedWithoutN8nCloudSupportから除外しますか?
ステップ 2:ルールを実装する
src/rules/<rule-name>.ts を作成します。
import { AST_NODE_TYPES } from '@typescript-eslint/utils';
import {
isNodeTypeClass, // or isCredentialTypeClass
findClassProperty,
findObjectProperty,
createRule,
} from '../utils/index.js';
export const YourRuleNameRule = createRule({
name: 'rule-name',
meta: {
type: 'problem', // or 'suggestion'
docs: {
description: 'One-line description of what the rule enforces',
},
messages: {
messageId: 'Human-readable message. Use {{placeholder}} for dynamic data.',
},
fixable: 'code', // omit if not auto-fixable
hasSuggestions: true, // omit if no suggestions
schema: [], // add options schema if configurable
},
defaultOptions: [],
create(context) {
return {
ClassDeclaration(node) {
if (!isNodeTypeClass(node)) return;
const descriptionProperty = findClassProperty(node, 'description');
if (!descriptionProperty) return;
const descriptionValue = descriptionProperty.value;
if (descriptionValue?.type !== AST_NODE_TYPES.ObjectExpression) return;
// Rule logic here — use findObjectProperty(), getLiteralValue(), etc.
context.report({
node: targetNode,
messageId: 'messageId',
data: { /* template vars */ },
fix(fixer) {
return fixer.replaceText(targetNode, 'replacement');
},
});
},
};
},
});
命名規則:PascalCaseRule としてエクスポートします(例:MissingPairedItemRule)。name フィールドはケバブケースにします。
利用可能な AST ヘルパー — ast-utils と file-utils のエクスポート一覧については、reference.md を参照してください。
ステップ 3:テストを書く
src/rules/<rule-name>.test.ts を作成します。
import { RuleTester } from '@typescript-eslint/rule-tester';
import { YourRuleNameRule } from './rule-name.js';
const ruleTester = new RuleTester();
// Helper to generate test code — keeps test cases readable
function createNodeCode(/* parameterize the varying parts */): string {
return `
import type { INodeType, INodeTypeDescription } from 'n8n-workflow';
export class TestNode implements INodeType {
description: INodeTypeDescription = {
displayName: 'Test Node',
name: 'testNode',
group: ['input'],
version: 1,
description: 'A test node',
defaults: { name: 'Test Node' },
inputs: [],
outputs: [],
properties: [],
};
}`;
}
ruleTester.run('rule-name', YourRuleNameRule, {
valid: [
{ name: 'class that does not implement INodeType', code: '...' },
{ name: 'node with correct pattern', code: createNodeCode(/* correct */) },
],
invalid: [
{
name: 'descriptive case name',
code: createNodeCode(/* incorrect */),
errors: [{ messageId: 'messageId', data: { /* expected template vars */ } }],
output: createNodeCode(/* expected after fix */), // or `output: null` if no fix
},
],
});
テストのガイドライン:
- 有効なケースとして、INodeType 以外のクラスがスキップされることを必ずテストします
- 自動修正可能なルールでは、エラーメッセージと修正後の出力の両方をテストします
- オプションがあるルールでは、各オプションの組み合わせをテストします
- ファイルシステムを使うルールでは、
vi.mock('../utils/file-utils.js')でモックします - 提案のみのルールでは、
errors: [{ messageId, suggestions: [...] }]を使用します
ステップ 4:ルールを登録する
4a. src/rules/index.ts に追加する
import { YourRuleNameRule } from './rule-name.js';
// Add to the rules object:
export const rules = {
// ... existing rules
'rule-name': YourRuleNameRule,
} satisfies Record<string, AnyRuleModule>;
4b. src/plugin.ts の設定に追加する
ルールが n8n クラウドの機能に依存していない限り、両方の設定オブジェクトに追加します。
'@n8n/community-nodes/rule-name': 'error', // or 'warn'
- バグや必須パターンを検出するルールには
errorを使用します - スタイルや規約に関するルール(
options-sorted-alphabeticallyなど)にはwarnを使用します - ルールが
no-restricted-globalsまたはno-restricted-importsのパターンを使う場合は、recommendedにのみ追加します(recommendedWithoutN8nCloudSupportには追加しません)
ステップ 5:ドキュメントを書く
docs/rules/<rule-name>.md を作成します。
# Description of what the rule does (`@n8n/community-nodes/rule-name`)
## Rule Details
Explain why this rule exists and what problem it prevents.
## Examples
### Incorrect
\`\`\`typescript
// code that triggers the rule
\`\`\`
### Correct
\`\`\`typescript
// code that passes the rule
\`\`\`
上記の `` 内のヘッダーは、pnpm build:docs によって再生成されます。まずは妥当な内容を書いてください。後で上書きされます。
ステップ 6:確認する
packages/@n8n/eslint-plugin-community-nodes/ から実行します。
pushd packages/@n8n/eslint-plugin-community-nodes
pnpm test <rule-name>.test.ts # tests pass
pnpm typecheck # types are clean
pnpm build # compiles
pnpm build:docs # regenerates doc headers and README table
pnpm lint:docs # docs match schema
popd
チェックリスト
- ルールファイル:
src/rules/<rule-name>.ts - テストファイル:
src/rules/<rule-name>.test.ts -
src/rules/index.tsに登録済み -
src/plugin.tsの設定に追加済み - ドキュメントファイル:
docs/rules/<rule-name>.md -
pnpm build:docsで README の表を更新済み - すべての確認コマンドが成功