关于 n8n:create-community-node-lint-rule
此技能指导贡献者为 n8n 的 community-nodes ESLint 插件添加规则,涵盖规则设计、实现、测试、注册、文档和验证。
主要功能
- 01明确规则行为与适用范围
- 02使用 AST 辅助函数实现规则
- 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 字段使用 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