mcpField
N
n8n:create-community-node-lint-rule

n8n:create-community-node-lint-rule

github.com/n8n-io开发209.1k238 次安装今天更新
代码仓库

关于 n8n:create-community-node-lint-rule

此技能指导贡献者为 n8n 的 community-nodes ESLint 插件添加规则,涵盖规则设计、实现、测试、注册、文档和验证。

主要功能

  1. 01明确规则行为与适用范围
  2. 02使用 AST 辅助函数实现规则
  3. 03测试诊断信息与自动修复
  4. 04注册规则及推荐配置
  5. 05编写规则文档
  6. 06运行测试、构建和 Lint 检查

适用场景

  1. 01为节点文件添加 Lint 规则
  2. 02约束凭据类中的代码模式
  3. 03创建带测试的可修复规则
  4. 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 字段使用 kebab-case。

可用的 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
    },
  ],
});

测试指南:

  • 始终测试跳过非 INNodeType 类的情况(有效情况)
  • 对于可修复的规则,测试错误消息和修复后的输出
  • 对于带选项的规则,测试每种选项组合
  • 对于使用文件系统的规则,使用 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 Cloud 功能):

'@n8n/community-nodes/rule-name': 'error',  // or 'warn'
  • 对于会捕获 Bug 或强制模式的规则,使用 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 表格
  • 所有验证命令均已通过

评论

支持 Markdown